f05aaeaf0413f0fc1180a446844b7e7947153886
[mech_eap.git] / tests / hwsim / test_ap_wps.py
1 # WPS tests
2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import base64
8 import binascii
9 from Crypto.Cipher import AES
10 import hashlib
11 import hmac
12 import os
13 import time
14 import stat
15 import subprocess
16 import logging
17 logger = logging.getLogger()
18 import re
19 import socket
20 import struct
21 import httplib
22 import urlparse
23 import urllib
24 import xml.etree.ElementTree as ET
25 import StringIO
26 import SocketServer
27
28 import hwsim_utils
29 import hostapd
30 from wpasupplicant import WpaSupplicant
31 from utils import HwsimSkip, alloc_fail, fail_test, skip_with_fips
32
33 def wps_start_ap(apdev, ssid="test-wps-conf"):
34     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
35                "wpa_passphrase": "12345678", "wpa": "2",
36                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
37     return hostapd.add_ap(apdev['ifname'], params)
38
39 def test_ap_wps_init(dev, apdev):
40     """Initial AP configuration with first WPS Enrollee"""
41     ssid = "test-wps"
42     hostapd.add_ap(apdev[0]['ifname'],
43                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
44     hapd = hostapd.Hostapd(apdev[0]['ifname'])
45     logger.info("WPS provisioning step")
46     hapd.request("WPS_PBC")
47     if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
48         raise Exception("PBC status not shown correctly")
49
50     id = dev[0].add_network()
51     dev[0].set_network_quoted(id, "ssid", "home")
52     dev[0].set_network_quoted(id, "psk", "12345678")
53     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
54
55     id = dev[0].add_network()
56     dev[0].set_network_quoted(id, "ssid", "home2")
57     dev[0].set_network(id, "bssid", "00:11:22:33:44:55")
58     dev[0].set_network(id, "key_mgmt", "NONE")
59     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
60
61     dev[0].request("WPS_PBC")
62     dev[0].wait_connected(timeout=30)
63     status = dev[0].get_status()
64     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
65         raise Exception("Not fully connected")
66     if status['ssid'] != ssid:
67         raise Exception("Unexpected SSID")
68     if status['pairwise_cipher'] != 'CCMP':
69         raise Exception("Unexpected encryption configuration")
70     if status['key_mgmt'] != 'WPA2-PSK':
71         raise Exception("Unexpected key_mgmt")
72
73     status = hapd.request("WPS_GET_STATUS")
74     if "PBC Status: Disabled" not in status:
75         raise Exception("PBC status not shown correctly")
76     if "Last WPS result: Success" not in status:
77         raise Exception("Last WPS result not shown correctly")
78     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
79         raise Exception("Peer address not shown correctly")
80     conf = hapd.request("GET_CONFIG")
81     if "wps_state=configured" not in conf:
82         raise Exception("AP not in WPS configured state")
83     if "wpa=3" not in conf:
84         raise Exception("AP not in WPA+WPA2 configuration")
85     if "rsn_pairwise_cipher=CCMP TKIP" not in conf:
86         raise Exception("Unexpected rsn_pairwise_cipher")
87     if "wpa_pairwise_cipher=CCMP TKIP" not in conf:
88         raise Exception("Unexpected wpa_pairwise_cipher")
89     if "group_cipher=TKIP" not in conf:
90         raise Exception("Unexpected group_cipher")
91
92     if len(dev[0].list_networks()) != 3:
93         raise Exception("Unexpected number of network blocks")
94
95 def test_ap_wps_init_2ap_pbc(dev, apdev):
96     """Initial two-radio AP configuration with first WPS PBC Enrollee"""
97     ssid = "test-wps"
98     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
99     hostapd.add_ap(apdev[0]['ifname'], params)
100     hostapd.add_ap(apdev[1]['ifname'], params)
101     hapd = hostapd.Hostapd(apdev[0]['ifname'])
102     logger.info("WPS provisioning step")
103     hapd.request("WPS_PBC")
104     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
105     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
106     bss = dev[0].get_bss(apdev[0]['bssid'])
107     if "[WPS-PBC]" not in bss['flags']:
108         raise Exception("WPS-PBC flag missing from AP1")
109     bss = dev[0].get_bss(apdev[1]['bssid'])
110     if "[WPS-PBC]" not in bss['flags']:
111         raise Exception("WPS-PBC flag missing from AP2")
112     dev[0].dump_monitor()
113     dev[0].request("SET wps_cred_processing 2")
114     dev[0].request("WPS_PBC")
115     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=30)
116     dev[0].request("SET wps_cred_processing 0")
117     if ev is None:
118         raise Exception("WPS cred event not seen")
119     if "100e" not in ev:
120         raise Exception("WPS attributes not included in the cred event")
121     dev[0].wait_connected(timeout=30)
122
123     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
124     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
125     bss = dev[1].get_bss(apdev[0]['bssid'])
126     if "[WPS-PBC]" in bss['flags']:
127         raise Exception("WPS-PBC flag not cleared from AP1")
128     bss = dev[1].get_bss(apdev[1]['bssid'])
129     if "[WPS-PBC]" in bss['flags']:
130         raise Exception("WPS-PBC flag not cleared from AP2")
131
132 def test_ap_wps_init_2ap_pin(dev, apdev):
133     """Initial two-radio AP configuration with first WPS PIN Enrollee"""
134     ssid = "test-wps"
135     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
136     hostapd.add_ap(apdev[0]['ifname'], params)
137     hostapd.add_ap(apdev[1]['ifname'], params)
138     hapd = hostapd.Hostapd(apdev[0]['ifname'])
139     logger.info("WPS provisioning step")
140     pin = dev[0].wps_read_pin()
141     hapd.request("WPS_PIN any " + pin)
142     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
143     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
144     bss = dev[0].get_bss(apdev[0]['bssid'])
145     if "[WPS-AUTH]" not in bss['flags']:
146         raise Exception("WPS-AUTH flag missing from AP1")
147     bss = dev[0].get_bss(apdev[1]['bssid'])
148     if "[WPS-AUTH]" not in bss['flags']:
149         raise Exception("WPS-AUTH flag missing from AP2")
150     dev[0].dump_monitor()
151     dev[0].request("WPS_PIN any " + pin)
152     dev[0].wait_connected(timeout=30)
153
154     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
155     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
156     bss = dev[1].get_bss(apdev[0]['bssid'])
157     if "[WPS-AUTH]" in bss['flags']:
158         raise Exception("WPS-AUTH flag not cleared from AP1")
159     bss = dev[1].get_bss(apdev[1]['bssid'])
160     if "[WPS-AUTH]" in bss['flags']:
161         raise Exception("WPS-AUTH flag not cleared from AP2")
162
163 def test_ap_wps_init_through_wps_config(dev, apdev):
164     """Initial AP configuration using wps_config command"""
165     ssid = "test-wps-init-config"
166     hostapd.add_ap(apdev[0]['ifname'],
167                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
168     hapd = hostapd.Hostapd(apdev[0]['ifname'])
169     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
170         raise Exception("WPS_CONFIG command failed")
171     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
172     if ev is None:
173         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
174     # It takes some time for the AP to update Beacon and Probe Response frames,
175     # so wait here before requesting the scan to be started to avoid adding
176     # extra five second wait to the test due to fetching obsolete scan results.
177     hapd.ping()
178     time.sleep(0.2)
179     dev[0].connect(ssid, psk="12345678", scan_freq="2412", proto="WPA2",
180                    pairwise="CCMP", group="CCMP")
181
182 def test_ap_wps_init_through_wps_config_2(dev, apdev):
183     """AP configuration using wps_config and wps_cred_processing=2"""
184     ssid = "test-wps-init-config"
185     hostapd.add_ap(apdev[0]['ifname'],
186                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
187                      "wps_cred_processing": "2" })
188     hapd = hostapd.Hostapd(apdev[0]['ifname'])
189     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
190         raise Exception("WPS_CONFIG command failed")
191     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
192     if ev is None:
193         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
194     if "100e" not in ev:
195         raise Exception("WPS-NEW-AP-SETTINGS did not include Credential")
196
197 def test_ap_wps_invalid_wps_config_passphrase(dev, apdev):
198     """AP configuration using wps_config command with invalid passphrase"""
199     ssid = "test-wps-init-config"
200     hostapd.add_ap(apdev[0]['ifname'],
201                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
202     hapd = hostapd.Hostapd(apdev[0]['ifname'])
203     if "FAIL" not in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "1234567".encode("hex")):
204         raise Exception("Invalid WPS_CONFIG command accepted")
205
206 def test_ap_wps_conf(dev, apdev):
207     """WPS PBC provisioning with configured AP"""
208     ssid = "test-wps-conf"
209     hostapd.add_ap(apdev[0]['ifname'],
210                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
211                      "wpa_passphrase": "12345678", "wpa": "2",
212                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
213     hapd = hostapd.Hostapd(apdev[0]['ifname'])
214     logger.info("WPS provisioning step")
215     hapd.request("WPS_PBC")
216     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
217     dev[0].dump_monitor()
218     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
219     dev[0].wait_connected(timeout=30)
220     status = dev[0].get_status()
221     if status['wpa_state'] != 'COMPLETED':
222         raise Exception("Not fully connected")
223     if status['bssid'] != apdev[0]['bssid']:
224         raise Exception("Unexpected BSSID")
225     if status['ssid'] != ssid:
226         raise Exception("Unexpected SSID")
227     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
228         raise Exception("Unexpected encryption configuration")
229     if status['key_mgmt'] != 'WPA2-PSK':
230         raise Exception("Unexpected key_mgmt")
231
232     sta = hapd.get_sta(dev[0].p2p_interface_addr())
233     if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
234         raise Exception("Device name not available in STA command")
235
236 def test_ap_wps_conf_5ghz(dev, apdev):
237     """WPS PBC provisioning with configured AP on 5 GHz band"""
238     try:
239         hapd = None
240         ssid = "test-wps-conf"
241         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
242                    "wpa_passphrase": "12345678", "wpa": "2",
243                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
244                    "country_code": "FI", "hw_mode": "a", "channel": "36" }
245         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
246         logger.info("WPS provisioning step")
247         hapd.request("WPS_PBC")
248         dev[0].scan_for_bss(apdev[0]['bssid'], freq="5180")
249         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
250         dev[0].wait_connected(timeout=30)
251
252         sta = hapd.get_sta(dev[0].p2p_interface_addr())
253         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
254             raise Exception("Device name not available in STA command")
255     finally:
256         dev[0].request("DISCONNECT")
257         if hapd:
258             hapd.request("DISABLE")
259         subprocess.call(['iw', 'reg', 'set', '00'])
260         dev[0].flush_scan_cache()
261
262 def test_ap_wps_conf_chan14(dev, apdev):
263     """WPS PBC provisioning with configured AP on channel 14"""
264     try:
265         hapd = None
266         ssid = "test-wps-conf"
267         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
268                    "wpa_passphrase": "12345678", "wpa": "2",
269                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
270                    "country_code": "JP", "hw_mode": "b", "channel": "14" }
271         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
272         logger.info("WPS provisioning step")
273         hapd.request("WPS_PBC")
274         dev[0].request("WPS_PBC")
275         dev[0].wait_connected(timeout=30)
276
277         sta = hapd.get_sta(dev[0].p2p_interface_addr())
278         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
279             raise Exception("Device name not available in STA command")
280     finally:
281         dev[0].request("DISCONNECT")
282         if hapd:
283             hapd.request("DISABLE")
284         subprocess.call(['iw', 'reg', 'set', '00'])
285         dev[0].flush_scan_cache()
286
287 def test_ap_wps_twice(dev, apdev):
288     """WPS provisioning with twice to change passphrase"""
289     ssid = "test-wps-twice"
290     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
291                "wpa_passphrase": "12345678", "wpa": "2",
292                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
293     hostapd.add_ap(apdev[0]['ifname'], params)
294     hapd = hostapd.Hostapd(apdev[0]['ifname'])
295     logger.info("WPS provisioning step")
296     hapd.request("WPS_PBC")
297     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
298     dev[0].dump_monitor()
299     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
300     dev[0].wait_connected(timeout=30)
301     dev[0].request("DISCONNECT")
302
303     logger.info("Restart AP with different passphrase and re-run WPS")
304     hapd_global = hostapd.HostapdGlobal()
305     hapd_global.remove(apdev[0]['ifname'])
306     params['wpa_passphrase'] = 'another passphrase'
307     hostapd.add_ap(apdev[0]['ifname'], params)
308     hapd = hostapd.Hostapd(apdev[0]['ifname'])
309     logger.info("WPS provisioning step")
310     hapd.request("WPS_PBC")
311     dev[0].dump_monitor()
312     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
313     dev[0].wait_connected(timeout=30)
314     networks = dev[0].list_networks()
315     if len(networks) > 1:
316         raise Exception("Unexpected duplicated network block present")
317
318 def test_ap_wps_incorrect_pin(dev, apdev):
319     """WPS PIN provisioning with incorrect PIN"""
320     ssid = "test-wps-incorrect-pin"
321     hostapd.add_ap(apdev[0]['ifname'],
322                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
323                      "wpa_passphrase": "12345678", "wpa": "2",
324                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
325     hapd = hostapd.Hostapd(apdev[0]['ifname'])
326
327     logger.info("WPS provisioning attempt 1")
328     hapd.request("WPS_PIN any 12345670")
329     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
330     dev[0].dump_monitor()
331     dev[0].request("WPS_PIN %s 55554444" % apdev[0]['bssid'])
332     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
333     if ev is None:
334         raise Exception("WPS operation timed out")
335     if "config_error=18" not in ev:
336         raise Exception("Incorrect config_error reported")
337     if "msg=8" not in ev:
338         raise Exception("PIN error detected on incorrect message")
339     dev[0].wait_disconnected(timeout=10)
340     dev[0].request("WPS_CANCEL")
341     # if a scan was in progress, wait for it to complete before trying WPS again
342     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
343
344     status = hapd.request("WPS_GET_STATUS")
345     if "Last WPS result: Failed" not in status:
346         raise Exception("WPS failure result not shown correctly")
347
348     logger.info("WPS provisioning attempt 2")
349     hapd.request("WPS_PIN any 12345670")
350     dev[0].dump_monitor()
351     dev[0].request("WPS_PIN %s 12344444" % apdev[0]['bssid'])
352     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
353     if ev is None:
354         raise Exception("WPS operation timed out")
355     if "config_error=18" not in ev:
356         raise Exception("Incorrect config_error reported")
357     if "msg=10" not in ev:
358         raise Exception("PIN error detected on incorrect message")
359     dev[0].wait_disconnected(timeout=10)
360
361 def test_ap_wps_conf_pin(dev, apdev):
362     """WPS PIN provisioning with configured AP"""
363     ssid = "test-wps-conf-pin"
364     hostapd.add_ap(apdev[0]['ifname'],
365                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
366                      "wpa_passphrase": "12345678", "wpa": "2",
367                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
368     hapd = hostapd.Hostapd(apdev[0]['ifname'])
369     logger.info("WPS provisioning step")
370     pin = dev[0].wps_read_pin()
371     hapd.request("WPS_PIN any " + pin)
372     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
373     dev[0].dump_monitor()
374     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
375     dev[0].wait_connected(timeout=30)
376     status = dev[0].get_status()
377     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
378         raise Exception("Not fully connected")
379     if status['ssid'] != ssid:
380         raise Exception("Unexpected SSID")
381     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
382         raise Exception("Unexpected encryption configuration")
383     if status['key_mgmt'] != 'WPA2-PSK':
384         raise Exception("Unexpected key_mgmt")
385
386     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
387     bss = dev[1].get_bss(apdev[0]['bssid'])
388     if "[WPS-AUTH]" in bss['flags']:
389         raise Exception("WPS-AUTH flag not cleared")
390     logger.info("Try to connect from another station using the same PIN")
391     pin = dev[1].request("WPS_PIN " + apdev[0]['bssid'])
392     ev = dev[1].wait_event(["WPS-M2D","CTRL-EVENT-CONNECTED"], timeout=30)
393     if ev is None:
394         raise Exception("Operation timed out")
395     if "WPS-M2D" not in ev:
396         raise Exception("Unexpected WPS operation started")
397     hapd.request("WPS_PIN any " + pin)
398     dev[1].wait_connected(timeout=30)
399
400 def test_ap_wps_conf_pin_v1(dev, apdev):
401     """WPS PIN provisioning with configured WPS v1.0 AP"""
402     ssid = "test-wps-conf-pin-v1"
403     hostapd.add_ap(apdev[0]['ifname'],
404                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
405                      "wpa_passphrase": "12345678", "wpa": "2",
406                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
407     hapd = hostapd.Hostapd(apdev[0]['ifname'])
408     logger.info("WPS provisioning step")
409     pin = dev[0].wps_read_pin()
410     hapd.request("SET wps_version_number 0x10")
411     hapd.request("WPS_PIN any " + pin)
412     found = False
413     for i in range(0, 10):
414         dev[0].scan(freq="2412")
415         if "[WPS-PIN]" in dev[0].request("SCAN_RESULTS"):
416             found = True
417             break
418     if not found:
419         hapd.request("SET wps_version_number 0x20")
420         raise Exception("WPS-PIN flag not seen in scan results")
421     dev[0].dump_monitor()
422     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
423     dev[0].wait_connected(timeout=30)
424     hapd.request("SET wps_version_number 0x20")
425
426 def test_ap_wps_conf_pin_2sta(dev, apdev):
427     """Two stations trying to use WPS PIN at the same time"""
428     ssid = "test-wps-conf-pin2"
429     hostapd.add_ap(apdev[0]['ifname'],
430                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
431                      "wpa_passphrase": "12345678", "wpa": "2",
432                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
433     hapd = hostapd.Hostapd(apdev[0]['ifname'])
434     logger.info("WPS provisioning step")
435     pin = "12345670"
436     pin2 = "55554444"
437     hapd.request("WPS_PIN " + dev[0].get_status_field("uuid") + " " + pin)
438     hapd.request("WPS_PIN " + dev[1].get_status_field("uuid") + " " + pin)
439     dev[0].dump_monitor()
440     dev[1].dump_monitor()
441     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
442     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
443     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
444     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
445     dev[0].wait_connected(timeout=30)
446     dev[1].wait_connected(timeout=30)
447
448 def test_ap_wps_conf_pin_timeout(dev, apdev):
449     """WPS PIN provisioning with configured AP timing out PIN"""
450     ssid = "test-wps-conf-pin"
451     hostapd.add_ap(apdev[0]['ifname'],
452                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
453                      "wpa_passphrase": "12345678", "wpa": "2",
454                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
455     hapd = hostapd.Hostapd(apdev[0]['ifname'])
456     addr = dev[0].p2p_interface_addr()
457     pin = dev[0].wps_read_pin()
458     if "FAIL" not in hapd.request("WPS_PIN "):
459         raise Exception("Unexpected success on invalid WPS_PIN")
460     hapd.request("WPS_PIN any " + pin + " 1")
461     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
462     time.sleep(1.1)
463     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
464     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=20)
465     if ev is None:
466         raise Exception("WPS-PIN-NEEDED event timed out")
467     ev = dev[0].wait_event(["WPS-M2D"])
468     if ev is None:
469         raise Exception("M2D not reported")
470     dev[0].request("WPS_CANCEL")
471
472     hapd.request("WPS_PIN any " + pin + " 20 " + addr)
473     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
474     dev[0].wait_connected(timeout=30)
475
476 def test_ap_wps_reg_connect(dev, apdev):
477     """WPS registrar using AP PIN to connect"""
478     ssid = "test-wps-reg-ap-pin"
479     appin = "12345670"
480     hostapd.add_ap(apdev[0]['ifname'],
481                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
482                      "wpa_passphrase": "12345678", "wpa": "2",
483                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
484                      "ap_pin": appin})
485     logger.info("WPS provisioning step")
486     dev[0].dump_monitor()
487     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
488     dev[0].wps_reg(apdev[0]['bssid'], appin)
489     status = dev[0].get_status()
490     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
491         raise Exception("Not fully connected")
492     if status['ssid'] != ssid:
493         raise Exception("Unexpected SSID")
494     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
495         raise Exception("Unexpected encryption configuration")
496     if status['key_mgmt'] != 'WPA2-PSK':
497         raise Exception("Unexpected key_mgmt")
498
499 def test_ap_wps_reg_connect_mixed_mode(dev, apdev):
500     """WPS registrar using AP PIN to connect (WPA+WPA2)"""
501     ssid = "test-wps-reg-ap-pin"
502     appin = "12345670"
503     hostapd.add_ap(apdev[0]['ifname'],
504                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
505                      "wpa_passphrase": "12345678", "wpa": "3",
506                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
507                      "wpa_pairwise": "TKIP", "ap_pin": appin})
508     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
509     dev[0].wps_reg(apdev[0]['bssid'], appin)
510     status = dev[0].get_status()
511     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
512         raise Exception("Not fully connected")
513     if status['ssid'] != ssid:
514         raise Exception("Unexpected SSID")
515     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
516         raise Exception("Unexpected encryption configuration")
517     if status['key_mgmt'] != 'WPA2-PSK':
518         raise Exception("Unexpected key_mgmt")
519
520 def test_ap_wps_reg_override_ap_settings(dev, apdev):
521     """WPS registrar and ap_settings override"""
522     ap_settings = "/tmp/ap_wps_reg_override_ap_settings"
523     try:
524         os.remove(ap_settings)
525     except:
526         pass
527     # Override AP Settings with values that point to another AP
528     data = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
529     data += build_wsc_attr(ATTR_SSID, "test")
530     data += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
531     data += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
532     data += build_wsc_attr(ATTR_NETWORK_KEY, '')
533     data += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[1]['bssid'].replace(':', '')))
534     with open(ap_settings, "w") as f:
535         f.write(data)
536     ssid = "test-wps-reg-ap-pin"
537     appin = "12345670"
538     hostapd.add_ap(apdev[0]['ifname'],
539                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
540                      "wpa_passphrase": "12345678", "wpa": "2",
541                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
542                      "ap_pin": appin, "ap_settings": ap_settings })
543     hapd2 = hostapd.add_ap(apdev[1]['ifname'], { "ssid": "test" })
544     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
545     dev[0].scan_for_bss(apdev[1]['bssid'], freq=2412)
546     dev[0].wps_reg(apdev[0]['bssid'], appin)
547     ev = hapd2.wait_event(['AP-STA-CONNECTED'], timeout=10)
548     os.remove(ap_settings)
549     if ev is None:
550         raise Exception("No connection with the other AP")
551
552 def check_wps_reg_failure(dev, ap, appin):
553     dev.request("WPS_REG " + ap['bssid'] + " " + appin)
554     ev = dev.wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=15)
555     if ev is None:
556         raise Exception("WPS operation timed out")
557     if "WPS-SUCCESS" in ev:
558         raise Exception("WPS operation succeeded unexpectedly")
559     if "config_error=15" not in ev:
560         raise Exception("WPS setup locked state was not reported correctly")
561
562 def test_ap_wps_random_ap_pin(dev, apdev):
563     """WPS registrar using random AP PIN"""
564     ssid = "test-wps-reg-random-ap-pin"
565     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
566     hostapd.add_ap(apdev[0]['ifname'],
567                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
568                      "wpa_passphrase": "12345678", "wpa": "2",
569                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
570                      "device_name": "Wireless AP", "manufacturer": "Company",
571                      "model_name": "WAP", "model_number": "123",
572                      "serial_number": "12345", "device_type": "6-0050F204-1",
573                      "os_version": "01020300",
574                      "config_methods": "label push_button",
575                      "uuid": ap_uuid, "upnp_iface": "lo" })
576     hapd = hostapd.Hostapd(apdev[0]['ifname'])
577     appin = hapd.request("WPS_AP_PIN random")
578     if "FAIL" in appin:
579         raise Exception("Could not generate random AP PIN")
580     if appin not in hapd.request("WPS_AP_PIN get"):
581         raise Exception("Could not fetch current AP PIN")
582     logger.info("WPS provisioning step")
583     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
584     dev[0].wps_reg(apdev[0]['bssid'], appin)
585
586     hapd.request("WPS_AP_PIN disable")
587     logger.info("WPS provisioning step with AP PIN disabled")
588     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
589     check_wps_reg_failure(dev[1], apdev[0], appin)
590
591     logger.info("WPS provisioning step with AP PIN reset")
592     appin = "12345670"
593     hapd.request("WPS_AP_PIN set " + appin)
594     dev[1].wps_reg(apdev[0]['bssid'], appin)
595     dev[0].request("REMOVE_NETWORK all")
596     dev[1].request("REMOVE_NETWORK all")
597     dev[0].wait_disconnected(timeout=10)
598     dev[1].wait_disconnected(timeout=10)
599
600     logger.info("WPS provisioning step after AP PIN timeout")
601     hapd.request("WPS_AP_PIN disable")
602     appin = hapd.request("WPS_AP_PIN random 1")
603     time.sleep(1.1)
604     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
605         raise Exception("AP PIN unexpectedly still enabled")
606     check_wps_reg_failure(dev[0], apdev[0], appin)
607
608     logger.info("WPS provisioning step after AP PIN timeout(2)")
609     hapd.request("WPS_AP_PIN disable")
610     appin = "12345670"
611     hapd.request("WPS_AP_PIN set " + appin + " 1")
612     time.sleep(1.1)
613     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
614         raise Exception("AP PIN unexpectedly still enabled")
615     check_wps_reg_failure(dev[1], apdev[0], appin)
616
617     with fail_test(hapd, 1, "os_get_random;wps_generate_pin"):
618         if "FAIL" in hapd.request("WPS_AP_PIN random 1"):
619             raise Exception("Failed to generate PIN during OOM")
620         hapd.request("WPS_AP_PIN disable")
621
622     with alloc_fail(hapd, 1, "upnp_wps_set_ap_pin"):
623         hapd.request("WPS_AP_PIN set 12345670")
624         hapd.request("WPS_AP_PIN disable")
625
626 def test_ap_wps_reg_config(dev, apdev):
627     """WPS registrar configuring an AP using AP PIN"""
628     ssid = "test-wps-init-ap-pin"
629     appin = "12345670"
630     hostapd.add_ap(apdev[0]['ifname'],
631                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
632                      "ap_pin": appin})
633     logger.info("WPS configuration step")
634     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
635     dev[0].dump_monitor()
636     new_ssid = "wps-new-ssid"
637     new_passphrase = "1234567890"
638     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
639                    new_passphrase)
640     status = dev[0].get_status()
641     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
642         raise Exception("Not fully connected")
643     if status['ssid'] != new_ssid:
644         raise Exception("Unexpected SSID")
645     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
646         raise Exception("Unexpected encryption configuration")
647     if status['key_mgmt'] != 'WPA2-PSK':
648         raise Exception("Unexpected key_mgmt")
649
650     logger.info("Re-configure back to open")
651     dev[0].request("REMOVE_NETWORK all")
652     dev[0].flush_scan_cache()
653     dev[0].dump_monitor()
654     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-open", "OPEN", "NONE", "")
655     status = dev[0].get_status()
656     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
657         raise Exception("Not fully connected")
658     if status['ssid'] != "wps-open":
659         raise Exception("Unexpected SSID")
660     if status['key_mgmt'] != 'NONE':
661         raise Exception("Unexpected key_mgmt")
662
663 def test_ap_wps_reg_config_ext_processing(dev, apdev):
664     """WPS registrar configuring an AP with external config processing"""
665     ssid = "test-wps-init-ap-pin"
666     appin = "12345670"
667     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
668                "wps_cred_processing": "1", "ap_pin": appin}
669     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
670     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
671     new_ssid = "wps-new-ssid"
672     new_passphrase = "1234567890"
673     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
674                    new_passphrase, no_wait=True)
675     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
676     if ev is None:
677         raise Exception("WPS registrar operation timed out")
678     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=15)
679     if ev is None:
680         raise Exception("WPS configuration timed out")
681     if "1026" not in ev:
682         raise Exception("AP Settings missing from event")
683     hapd.request("SET wps_cred_processing 0")
684     if "FAIL" in hapd.request("WPS_CONFIG " + new_ssid.encode("hex") + " WPA2PSK CCMP " + new_passphrase.encode("hex")):
685         raise Exception("WPS_CONFIG command failed")
686     dev[0].wait_connected(timeout=15)
687
688 def test_ap_wps_reg_config_tkip(dev, apdev):
689     """WPS registrar configuring AP to use TKIP and AP upgrading to TKIP+CCMP"""
690     skip_with_fips(dev[0])
691     ssid = "test-wps-init-ap"
692     appin = "12345670"
693     hostapd.add_ap(apdev[0]['ifname'],
694                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
695                      "ap_pin": appin})
696     logger.info("WPS configuration step")
697     dev[0].request("SET wps_version_number 0x10")
698     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
699     dev[0].dump_monitor()
700     new_ssid = "wps-new-ssid-with-tkip"
701     new_passphrase = "1234567890"
702     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPAPSK", "TKIP",
703                    new_passphrase)
704     logger.info("Re-connect to verify WPA2 mixed mode")
705     dev[0].request("DISCONNECT")
706     id = 0
707     dev[0].set_network(id, "pairwise", "CCMP")
708     dev[0].set_network(id, "proto", "RSN")
709     dev[0].connect_network(id)
710     status = dev[0].get_status()
711     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
712         raise Exception("Not fully connected: wpa_state={} bssid={}".format(status['wpa_state'], status['bssid']))
713     if status['ssid'] != new_ssid:
714         raise Exception("Unexpected SSID")
715     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
716         raise Exception("Unexpected encryption configuration")
717     if status['key_mgmt'] != 'WPA2-PSK':
718         raise Exception("Unexpected key_mgmt")
719
720 def test_ap_wps_setup_locked(dev, apdev):
721     """WPS registrar locking up AP setup on AP PIN failures"""
722     ssid = "test-wps-incorrect-ap-pin"
723     appin = "12345670"
724     hostapd.add_ap(apdev[0]['ifname'],
725                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
726                      "wpa_passphrase": "12345678", "wpa": "2",
727                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
728                      "ap_pin": appin})
729     new_ssid = "wps-new-ssid-test"
730     new_passphrase = "1234567890"
731
732     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
733     ap_setup_locked=False
734     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
735         dev[0].dump_monitor()
736         logger.info("Try incorrect AP PIN - attempt " + pin)
737         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
738                        "CCMP", new_passphrase, no_wait=True)
739         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
740         if ev is None:
741             raise Exception("Timeout on receiving WPS operation failure event")
742         if "CTRL-EVENT-CONNECTED" in ev:
743             raise Exception("Unexpected connection")
744         if "config_error=15" in ev:
745             logger.info("AP Setup Locked")
746             ap_setup_locked=True
747         elif "config_error=18" not in ev:
748             raise Exception("config_error=18 not reported")
749         dev[0].wait_disconnected(timeout=10)
750         time.sleep(0.1)
751     if not ap_setup_locked:
752         raise Exception("AP setup was not locked")
753     dev[0].request("WPS_CANCEL")
754     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True,
755                         only_new=True)
756     bss = dev[0].get_bss(apdev[0]['bssid'])
757     if 'wps_ap_setup_locked' not in bss or bss['wps_ap_setup_locked'] != '1':
758         logger.info("BSS: " + str(bss))
759         raise Exception("AP Setup Locked not indicated in scan results")
760
761     hapd = hostapd.Hostapd(apdev[0]['ifname'])
762     status = hapd.request("WPS_GET_STATUS")
763     if "Last WPS result: Failed" not in status:
764         raise Exception("WPS failure result not shown correctly")
765     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
766         raise Exception("Peer address not shown correctly")
767
768     time.sleep(0.5)
769     dev[0].dump_monitor()
770     logger.info("WPS provisioning step")
771     pin = dev[0].wps_read_pin()
772     hapd = hostapd.Hostapd(apdev[0]['ifname'])
773     hapd.request("WPS_PIN any " + pin)
774     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
775     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
776     if ev is None:
777         raise Exception("WPS success was not reported")
778     dev[0].wait_connected(timeout=30)
779
780     appin = hapd.request("WPS_AP_PIN random")
781     if "FAIL" in appin:
782         raise Exception("Could not generate random AP PIN")
783     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=10)
784     if ev is None:
785         raise Exception("Failed to unlock AP PIN")
786
787 def test_ap_wps_setup_locked_timeout(dev, apdev):
788     """WPS re-enabling AP PIN after timeout"""
789     ssid = "test-wps-incorrect-ap-pin"
790     appin = "12345670"
791     hostapd.add_ap(apdev[0]['ifname'],
792                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
793                      "wpa_passphrase": "12345678", "wpa": "2",
794                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
795                      "ap_pin": appin})
796     new_ssid = "wps-new-ssid-test"
797     new_passphrase = "1234567890"
798
799     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
800     ap_setup_locked=False
801     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
802         dev[0].dump_monitor()
803         logger.info("Try incorrect AP PIN - attempt " + pin)
804         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
805                        "CCMP", new_passphrase, no_wait=True)
806         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"], timeout=15)
807         if ev is None:
808             raise Exception("Timeout on receiving WPS operation failure event")
809         if "CTRL-EVENT-CONNECTED" in ev:
810             raise Exception("Unexpected connection")
811         if "config_error=15" in ev:
812             logger.info("AP Setup Locked")
813             ap_setup_locked=True
814             break
815         elif "config_error=18" not in ev:
816             raise Exception("config_error=18 not reported")
817         dev[0].wait_disconnected(timeout=10)
818         time.sleep(0.1)
819     if not ap_setup_locked:
820         raise Exception("AP setup was not locked")
821     hapd = hostapd.Hostapd(apdev[0]['ifname'])
822     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=80)
823     if ev is None:
824         raise Exception("AP PIN did not get unlocked on 60 second timeout")
825
826 def test_ap_wps_setup_locked_2(dev, apdev):
827     """WPS AP configured for special ap_setup_locked=2 mode"""
828     ssid = "test-wps-ap-pin"
829     appin = "12345670"
830     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
831                "wpa_passphrase": "12345678", "wpa": "2",
832                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
833                "ap_pin": appin, "ap_setup_locked": "2" }
834     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
835     new_ssid = "wps-new-ssid-test"
836     new_passphrase = "1234567890"
837
838     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
839     dev[0].wps_reg(apdev[0]['bssid'], appin)
840     dev[0].request("REMOVE_NETWORK all")
841     dev[0].wait_disconnected()
842
843     hapd.dump_monitor()
844     dev[0].dump_monitor()
845     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK",
846                    "CCMP", new_passphrase, no_wait=True)
847
848     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
849     if ev is None:
850         raise Exception("hostapd did not report WPS failure")
851     if "msg=12 config_error=15" not in ev:
852         raise Exception("Unexpected failure reason (AP): " + ev)
853
854     ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
855     if ev is None:
856         raise Exception("Timeout on receiving WPS operation failure event")
857     if "CTRL-EVENT-CONNECTED" in ev:
858         raise Exception("Unexpected connection")
859     if "config_error=15" not in ev:
860         raise Exception("Unexpected failure reason (STA): " + ev)
861     dev[0].request("WPS_CANCEL")
862     dev[0].wait_disconnected()
863
864 def test_ap_wps_pbc_overlap_2ap(dev, apdev):
865     """WPS PBC session overlap with two active APs"""
866     hostapd.add_ap(apdev[0]['ifname'],
867                    { "ssid": "wps1", "eap_server": "1", "wps_state": "2",
868                      "wpa_passphrase": "12345678", "wpa": "2",
869                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
870                      "wps_independent": "1"})
871     hostapd.add_ap(apdev[1]['ifname'],
872                    { "ssid": "wps2", "eap_server": "1", "wps_state": "2",
873                      "wpa_passphrase": "123456789", "wpa": "2",
874                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
875                      "wps_independent": "1"})
876     hapd = hostapd.Hostapd(apdev[0]['ifname'])
877     hapd.request("WPS_PBC")
878     hapd2 = hostapd.Hostapd(apdev[1]['ifname'])
879     hapd2.request("WPS_PBC")
880     logger.info("WPS provisioning step")
881     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
882     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
883     dev[0].request("WPS_PBC")
884     ev = dev[0].wait_event(["WPS-OVERLAP-DETECTED"], timeout=15)
885     if ev is None:
886         raise Exception("PBC session overlap not detected")
887     hapd.request("DISABLE")
888     hapd2.request("DISABLE")
889     dev[0].flush_scan_cache()
890
891 def test_ap_wps_pbc_overlap_2sta(dev, apdev):
892     """WPS PBC session overlap with two active STAs"""
893     ssid = "test-wps-pbc-overlap"
894     hostapd.add_ap(apdev[0]['ifname'],
895                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
896                      "wpa_passphrase": "12345678", "wpa": "2",
897                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
898     hapd = hostapd.Hostapd(apdev[0]['ifname'])
899     logger.info("WPS provisioning step")
900     hapd.request("WPS_PBC")
901     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
902     dev[0].dump_monitor()
903     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
904     dev[1].dump_monitor()
905     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
906     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
907     ev = dev[0].wait_event(["WPS-M2D"], timeout=15)
908     if ev is None:
909         raise Exception("PBC session overlap not detected (dev0)")
910     if "config_error=12" not in ev:
911         raise Exception("PBC session overlap not correctly reported (dev0)")
912     dev[0].request("WPS_CANCEL")
913     dev[0].request("DISCONNECT")
914     ev = dev[1].wait_event(["WPS-M2D"], timeout=15)
915     if ev is None:
916         raise Exception("PBC session overlap not detected (dev1)")
917     if "config_error=12" not in ev:
918         raise Exception("PBC session overlap not correctly reported (dev1)")
919     dev[1].request("WPS_CANCEL")
920     dev[1].request("DISCONNECT")
921     hapd.request("WPS_CANCEL")
922     ret = hapd.request("WPS_PBC")
923     if "FAIL" not in ret:
924         raise Exception("PBC mode allowed to be started while PBC overlap still active")
925     hapd.request("DISABLE")
926     dev[0].flush_scan_cache()
927     dev[1].flush_scan_cache()
928
929 def test_ap_wps_cancel(dev, apdev):
930     """WPS AP cancelling enabled config method"""
931     ssid = "test-wps-ap-cancel"
932     hostapd.add_ap(apdev[0]['ifname'],
933                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
934                      "wpa_passphrase": "12345678", "wpa": "2",
935                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
936     bssid = apdev[0]['bssid']
937     hapd = hostapd.Hostapd(apdev[0]['ifname'])
938
939     logger.info("Verify PBC enable/cancel")
940     hapd.request("WPS_PBC")
941     dev[0].scan(freq="2412")
942     dev[0].scan(freq="2412")
943     bss = dev[0].get_bss(apdev[0]['bssid'])
944     if "[WPS-PBC]" not in bss['flags']:
945         raise Exception("WPS-PBC flag missing")
946     if "FAIL" in hapd.request("WPS_CANCEL"):
947         raise Exception("WPS_CANCEL failed")
948     dev[0].scan(freq="2412")
949     dev[0].scan(freq="2412")
950     bss = dev[0].get_bss(apdev[0]['bssid'])
951     if "[WPS-PBC]" in bss['flags']:
952         raise Exception("WPS-PBC flag not cleared")
953
954     logger.info("Verify PIN enable/cancel")
955     hapd.request("WPS_PIN any 12345670")
956     dev[0].scan(freq="2412")
957     dev[0].scan(freq="2412")
958     bss = dev[0].get_bss(apdev[0]['bssid'])
959     if "[WPS-AUTH]" not in bss['flags']:
960         raise Exception("WPS-AUTH flag missing")
961     if "FAIL" in hapd.request("WPS_CANCEL"):
962         raise Exception("WPS_CANCEL failed")
963     dev[0].scan(freq="2412")
964     dev[0].scan(freq="2412")
965     bss = dev[0].get_bss(apdev[0]['bssid'])
966     if "[WPS-AUTH]" in bss['flags']:
967         raise Exception("WPS-AUTH flag not cleared")
968
969 def test_ap_wps_er_add_enrollee(dev, apdev):
970     """WPS ER configuring AP and adding a new enrollee using PIN"""
971     try:
972         _test_ap_wps_er_add_enrollee(dev, apdev)
973     finally:
974         dev[0].request("WPS_ER_STOP")
975
976 def _test_ap_wps_er_add_enrollee(dev, apdev):
977     ssid = "wps-er-add-enrollee"
978     ap_pin = "12345670"
979     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
980     hostapd.add_ap(apdev[0]['ifname'],
981                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
982                      "device_name": "Wireless AP", "manufacturer": "Company",
983                      "model_name": "WAP", "model_number": "123",
984                      "serial_number": "12345", "device_type": "6-0050F204-1",
985                      "os_version": "01020300",
986                      'friendly_name': "WPS AP - <>&'\" - TEST",
987                      "config_methods": "label push_button",
988                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
989     logger.info("WPS configuration step")
990     new_passphrase = "1234567890"
991     dev[0].dump_monitor()
992     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
993     dev[0].wps_reg(apdev[0]['bssid'], ap_pin, ssid, "WPA2PSK", "CCMP",
994                    new_passphrase)
995     status = dev[0].get_status()
996     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
997         raise Exception("Not fully connected")
998     if status['ssid'] != ssid:
999         raise Exception("Unexpected SSID")
1000     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
1001         raise Exception("Unexpected encryption configuration")
1002     if status['key_mgmt'] != 'WPA2-PSK':
1003         raise Exception("Unexpected key_mgmt")
1004
1005     logger.info("Start ER")
1006     dev[0].request("WPS_ER_START ifname=lo")
1007     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1008     if ev is None:
1009         raise Exception("AP discovery timed out")
1010     if ap_uuid not in ev:
1011         raise Exception("Expected AP UUID not found")
1012     if "|WPS AP - &lt;&gt;&amp;&apos;&quot; - TEST|Company|" not in ev:
1013         raise Exception("Expected friendly name not found")
1014
1015     logger.info("Learn AP configuration through UPnP")
1016     dev[0].dump_monitor()
1017     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1018     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1019     if ev is None:
1020         raise Exception("AP learn timed out")
1021     if ap_uuid not in ev:
1022         raise Exception("Expected AP UUID not in settings")
1023     if "ssid=" + ssid not in ev:
1024         raise Exception("Expected SSID not in settings")
1025     if "key=" + new_passphrase not in ev:
1026         raise Exception("Expected passphrase not in settings")
1027     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1028     if ev is None:
1029         raise Exception("WPS-FAIL after AP learn timed out")
1030     time.sleep(0.1)
1031
1032     logger.info("Add Enrollee using ER")
1033     pin = dev[1].wps_read_pin()
1034     dev[0].dump_monitor()
1035     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1036     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1037     dev[1].dump_monitor()
1038     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1039     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1040     if ev is None:
1041         raise Exception("Enrollee did not report success")
1042     dev[1].wait_connected(timeout=15)
1043     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1044     if ev is None:
1045         raise Exception("WPS ER did not report success")
1046     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1047
1048     logger.info("Add a specific Enrollee using ER")
1049     pin = dev[2].wps_read_pin()
1050     addr2 = dev[2].p2p_interface_addr()
1051     dev[0].dump_monitor()
1052     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1053     dev[2].dump_monitor()
1054     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1055     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1056     if ev is None:
1057         raise Exception("Enrollee not seen")
1058     if addr2 not in ev:
1059         raise Exception("Unexpected Enrollee MAC address")
1060     dev[0].request("WPS_ER_PIN " + addr2 + " " + pin + " " + addr2)
1061     dev[2].wait_connected(timeout=30)
1062     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1063     if ev is None:
1064         raise Exception("WPS ER did not report success")
1065
1066     logger.info("Verify registrar selection behavior")
1067     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1068     dev[1].request("DISCONNECT")
1069     dev[1].wait_disconnected(timeout=10)
1070     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1071     dev[1].scan(freq="2412")
1072     bss = dev[1].get_bss(apdev[0]['bssid'])
1073     if "[WPS-AUTH]" not in bss['flags']:
1074         # It is possible for scan to miss an update especially when running
1075         # tests under load with multiple VMs, so allow another attempt.
1076         dev[1].scan(freq="2412")
1077         bss = dev[1].get_bss(apdev[0]['bssid'])
1078         if "[WPS-AUTH]" not in bss['flags']:
1079             raise Exception("WPS-AUTH flag missing")
1080
1081     logger.info("Stop ER")
1082     dev[0].dump_monitor()
1083     dev[0].request("WPS_ER_STOP")
1084     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"])
1085     if ev is None:
1086         raise Exception("WPS ER unsubscription timed out")
1087     # It takes some time for the UPnP UNSUBSCRIBE command to go through, so wait
1088     # a bit before verifying that the scan results have changed.
1089     time.sleep(0.2)
1090
1091     for i in range(0, 10):
1092         dev[1].request("BSS_FLUSH 0")
1093         dev[1].scan(freq="2412", only_new=True)
1094         bss = dev[1].get_bss(apdev[0]['bssid'])
1095         if bss and 'flags' in bss and "[WPS-AUTH]" not in bss['flags']:
1096             break
1097         logger.debug("WPS-AUTH flag was still in place - wait a bit longer")
1098         time.sleep(0.1)
1099     if "[WPS-AUTH]" in bss['flags']:
1100         raise Exception("WPS-AUTH flag not removed")
1101
1102 def test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1103     """WPS ER adding a new enrollee identified by UUID"""
1104     try:
1105         _test_ap_wps_er_add_enrollee_uuid(dev, apdev)
1106     finally:
1107         dev[0].request("WPS_ER_STOP")
1108
1109 def _test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1110     ssid = "wps-er-add-enrollee"
1111     ap_pin = "12345670"
1112     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1113     hostapd.add_ap(apdev[0]['ifname'],
1114                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1115                      "wpa_passphrase": "12345678", "wpa": "2",
1116                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1117                      "device_name": "Wireless AP", "manufacturer": "Company",
1118                      "model_name": "WAP", "model_number": "123",
1119                      "serial_number": "12345", "device_type": "6-0050F204-1",
1120                      "os_version": "01020300",
1121                      "config_methods": "label push_button",
1122                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1123     logger.info("WPS configuration step")
1124     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1125     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1126
1127     logger.info("Start ER")
1128     dev[0].request("WPS_ER_START ifname=lo")
1129     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1130     if ev is None:
1131         raise Exception("AP discovery timed out")
1132     if ap_uuid not in ev:
1133         raise Exception("Expected AP UUID not found")
1134
1135     logger.info("Learn AP configuration through UPnP")
1136     dev[0].dump_monitor()
1137     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1138     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1139     if ev is None:
1140         raise Exception("AP learn timed out")
1141     if ap_uuid not in ev:
1142         raise Exception("Expected AP UUID not in settings")
1143     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1144     if ev is None:
1145         raise Exception("WPS-FAIL after AP learn timed out")
1146     time.sleep(0.1)
1147
1148     logger.info("Add a specific Enrollee using ER (PBC/UUID)")
1149     addr1 = dev[1].p2p_interface_addr()
1150     dev[0].dump_monitor()
1151     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1152     dev[1].dump_monitor()
1153     dev[1].request("WPS_PBC %s" % apdev[0]['bssid'])
1154     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1155     if ev is None:
1156         raise Exception("Enrollee not seen")
1157     if addr1 not in ev:
1158         raise Exception("Unexpected Enrollee MAC address")
1159     uuid = ev.split(' ')[1]
1160     dev[0].request("WPS_ER_PBC " + uuid)
1161     dev[1].wait_connected(timeout=30)
1162     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1163     if ev is None:
1164         raise Exception("WPS ER did not report success")
1165
1166     logger.info("Add a specific Enrollee using ER (PIN/UUID)")
1167     pin = dev[2].wps_read_pin()
1168     addr2 = dev[2].p2p_interface_addr()
1169     dev[0].dump_monitor()
1170     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1171     dev[2].dump_monitor()
1172     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1173     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1174     if ev is None:
1175         raise Exception("Enrollee not seen")
1176     if addr2 not in ev:
1177         raise Exception("Unexpected Enrollee MAC address")
1178     uuid = ev.split(' ')[1]
1179     dev[0].request("WPS_ER_PIN " + uuid + " " + pin)
1180     dev[2].wait_connected(timeout=30)
1181     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1182     if ev is None:
1183         raise Exception("WPS ER did not report success")
1184
1185     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-REMOVE"], timeout=15)
1186     if ev is None:
1187         raise Exception("No Enrollee STA entry timeout seen")
1188
1189     logger.info("Stop ER")
1190     dev[0].dump_monitor()
1191     dev[0].request("WPS_ER_STOP")
1192
1193 def test_ap_wps_er_multi_add_enrollee(dev, apdev):
1194     """Multiple WPS ERs adding a new enrollee using PIN"""
1195     try:
1196         _test_ap_wps_er_multi_add_enrollee(dev, apdev)
1197     finally:
1198         dev[0].request("WPS_ER_STOP")
1199
1200 def _test_ap_wps_er_multi_add_enrollee(dev, apdev):
1201     ssid = "wps-er-add-enrollee"
1202     ap_pin = "12345670"
1203     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1204     hostapd.add_ap(apdev[0]['ifname'],
1205                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1206                      "wpa_passphrase": "12345678", "wpa": "2",
1207                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1208                      "device_name": "Wireless AP", "manufacturer": "Company",
1209                      "model_name": "WAP", "model_number": "123",
1210                      "serial_number": "12345", "device_type": "6-0050F204-1",
1211                      "os_version": "01020300",
1212                      'friendly_name': "WPS AP",
1213                      "config_methods": "label push_button",
1214                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1215
1216     for i in range(2):
1217         dev[i].scan_for_bss(apdev[0]['bssid'], freq=2412)
1218         dev[i].wps_reg(apdev[0]['bssid'], ap_pin)
1219         dev[i].request("WPS_ER_START ifname=lo")
1220     for i in range(2):
1221         ev = dev[i].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1222         if ev is None:
1223             raise Exception("AP discovery timed out")
1224         dev[i].dump_monitor()
1225         dev[i].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1226         ev = dev[i].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1227         if ev is None:
1228             raise Exception("AP learn timed out")
1229         ev = dev[i].wait_event(["WPS-FAIL"], timeout=15)
1230         if ev is None:
1231             raise Exception("WPS-FAIL after AP learn timed out")
1232
1233     time.sleep(0.1)
1234
1235     pin = dev[2].wps_read_pin()
1236     addr = dev[2].own_addr()
1237     dev[0].dump_monitor()
1238     dev[0].request("WPS_ER_PIN any " + pin + " " + addr)
1239     dev[1].dump_monitor()
1240     dev[1].request("WPS_ER_PIN any " + pin + " " + addr)
1241
1242     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1243     dev[2].dump_monitor()
1244     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1245     ev = dev[2].wait_event(["WPS-SUCCESS"], timeout=30)
1246     if ev is None:
1247         raise Exception("Enrollee did not report success")
1248     dev[2].wait_connected(timeout=15)
1249
1250 def test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1251     """WPS ER connected to AP and adding a new enrollee using PBC"""
1252     try:
1253         _test_ap_wps_er_add_enrollee_pbc(dev, apdev)
1254     finally:
1255         dev[0].request("WPS_ER_STOP")
1256
1257 def _test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1258     ssid = "wps-er-add-enrollee-pbc"
1259     ap_pin = "12345670"
1260     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1261     hostapd.add_ap(apdev[0]['ifname'],
1262                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1263                      "wpa_passphrase": "12345678", "wpa": "2",
1264                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1265                      "device_name": "Wireless AP", "manufacturer": "Company",
1266                      "model_name": "WAP", "model_number": "123",
1267                      "serial_number": "12345", "device_type": "6-0050F204-1",
1268                      "os_version": "01020300",
1269                      "config_methods": "label push_button",
1270                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1271     logger.info("Learn AP configuration")
1272     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1273     dev[0].dump_monitor()
1274     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1275     status = dev[0].get_status()
1276     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1277         raise Exception("Not fully connected")
1278
1279     logger.info("Start ER")
1280     dev[0].request("WPS_ER_START ifname=lo")
1281     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1282     if ev is None:
1283         raise Exception("AP discovery timed out")
1284     if ap_uuid not in ev:
1285         raise Exception("Expected AP UUID not found")
1286
1287     enrollee = dev[1].p2p_interface_addr()
1288
1289     if "FAIL-UNKNOWN-UUID" not in dev[0].request("WPS_ER_PBC " + enrollee):
1290         raise Exception("Unknown UUID not reported")
1291
1292     logger.info("Add Enrollee using ER and PBC")
1293     dev[0].dump_monitor()
1294     dev[1].dump_monitor()
1295     dev[1].request("WPS_PBC")
1296
1297     for i in range(0, 2):
1298         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1299         if ev is None:
1300             raise Exception("Enrollee discovery timed out")
1301         if enrollee in ev:
1302             break
1303         if i == 1:
1304             raise Exception("Expected Enrollee not found")
1305     if "FAIL-NO-AP-SETTINGS" not in dev[0].request("WPS_ER_PBC " + enrollee):
1306         raise Exception("Unknown UUID not reported")
1307     logger.info("Use learned network configuration on ER")
1308     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1309     if "OK" not in dev[0].request("WPS_ER_PBC " + enrollee):
1310         raise Exception("WPS_ER_PBC failed")
1311
1312     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=15)
1313     if ev is None:
1314         raise Exception("Enrollee did not report success")
1315     dev[1].wait_connected(timeout=15)
1316     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1317     if ev is None:
1318         raise Exception("WPS ER did not report success")
1319     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1320
1321 def test_ap_wps_er_pbc_overlap(dev, apdev):
1322     """WPS ER connected to AP and PBC session overlap"""
1323     try:
1324         _test_ap_wps_er_pbc_overlap(dev, apdev)
1325     finally:
1326         dev[0].request("WPS_ER_STOP")
1327
1328 def _test_ap_wps_er_pbc_overlap(dev, apdev):
1329     ssid = "wps-er-add-enrollee-pbc"
1330     ap_pin = "12345670"
1331     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1332     hostapd.add_ap(apdev[0]['ifname'],
1333                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1334                      "wpa_passphrase": "12345678", "wpa": "2",
1335                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1336                      "device_name": "Wireless AP", "manufacturer": "Company",
1337                      "model_name": "WAP", "model_number": "123",
1338                      "serial_number": "12345", "device_type": "6-0050F204-1",
1339                      "os_version": "01020300",
1340                      "config_methods": "label push_button",
1341                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1342     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1343     dev[0].dump_monitor()
1344     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1345
1346     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1347     dev[2].scan_for_bss(apdev[0]['bssid'], freq="2412")
1348     # avoid leaving dev 1 or 2 as the last Probe Request to the AP
1349     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True)
1350
1351     dev[0].dump_monitor()
1352     dev[0].request("WPS_ER_START ifname=lo")
1353
1354     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1355     if ev is None:
1356         raise Exception("AP discovery timed out")
1357     if ap_uuid not in ev:
1358         raise Exception("Expected AP UUID not found")
1359
1360     # verify BSSID selection of the AP instead of UUID
1361     if "FAIL" in dev[0].request("WPS_ER_SET_CONFIG " + apdev[0]['bssid'] + " 0"):
1362         raise Exception("Could not select AP based on BSSID")
1363
1364     dev[0].dump_monitor()
1365     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1366     dev[2].request("WPS_PBC " + apdev[0]['bssid'])
1367     ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1368     if ev is None:
1369         raise Exception("PBC scan failed")
1370     ev = dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1371     if ev is None:
1372         raise Exception("PBC scan failed")
1373     found1 = False
1374     found2 = False
1375     addr1 = dev[1].own_addr()
1376     addr2 = dev[2].own_addr()
1377     for i in range(3):
1378         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1379         if ev is None:
1380             raise Exception("Enrollee discovery timed out")
1381         if addr1 in ev:
1382             found1 = True
1383             if found2:
1384                 break
1385         if addr2 in ev:
1386             found2 = True
1387             if found1:
1388                 break
1389     if dev[0].request("WPS_ER_PBC " + ap_uuid) != "FAIL-PBC-OVERLAP\n":
1390         raise Exception("PBC overlap not reported")
1391     dev[1].request("WPS_CANCEL")
1392     dev[2].request("WPS_CANCEL")
1393     if dev[0].request("WPS_ER_PBC foo") != "FAIL\n":
1394         raise Exception("Invalid WPS_ER_PBC accepted")
1395
1396 def test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1397     """WPS v1.0 ER connected to AP and adding a new enrollee using PIN"""
1398     try:
1399         _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev)
1400     finally:
1401         dev[0].request("WPS_ER_STOP")
1402
1403 def _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1404     ssid = "wps-er-add-enrollee-pbc"
1405     ap_pin = "12345670"
1406     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1407     hostapd.add_ap(apdev[0]['ifname'],
1408                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1409                      "wpa_passphrase": "12345678", "wpa": "2",
1410                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1411                      "device_name": "Wireless AP", "manufacturer": "Company",
1412                      "model_name": "WAP", "model_number": "123",
1413                      "serial_number": "12345", "device_type": "6-0050F204-1",
1414                      "os_version": "01020300",
1415                      "config_methods": "label push_button",
1416                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1417     logger.info("Learn AP configuration")
1418     dev[0].request("SET wps_version_number 0x10")
1419     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1420     dev[0].dump_monitor()
1421     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1422     status = dev[0].get_status()
1423     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1424         raise Exception("Not fully connected")
1425
1426     logger.info("Start ER")
1427     dev[0].request("WPS_ER_START ifname=lo")
1428     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1429     if ev is None:
1430         raise Exception("AP discovery timed out")
1431     if ap_uuid not in ev:
1432         raise Exception("Expected AP UUID not found")
1433
1434     logger.info("Use learned network configuration on ER")
1435     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1436
1437     logger.info("Add Enrollee using ER and PIN")
1438     enrollee = dev[1].p2p_interface_addr()
1439     pin = dev[1].wps_read_pin()
1440     dev[0].dump_monitor()
1441     dev[0].request("WPS_ER_PIN any " + pin + " " + enrollee)
1442     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1443     dev[1].dump_monitor()
1444     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1445     dev[1].wait_connected(timeout=30)
1446     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1447     if ev is None:
1448         raise Exception("WPS ER did not report success")
1449
1450 def test_ap_wps_er_config_ap(dev, apdev):
1451     """WPS ER configuring AP over UPnP"""
1452     try:
1453         _test_ap_wps_er_config_ap(dev, apdev)
1454     finally:
1455         dev[0].request("WPS_ER_STOP")
1456
1457 def _test_ap_wps_er_config_ap(dev, apdev):
1458     ssid = "wps-er-ap-config"
1459     ap_pin = "12345670"
1460     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1461     hostapd.add_ap(apdev[0]['ifname'],
1462                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1463                      "wpa_passphrase": "12345678", "wpa": "2",
1464                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1465                      "device_name": "Wireless AP", "manufacturer": "Company",
1466                      "model_name": "WAP", "model_number": "123",
1467                      "serial_number": "12345", "device_type": "6-0050F204-1",
1468                      "os_version": "01020300",
1469                      "config_methods": "label push_button",
1470                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1471
1472     logger.info("Connect ER to the AP")
1473     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
1474
1475     logger.info("WPS configuration step")
1476     dev[0].request("WPS_ER_START ifname=lo")
1477     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1478     if ev is None:
1479         raise Exception("AP discovery timed out")
1480     if ap_uuid not in ev:
1481         raise Exception("Expected AP UUID not found")
1482     new_passphrase = "1234567890"
1483     dev[0].request("WPS_ER_CONFIG " + apdev[0]['bssid'] + " " + ap_pin + " " +
1484                    ssid.encode("hex") + " WPA2PSK CCMP " +
1485                    new_passphrase.encode("hex"))
1486     ev = dev[0].wait_event(["WPS-SUCCESS"])
1487     if ev is None:
1488         raise Exception("WPS ER configuration operation timed out")
1489     dev[0].wait_disconnected(timeout=10)
1490     dev[0].connect(ssid, psk="1234567890", scan_freq="2412")
1491
1492     logger.info("WPS ER restart")
1493     dev[0].request("WPS_ER_START")
1494     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1495     if ev is None:
1496         raise Exception("AP discovery timed out on ER restart")
1497     if ap_uuid not in ev:
1498         raise Exception("Expected AP UUID not found on ER restart")
1499     if "OK" not in dev[0].request("WPS_ER_STOP"):
1500         raise Exception("WPS_ER_STOP failed")
1501     if "OK" not in dev[0].request("WPS_ER_STOP"):
1502         raise Exception("WPS_ER_STOP failed")
1503
1504 def test_ap_wps_er_cache_ap_settings(dev, apdev):
1505     """WPS ER caching AP settings"""
1506     try:
1507         _test_ap_wps_er_cache_ap_settings(dev, apdev)
1508     finally:
1509         dev[0].request("WPS_ER_STOP")
1510
1511 def _test_ap_wps_er_cache_ap_settings(dev, apdev):
1512     ssid = "wps-er-add-enrollee"
1513     ap_pin = "12345670"
1514     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1515     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1516                "wpa_passphrase": "12345678", "wpa": "2",
1517                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1518                "device_name": "Wireless AP", "manufacturer": "Company",
1519                "model_name": "WAP", "model_number": "123",
1520                "serial_number": "12345", "device_type": "6-0050F204-1",
1521                "os_version": "01020300",
1522                "config_methods": "label push_button",
1523                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1524     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1525     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1526     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1527     id = int(dev[0].list_networks()[0]['id'])
1528     dev[0].set_network(id, "scan_freq", "2412")
1529
1530     dev[0].request("WPS_ER_START ifname=lo")
1531     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1532     if ev is None:
1533         raise Exception("AP discovery timed out")
1534     if ap_uuid not in ev:
1535         raise Exception("Expected AP UUID not found")
1536
1537     dev[0].dump_monitor()
1538     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1539     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1540     if ev is None:
1541         raise Exception("AP learn timed out")
1542     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1543     if ev is None:
1544         raise Exception("WPS-FAIL after AP learn timed out")
1545     time.sleep(0.1)
1546
1547     hapd.disable()
1548
1549     for i in range(2):
1550         ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1551                                  "CTRL-EVENT-DISCONNECTED" ],
1552                                timeout=15)
1553         if ev is None:
1554             raise Exception("AP removal or disconnection timed out")
1555
1556     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1557     for i in range(2):
1558         ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1559                                timeout=15)
1560         if ev is None:
1561             raise Exception("AP discovery or connection timed out")
1562
1563     pin = dev[1].wps_read_pin()
1564     dev[0].dump_monitor()
1565     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1566
1567     time.sleep(0.2)
1568
1569     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1570     dev[1].dump_monitor()
1571     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1572     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1573     if ev is None:
1574         raise Exception("Enrollee did not report success")
1575     dev[1].wait_connected(timeout=15)
1576     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1577     if ev is None:
1578         raise Exception("WPS ER did not report success")
1579
1580     dev[0].dump_monitor()
1581     dev[0].request("WPS_ER_STOP")
1582
1583 def test_ap_wps_er_cache_ap_settings_oom(dev, apdev):
1584     """WPS ER caching AP settings (OOM)"""
1585     try:
1586         _test_ap_wps_er_cache_ap_settings_oom(dev, apdev)
1587     finally:
1588         dev[0].request("WPS_ER_STOP")
1589
1590 def _test_ap_wps_er_cache_ap_settings_oom(dev, apdev):
1591     ssid = "wps-er-add-enrollee"
1592     ap_pin = "12345670"
1593     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1594     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1595                "wpa_passphrase": "12345678", "wpa": "2",
1596                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1597                "device_name": "Wireless AP", "manufacturer": "Company",
1598                "model_name": "WAP", "model_number": "123",
1599                "serial_number": "12345", "device_type": "6-0050F204-1",
1600                "os_version": "01020300",
1601                "config_methods": "label push_button",
1602                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1603     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1604     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1605     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1606     id = int(dev[0].list_networks()[0]['id'])
1607     dev[0].set_network(id, "scan_freq", "2412")
1608
1609     dev[0].request("WPS_ER_START ifname=lo")
1610     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1611     if ev is None:
1612         raise Exception("AP discovery timed out")
1613     if ap_uuid not in ev:
1614         raise Exception("Expected AP UUID not found")
1615
1616     dev[0].dump_monitor()
1617     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1618     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1619     if ev is None:
1620         raise Exception("AP learn timed out")
1621     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1622     if ev is None:
1623         raise Exception("WPS-FAIL after AP learn timed out")
1624     time.sleep(0.1)
1625
1626     with alloc_fail(dev[0], 1, "=wps_er_ap_use_cached_settings"):
1627         hapd.disable()
1628
1629         for i in range(2):
1630             ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1631                                      "CTRL-EVENT-DISCONNECTED" ],
1632                                    timeout=15)
1633             if ev is None:
1634                 raise Exception("AP removal or disconnection timed out")
1635
1636         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1637         for i in range(2):
1638             ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1639                                    timeout=15)
1640             if ev is None:
1641                 raise Exception("AP discovery or connection timed out")
1642
1643     dev[0].request("WPS_ER_STOP")
1644
1645 def test_ap_wps_er_cache_ap_settings_oom2(dev, apdev):
1646     """WPS ER caching AP settings (OOM 2)"""
1647     try:
1648         _test_ap_wps_er_cache_ap_settings_oom2(dev, apdev)
1649     finally:
1650         dev[0].request("WPS_ER_STOP")
1651
1652 def _test_ap_wps_er_cache_ap_settings_oom2(dev, apdev):
1653     ssid = "wps-er-add-enrollee"
1654     ap_pin = "12345670"
1655     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1656     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1657                "wpa_passphrase": "12345678", "wpa": "2",
1658                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1659                "device_name": "Wireless AP", "manufacturer": "Company",
1660                "model_name": "WAP", "model_number": "123",
1661                "serial_number": "12345", "device_type": "6-0050F204-1",
1662                "os_version": "01020300",
1663                "config_methods": "label push_button",
1664                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1665     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1666     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1667     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1668     id = int(dev[0].list_networks()[0]['id'])
1669     dev[0].set_network(id, "scan_freq", "2412")
1670
1671     dev[0].request("WPS_ER_START ifname=lo")
1672     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1673     if ev is None:
1674         raise Exception("AP discovery timed out")
1675     if ap_uuid not in ev:
1676         raise Exception("Expected AP UUID not found")
1677
1678     dev[0].dump_monitor()
1679     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1680     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1681     if ev is None:
1682         raise Exception("AP learn timed out")
1683     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1684     if ev is None:
1685         raise Exception("WPS-FAIL after AP learn timed out")
1686     time.sleep(0.1)
1687
1688     with alloc_fail(dev[0], 1, "=wps_er_ap_cache_settings"):
1689         hapd.disable()
1690
1691         for i in range(2):
1692             ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1693                                      "CTRL-EVENT-DISCONNECTED" ],
1694                                    timeout=15)
1695             if ev is None:
1696                 raise Exception("AP removal or disconnection timed out")
1697
1698         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1699         for i in range(2):
1700             ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1701                                    timeout=15)
1702             if ev is None:
1703                 raise Exception("AP discovery or connection timed out")
1704
1705     dev[0].request("WPS_ER_STOP")
1706
1707 def test_ap_wps_er_subscribe_oom(dev, apdev):
1708     """WPS ER subscribe OOM"""
1709     try:
1710         _test_ap_wps_er_subscribe_oom(dev, apdev)
1711     finally:
1712         dev[0].request("WPS_ER_STOP")
1713
1714 def _test_ap_wps_er_subscribe_oom(dev, apdev):
1715     ssid = "wps-er-add-enrollee"
1716     ap_pin = "12345670"
1717     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1718     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1719                "wpa_passphrase": "12345678", "wpa": "2",
1720                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1721                "device_name": "Wireless AP", "manufacturer": "Company",
1722                "model_name": "WAP", "model_number": "123",
1723                "serial_number": "12345", "device_type": "6-0050F204-1",
1724                "os_version": "01020300",
1725                "config_methods": "label push_button",
1726                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1727     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1728     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1729     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1730     id = int(dev[0].list_networks()[0]['id'])
1731     dev[0].set_network(id, "scan_freq", "2412")
1732
1733     with alloc_fail(dev[0], 1, "http_client_addr;wps_er_subscribe"):
1734         dev[0].request("WPS_ER_START ifname=lo")
1735         for i in range(50):
1736             res = dev[0].request("GET_ALLOC_FAIL")
1737             if res.startswith("0:"):
1738                 break
1739             time.sleep(0.1)
1740         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=0)
1741         if ev:
1742             raise Exception("Unexpected AP discovery during OOM")
1743
1744     dev[0].request("WPS_ER_STOP")
1745
1746 def test_ap_wps_fragmentation(dev, apdev):
1747     """WPS with fragmentation in EAP-WSC and mixed mode WPA+WPA2"""
1748     ssid = "test-wps-fragmentation"
1749     appin = "12345670"
1750     hostapd.add_ap(apdev[0]['ifname'],
1751                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1752                      "wpa_passphrase": "12345678", "wpa": "3",
1753                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1754                      "wpa_pairwise": "TKIP", "ap_pin": appin,
1755                      "fragment_size": "50" })
1756     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1757     logger.info("WPS provisioning step (PBC)")
1758     hapd.request("WPS_PBC")
1759     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1760     dev[0].dump_monitor()
1761     dev[0].request("SET wps_fragment_size 50")
1762     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1763     dev[0].wait_connected(timeout=30)
1764     status = dev[0].get_status()
1765     if status['wpa_state'] != 'COMPLETED':
1766         raise Exception("Not fully connected")
1767     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1768         raise Exception("Unexpected encryption configuration")
1769     if status['key_mgmt'] != 'WPA2-PSK':
1770         raise Exception("Unexpected key_mgmt")
1771
1772     logger.info("WPS provisioning step (PIN)")
1773     pin = dev[1].wps_read_pin()
1774     hapd.request("WPS_PIN any " + pin)
1775     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1776     dev[1].request("SET wps_fragment_size 50")
1777     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1778     dev[1].wait_connected(timeout=30)
1779     status = dev[1].get_status()
1780     if status['wpa_state'] != 'COMPLETED':
1781         raise Exception("Not fully connected")
1782     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1783         raise Exception("Unexpected encryption configuration")
1784     if status['key_mgmt'] != 'WPA2-PSK':
1785         raise Exception("Unexpected key_mgmt")
1786
1787     logger.info("WPS connection as registrar")
1788     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1789     dev[2].request("SET wps_fragment_size 50")
1790     dev[2].wps_reg(apdev[0]['bssid'], appin)
1791     status = dev[2].get_status()
1792     if status['wpa_state'] != 'COMPLETED':
1793         raise Exception("Not fully connected")
1794     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1795         raise Exception("Unexpected encryption configuration")
1796     if status['key_mgmt'] != 'WPA2-PSK':
1797         raise Exception("Unexpected key_mgmt")
1798
1799 def test_ap_wps_new_version_sta(dev, apdev):
1800     """WPS compatibility with new version number on the station"""
1801     ssid = "test-wps-ver"
1802     hostapd.add_ap(apdev[0]['ifname'],
1803                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1804                      "wpa_passphrase": "12345678", "wpa": "2",
1805                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1806     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1807     logger.info("WPS provisioning step")
1808     hapd.request("WPS_PBC")
1809     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1810     dev[0].dump_monitor()
1811     dev[0].request("SET wps_version_number 0x43")
1812     dev[0].request("SET wps_vendor_ext_m1 000137100100020001")
1813     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1814     dev[0].wait_connected(timeout=30)
1815
1816 def test_ap_wps_new_version_ap(dev, apdev):
1817     """WPS compatibility with new version number on the AP"""
1818     ssid = "test-wps-ver"
1819     hostapd.add_ap(apdev[0]['ifname'],
1820                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1821                      "wpa_passphrase": "12345678", "wpa": "2",
1822                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1823     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1824     logger.info("WPS provisioning step")
1825     if "FAIL" in hapd.request("SET wps_version_number 0x43"):
1826         raise Exception("Failed to enable test functionality")
1827     hapd.request("WPS_PBC")
1828     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1829     dev[0].dump_monitor()
1830     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1831     dev[0].wait_connected(timeout=30)
1832     hapd.request("SET wps_version_number 0x20")
1833
1834 def test_ap_wps_check_pin(dev, apdev):
1835     """Verify PIN checking through control interface"""
1836     hostapd.add_ap(apdev[0]['ifname'],
1837                    { "ssid": "wps", "eap_server": "1", "wps_state": "2",
1838                      "wpa_passphrase": "12345678", "wpa": "2",
1839                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1840     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1841     for t in [ ("12345670", "12345670"),
1842                ("12345678", "FAIL-CHECKSUM"),
1843                ("12345", "FAIL"),
1844                ("123456789", "FAIL"),
1845                ("1234-5670", "12345670"),
1846                ("1234 5670", "12345670"),
1847                ("1-2.3:4 5670", "12345670") ]:
1848         res = hapd.request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1849         res2 = dev[0].request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1850         if res != res2:
1851             raise Exception("Unexpected difference in WPS_CHECK_PIN responses")
1852         if res != t[1]:
1853             raise Exception("Incorrect WPS_CHECK_PIN response {} (expected {})".format(res, t[1]))
1854
1855     if "FAIL" not in hapd.request("WPS_CHECK_PIN 12345"):
1856         raise Exception("Unexpected WPS_CHECK_PIN success")
1857     if "FAIL" not in hapd.request("WPS_CHECK_PIN 123456789"):
1858         raise Exception("Unexpected WPS_CHECK_PIN success")
1859
1860     for i in range(0, 10):
1861         pin = dev[0].request("WPS_PIN get")
1862         rpin = dev[0].request("WPS_CHECK_PIN " + pin).rstrip('\n')
1863         if pin != rpin:
1864             raise Exception("Random PIN validation failed for " + pin)
1865
1866 def test_ap_wps_wep_config(dev, apdev):
1867     """WPS 2.0 AP rejecting WEP configuration"""
1868     ssid = "test-wps-config"
1869     appin = "12345670"
1870     hostapd.add_ap(apdev[0]['ifname'],
1871                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1872                      "ap_pin": appin})
1873     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1874     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1875     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
1876                    "hello", no_wait=True)
1877     ev = hapd.wait_event(["WPS-FAIL"], timeout=15)
1878     if ev is None:
1879         raise Exception("WPS-FAIL timed out")
1880     if "reason=2" not in ev:
1881         raise Exception("Unexpected reason code in WPS-FAIL")
1882     status = hapd.request("WPS_GET_STATUS")
1883     if "Last WPS result: Failed" not in status:
1884         raise Exception("WPS failure result not shown correctly")
1885     if "Failure Reason: WEP Prohibited" not in status:
1886         raise Exception("Failure reason not reported correctly")
1887     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
1888         raise Exception("Peer address not shown correctly")
1889
1890 def test_ap_wps_wep_enroll(dev, apdev):
1891     """WPS 2.0 STA rejecting WEP configuration"""
1892     ssid = "test-wps-wep"
1893     hostapd.add_ap(apdev[0]['ifname'],
1894                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1895                      "skip_cred_build": "1", "extra_cred": "wps-wep-cred" })
1896     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1897     hapd.request("WPS_PBC")
1898     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1899     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1900     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1901     if ev is None:
1902         raise Exception("WPS-FAIL event timed out")
1903     if "msg=12" not in ev or "reason=2 (WEP Prohibited)" not in ev:
1904         raise Exception("Unexpected WPS-FAIL event: " + ev)
1905
1906 def test_ap_wps_ie_fragmentation(dev, apdev):
1907     """WPS AP using fragmented WPS IE"""
1908     ssid = "test-wps-ie-fragmentation"
1909     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1910                "wpa_passphrase": "12345678", "wpa": "2",
1911                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1912                "device_name": "1234567890abcdef1234567890abcdef",
1913                "manufacturer": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
1914                "model_name": "1234567890abcdef1234567890abcdef",
1915                "model_number": "1234567890abcdef1234567890abcdef",
1916                "serial_number": "1234567890abcdef1234567890abcdef" }
1917     hostapd.add_ap(apdev[0]['ifname'], params)
1918     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1919     hapd.request("WPS_PBC")
1920     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1921     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1922     dev[0].wait_connected(timeout=30)
1923     bss = dev[0].get_bss(apdev[0]['bssid'])
1924     if "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1925         logger.info("Device Name not received correctly")
1926         logger.info(bss)
1927         # This can fail if Probe Response frame is missed and Beacon frame was
1928         # used to fill in the BSS entry. This can happen, e.g., during heavy
1929         # load every now and then and is not really an error, so try to
1930         # workaround by runnign another scan.
1931         dev[0].scan(freq="2412", only_new=True)
1932         bss = dev[0].get_bss(apdev[0]['bssid'])
1933         if not bss or "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1934             logger.info(bss)
1935             raise Exception("Device Name not received correctly")
1936     if len(re.findall("dd..0050f204", bss['ie'])) != 2:
1937         raise Exception("Unexpected number of WPS IEs")
1938
1939 def get_psk(pskfile):
1940     psks = {}
1941     with open(pskfile, "r") as f:
1942         lines = f.read().splitlines()
1943         for l in lines:
1944             if l == "# WPA PSKs":
1945                 continue
1946             (addr,psk) = l.split(' ')
1947             psks[addr] = psk
1948     return psks
1949
1950 def test_ap_wps_per_station_psk(dev, apdev):
1951     """WPS PBC provisioning with per-station PSK"""
1952     addr0 = dev[0].own_addr()
1953     addr1 = dev[1].own_addr()
1954     addr2 = dev[2].own_addr()
1955     ssid = "wps"
1956     appin = "12345670"
1957     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1958     try:
1959         os.remove(pskfile)
1960     except:
1961         pass
1962
1963     try:
1964         with open(pskfile, "w") as f:
1965             f.write("# WPA PSKs\n")
1966
1967         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1968                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1969                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1970                    "wpa_psk_file": pskfile }
1971         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1972
1973         logger.info("First enrollee")
1974         hapd.request("WPS_PBC")
1975         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1976         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1977         dev[0].wait_connected(timeout=30)
1978
1979         logger.info("Second enrollee")
1980         hapd.request("WPS_PBC")
1981         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1982         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1983         dev[1].wait_connected(timeout=30)
1984
1985         logger.info("External registrar")
1986         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1987         dev[2].wps_reg(apdev[0]['bssid'], appin)
1988
1989         logger.info("Verifying PSK results")
1990         psks = get_psk(pskfile)
1991         if addr0 not in psks:
1992             raise Exception("No PSK recorded for sta0")
1993         if addr1 not in psks:
1994             raise Exception("No PSK recorded for sta1")
1995         if addr2 not in psks:
1996             raise Exception("No PSK recorded for sta2")
1997         if psks[addr0] == psks[addr1]:
1998             raise Exception("Same PSK recorded for sta0 and sta1")
1999         if psks[addr0] == psks[addr2]:
2000             raise Exception("Same PSK recorded for sta0 and sta2")
2001         if psks[addr1] == psks[addr2]:
2002             raise Exception("Same PSK recorded for sta1 and sta2")
2003
2004         dev[0].request("REMOVE_NETWORK all")
2005         logger.info("Second external registrar")
2006         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2007         dev[0].wps_reg(apdev[0]['bssid'], appin)
2008         psks2 = get_psk(pskfile)
2009         if addr0 not in psks2:
2010             raise Exception("No PSK recorded for sta0(reg)")
2011         if psks[addr0] == psks2[addr0]:
2012             raise Exception("Same PSK recorded for sta0(enrollee) and sta0(reg)")
2013     finally:
2014         os.remove(pskfile)
2015
2016 def test_ap_wps_per_station_psk_failure(dev, apdev):
2017     """WPS PBC provisioning with per-station PSK (file not writable)"""
2018     addr0 = dev[0].p2p_dev_addr()
2019     addr1 = dev[1].p2p_dev_addr()
2020     addr2 = dev[2].p2p_dev_addr()
2021     ssid = "wps"
2022     appin = "12345670"
2023     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
2024     try:
2025         os.remove(pskfile)
2026     except:
2027         pass
2028
2029     try:
2030         with open(pskfile, "w") as f:
2031             f.write("# WPA PSKs\n")
2032
2033         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2034                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
2035                    "rsn_pairwise": "CCMP", "ap_pin": appin,
2036                    "wpa_psk_file": pskfile }
2037         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2038         if "FAIL" in hapd.request("SET wpa_psk_file /tmp/does/not/exists/ap_wps_per_enrollee_psk_failure.psk_file"):
2039             raise Exception("Failed to set wpa_psk_file")
2040
2041         logger.info("First enrollee")
2042         hapd.request("WPS_PBC")
2043         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2044         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2045         dev[0].wait_connected(timeout=30)
2046
2047         logger.info("Second enrollee")
2048         hapd.request("WPS_PBC")
2049         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2050         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2051         dev[1].wait_connected(timeout=30)
2052
2053         logger.info("External registrar")
2054         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2055         dev[2].wps_reg(apdev[0]['bssid'], appin)
2056
2057         logger.info("Verifying PSK results")
2058         psks = get_psk(pskfile)
2059         if len(psks) > 0:
2060             raise Exception("PSK recorded unexpectedly")
2061     finally:
2062         os.remove(pskfile)
2063
2064 def test_ap_wps_pin_request_file(dev, apdev):
2065     """WPS PIN provisioning with configured AP"""
2066     ssid = "wps"
2067     pinfile = "/tmp/ap_wps_pin_request_file.log"
2068     if os.path.exists(pinfile):
2069         os.remove(pinfile)
2070     hostapd.add_ap(apdev[0]['ifname'],
2071                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2072                      "wps_pin_requests": pinfile,
2073                      "wpa_passphrase": "12345678", "wpa": "2",
2074                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2075     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2076     uuid = dev[0].get_status_field("uuid")
2077     pin = dev[0].wps_read_pin()
2078     try:
2079         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2080         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
2081         ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=15)
2082         if ev is None:
2083             raise Exception("PIN needed event not shown")
2084         if uuid not in ev:
2085             raise Exception("UUID mismatch")
2086         dev[0].request("WPS_CANCEL")
2087         success = False
2088         with open(pinfile, "r") as f:
2089             lines = f.readlines()
2090             for l in lines:
2091                 if uuid in l:
2092                     success = True
2093                     break
2094         if not success:
2095             raise Exception("PIN request entry not in the log file")
2096     finally:
2097         try:
2098             os.remove(pinfile)
2099         except:
2100             pass
2101
2102 def test_ap_wps_auto_setup_with_config_file(dev, apdev):
2103     """WPS auto-setup with configuration file"""
2104     conffile = "/tmp/ap_wps_auto_setup_with_config_file.conf"
2105     ifname = apdev[0]['ifname']
2106     try:
2107         with open(conffile, "w") as f:
2108             f.write("driver=nl80211\n")
2109             f.write("hw_mode=g\n")
2110             f.write("channel=1\n")
2111             f.write("ieee80211n=1\n")
2112             f.write("interface=%s\n" % ifname)
2113             f.write("ctrl_interface=/var/run/hostapd\n")
2114             f.write("ssid=wps\n")
2115             f.write("eap_server=1\n")
2116             f.write("wps_state=1\n")
2117         hostapd.add_bss('phy3', ifname, conffile)
2118         hapd = hostapd.Hostapd(ifname)
2119         hapd.request("WPS_PBC")
2120         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2121         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2122         dev[0].wait_connected(timeout=30)
2123         with open(conffile, "r") as f:
2124             lines = f.read().splitlines()
2125             vals = dict()
2126             for l in lines:
2127                 try:
2128                     [name,value] = l.split('=', 1)
2129                     vals[name] = value
2130                 except ValueError, e:
2131                     if "# WPS configuration" in l:
2132                         pass
2133                     else:
2134                         raise Exception("Unexpected configuration line: " + l)
2135         if vals['ieee80211n'] != '1' or vals['wps_state'] != '2' or "WPA-PSK" not in vals['wpa_key_mgmt']:
2136             raise Exception("Incorrect configuration: " + str(vals))
2137     finally:
2138         try:
2139             os.remove(conffile)
2140         except:
2141             pass
2142
2143 def test_ap_wps_pbc_timeout(dev, apdev, params):
2144     """wpa_supplicant PBC walk time and WPS ER SelReg timeout [long]"""
2145     if not params['long']:
2146         raise HwsimSkip("Skip test case with long duration due to --long not specified")
2147     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2148     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2149
2150     location = ssdp_get_location(ap_uuid)
2151     urls = upnp_get_urls(location)
2152     eventurl = urlparse.urlparse(urls['event_sub_url'])
2153     ctrlurl = urlparse.urlparse(urls['control_url'])
2154
2155     url = urlparse.urlparse(location)
2156     conn = httplib.HTTPConnection(url.netloc)
2157
2158     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
2159         def handle(self):
2160             data = self.rfile.readline().strip()
2161             logger.debug(data)
2162             self.wfile.write(gen_wps_event())
2163
2164     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
2165     server.timeout = 1
2166
2167     headers = { "callback": '<http://127.0.0.1:12345/event>',
2168                 "NT": "upnp:event",
2169                 "timeout": "Second-1234" }
2170     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2171     resp = conn.getresponse()
2172     if resp.status != 200:
2173         raise Exception("Unexpected HTTP response: %d" % resp.status)
2174     sid = resp.getheader("sid")
2175     logger.debug("Subscription SID " + sid)
2176
2177     msg = '''<?xml version="1.0"?>
2178 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
2179 <s:Body>
2180 <u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
2181 <NewMessage>EEoAARAQQQABARASAAIAABBTAAIxSBBJAA4ANyoAASABBv///////xBIABA2LbR7pTpRkYj7
2182 VFi5hrLk
2183 </NewMessage>
2184 </u:SetSelectedRegistrar>
2185 </s:Body>
2186 </s:Envelope>'''
2187     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2188     headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
2189     conn.request("POST", ctrlurl.path, msg, headers)
2190     resp = conn.getresponse()
2191     if resp.status != 200:
2192         raise Exception("Unexpected HTTP response: %d" % resp.status)
2193
2194     server.handle_request()
2195
2196     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
2197     if "OK" not in dev[0].request("WPS_PBC"):
2198         raise Exception("WPS_PBC failed")
2199
2200     start = os.times()[4]
2201
2202     server.handle_request()
2203     dev[1].request("BSS_FLUSH 0")
2204     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2205                         only_new=True)
2206     bss = dev[1].get_bss(apdev[0]['bssid'])
2207     logger.debug("BSS: " + str(bss))
2208     if '[WPS-AUTH]' not in bss['flags']:
2209         raise Exception("WPS not indicated authorized")
2210
2211     server.handle_request()
2212
2213     wps_timeout_seen = False
2214
2215     while True:
2216         hapd.dump_monitor()
2217         dev[1].dump_monitor()
2218         if not wps_timeout_seen:
2219             ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=0)
2220             if ev is not None:
2221                 logger.info("PBC timeout seen")
2222                 wps_timeout_seen = True
2223         else:
2224             dev[0].dump_monitor()
2225         now = os.times()[4]
2226         if now - start > 130:
2227             raise Exception("Selected registration information not removed")
2228         dev[1].request("BSS_FLUSH 0")
2229         dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2230                             only_new=True)
2231         bss = dev[1].get_bss(apdev[0]['bssid'])
2232         logger.debug("BSS: " + str(bss))
2233         if '[WPS-AUTH]' not in bss['flags']:
2234             break
2235         server.handle_request()
2236
2237     server.server_close()
2238
2239     if wps_timeout_seen:
2240         return
2241
2242     now = os.times()[4]
2243     if now < start + 150:
2244         dur = start + 150 - now
2245     else:
2246         dur = 1
2247     logger.info("Continue waiting for PBC timeout (%d sec)" % dur)
2248     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=dur)
2249     if ev is None:
2250         raise Exception("WPS-TIMEOUT not reported")
2251
2252 def add_ssdp_ap(ifname, ap_uuid):
2253     ssid = "wps-ssdp"
2254     ap_pin = "12345670"
2255     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2256                "wpa_passphrase": "12345678", "wpa": "2",
2257                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2258                "device_name": "Wireless AP", "manufacturer": "Company",
2259                "model_name": "WAP", "model_number": "123",
2260                "serial_number": "12345", "device_type": "6-0050F204-1",
2261                "os_version": "01020300",
2262                "config_methods": "label push_button",
2263                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
2264                "friendly_name": "WPS Access Point",
2265                "manufacturer_url": "http://www.example.com/",
2266                "model_description": "Wireless Access Point",
2267                "model_url": "http://www.example.com/model/",
2268                "upc": "123456789012" }
2269     return hostapd.add_ap(ifname, params)
2270
2271 def ssdp_send(msg, no_recv=False):
2272     socket.setdefaulttimeout(1)
2273     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2274     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2275     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2276     sock.bind(("127.0.0.1", 0))
2277     sock.sendto(msg, ("239.255.255.250", 1900))
2278     if no_recv:
2279         return None
2280     return sock.recv(1000)
2281
2282 def ssdp_send_msearch(st, no_recv=False):
2283     msg = '\r\n'.join([
2284             'M-SEARCH * HTTP/1.1',
2285             'HOST: 239.255.255.250:1900',
2286             'MX: 1',
2287             'MAN: "ssdp:discover"',
2288             'ST: ' + st,
2289             '', ''])
2290     return ssdp_send(msg, no_recv=no_recv)
2291
2292 def test_ap_wps_ssdp_msearch(dev, apdev):
2293     """WPS AP and SSDP M-SEARCH messages"""
2294     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2295     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2296
2297     msg = '\r\n'.join([
2298             'M-SEARCH * HTTP/1.1',
2299             'Host: 239.255.255.250:1900',
2300             'Mx: 1',
2301             'Man: "ssdp:discover"',
2302             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
2303             '', ''])
2304     ssdp_send(msg)
2305
2306     msg = '\r\n'.join([
2307             'M-SEARCH * HTTP/1.1',
2308             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
2309             'mx: \t1\t\t   ',
2310             'man: \t \t "ssdp:discover"   ',
2311             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
2312             '', ''])
2313     ssdp_send(msg)
2314
2315     ssdp_send_msearch("ssdp:all")
2316     ssdp_send_msearch("upnp:rootdevice")
2317     ssdp_send_msearch("uuid:" + ap_uuid)
2318     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
2319     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1");
2320
2321     msg = '\r\n'.join([
2322             'M-SEARCH * HTTP/1.1',
2323             'HOST:\t239.255.255.250:1900',
2324             'MAN: "ssdp:discover"',
2325             'MX: 130',
2326             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2327             '', ''])
2328     ssdp_send(msg, no_recv=True)
2329
2330 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
2331     """WPS AP and invalid SSDP M-SEARCH messages"""
2332     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2333     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2334
2335     socket.setdefaulttimeout(1)
2336     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2337     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2338     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2339     sock.bind(("127.0.0.1", 0))
2340
2341     logger.debug("Missing MX")
2342     msg = '\r\n'.join([
2343             'M-SEARCH * HTTP/1.1',
2344             'HOST: 239.255.255.250:1900',
2345             'MAN: "ssdp:discover"',
2346             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2347             '', ''])
2348     sock.sendto(msg, ("239.255.255.250", 1900))
2349
2350     logger.debug("Negative MX")
2351     msg = '\r\n'.join([
2352             'M-SEARCH * HTTP/1.1',
2353             'HOST: 239.255.255.250:1900',
2354             'MX: -1',
2355             'MAN: "ssdp:discover"',
2356             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2357             '', ''])
2358     sock.sendto(msg, ("239.255.255.250", 1900))
2359
2360     logger.debug("Invalid MX")
2361     msg = '\r\n'.join([
2362             'M-SEARCH * HTTP/1.1',
2363             'HOST: 239.255.255.250:1900',
2364             'MX; 1',
2365             'MAN: "ssdp:discover"',
2366             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2367             '', ''])
2368     sock.sendto(msg, ("239.255.255.250", 1900))
2369
2370     logger.debug("Missing MAN")
2371     msg = '\r\n'.join([
2372             'M-SEARCH * HTTP/1.1',
2373             'HOST: 239.255.255.250:1900',
2374             'MX: 1',
2375             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2376             '', ''])
2377     sock.sendto(msg, ("239.255.255.250", 1900))
2378
2379     logger.debug("Invalid MAN")
2380     msg = '\r\n'.join([
2381             'M-SEARCH * HTTP/1.1',
2382             'HOST: 239.255.255.250:1900',
2383             'MX: 1',
2384             'MAN: foo',
2385             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2386             '', ''])
2387     sock.sendto(msg, ("239.255.255.250", 1900))
2388     msg = '\r\n'.join([
2389             'M-SEARCH * HTTP/1.1',
2390             'HOST: 239.255.255.250:1900',
2391             'MX: 1',
2392             'MAN; "ssdp:discover"',
2393             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2394             '', ''])
2395     sock.sendto(msg, ("239.255.255.250", 1900))
2396
2397     logger.debug("Missing HOST")
2398     msg = '\r\n'.join([
2399             'M-SEARCH * HTTP/1.1',
2400             'MAN: "ssdp:discover"',
2401             'MX: 1',
2402             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2403             '', ''])
2404     sock.sendto(msg, ("239.255.255.250", 1900))
2405
2406     logger.debug("Missing ST")
2407     msg = '\r\n'.join([
2408             'M-SEARCH * HTTP/1.1',
2409             'HOST: 239.255.255.250:1900',
2410             'MAN: "ssdp:discover"',
2411             'MX: 1',
2412             '', ''])
2413     sock.sendto(msg, ("239.255.255.250", 1900))
2414
2415     logger.debug("Mismatching ST")
2416     msg = '\r\n'.join([
2417             'M-SEARCH * HTTP/1.1',
2418             'HOST: 239.255.255.250:1900',
2419             'MAN: "ssdp:discover"',
2420             'MX: 1',
2421             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
2422             '', ''])
2423     sock.sendto(msg, ("239.255.255.250", 1900))
2424     msg = '\r\n'.join([
2425             'M-SEARCH * HTTP/1.1',
2426             'HOST: 239.255.255.250:1900',
2427             'MAN: "ssdp:discover"',
2428             'MX: 1',
2429             'ST: foo:bar',
2430             '', ''])
2431     sock.sendto(msg, ("239.255.255.250", 1900))
2432     msg = '\r\n'.join([
2433             'M-SEARCH * HTTP/1.1',
2434             'HOST: 239.255.255.250:1900',
2435             'MAN: "ssdp:discover"',
2436             'MX: 1',
2437             'ST: foobar',
2438             '', ''])
2439     sock.sendto(msg, ("239.255.255.250", 1900))
2440
2441     logger.debug("Invalid ST")
2442     msg = '\r\n'.join([
2443             'M-SEARCH * HTTP/1.1',
2444             'HOST: 239.255.255.250:1900',
2445             'MAN: "ssdp:discover"',
2446             'MX: 1',
2447             'ST; urn:schemas-wifialliance-org:device:WFADevice:1',
2448             '', ''])
2449     sock.sendto(msg, ("239.255.255.250", 1900))
2450
2451     logger.debug("Invalid M-SEARCH")
2452     msg = '\r\n'.join([
2453             'M+SEARCH * HTTP/1.1',
2454             'HOST: 239.255.255.250:1900',
2455             'MAN: "ssdp:discover"',
2456             'MX: 1',
2457             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2458             '', ''])
2459     sock.sendto(msg, ("239.255.255.250", 1900))
2460     msg = '\r\n'.join([
2461             'M-SEARCH-* HTTP/1.1',
2462             'HOST: 239.255.255.250:1900',
2463             'MAN: "ssdp:discover"',
2464             'MX: 1',
2465             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2466             '', ''])
2467     sock.sendto(msg, ("239.255.255.250", 1900))
2468
2469     logger.debug("Invalid message format")
2470     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
2471     msg = '\r'.join([
2472             'M-SEARCH * HTTP/1.1',
2473             'HOST: 239.255.255.250:1900',
2474             'MAN: "ssdp:discover"',
2475             'MX: 1',
2476             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2477             '', ''])
2478     sock.sendto(msg, ("239.255.255.250", 1900))
2479
2480     try:
2481         r = sock.recv(1000)
2482         raise Exception("Unexpected M-SEARCH response: " + r)
2483     except socket.timeout:
2484         pass
2485
2486     logger.debug("Valid M-SEARCH")
2487     msg = '\r\n'.join([
2488             'M-SEARCH * HTTP/1.1',
2489             'HOST: 239.255.255.250:1900',
2490             'MAN: "ssdp:discover"',
2491             'MX: 1',
2492             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2493             '', ''])
2494     sock.sendto(msg, ("239.255.255.250", 1900))
2495
2496     try:
2497         r = sock.recv(1000)
2498         pass
2499     except socket.timeout:
2500         raise Exception("No SSDP response")
2501
2502 def test_ap_wps_ssdp_burst(dev, apdev):
2503     """WPS AP and SSDP burst"""
2504     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2505     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2506
2507     msg = '\r\n'.join([
2508             'M-SEARCH * HTTP/1.1',
2509             'HOST: 239.255.255.250:1900',
2510             'MAN: "ssdp:discover"',
2511             'MX: 1',
2512             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2513             '', ''])
2514     socket.setdefaulttimeout(1)
2515     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2516     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2517     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2518     sock.bind(("127.0.0.1", 0))
2519     for i in range(0, 25):
2520         sock.sendto(msg, ("239.255.255.250", 1900))
2521     resp = 0
2522     while True:
2523         try:
2524             r = sock.recv(1000)
2525             if not r.startswith("HTTP/1.1 200 OK\r\n"):
2526                 raise Exception("Unexpected message: " + r)
2527             resp += 1
2528         except socket.timeout:
2529             break
2530     if resp < 20:
2531         raise Exception("Too few SSDP responses")
2532
2533     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2534     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2535     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2536     sock.bind(("127.0.0.1", 0))
2537     for i in range(0, 25):
2538         sock.sendto(msg, ("239.255.255.250", 1900))
2539     while True:
2540         try:
2541             r = sock.recv(1000)
2542             if ap_uuid in r:
2543                 break
2544         except socket.timeout:
2545             raise Exception("No SSDP response")
2546
2547 def ssdp_get_location(uuid):
2548     res = ssdp_send_msearch("uuid:" + uuid)
2549     location = None
2550     for l in res.splitlines():
2551         if l.lower().startswith("location:"):
2552             location = l.split(':', 1)[1].strip()
2553             break
2554     if location is None:
2555         raise Exception("No UPnP location found")
2556     return location
2557
2558 def upnp_get_urls(location):
2559     conn = urllib.urlopen(location)
2560     tree = ET.parse(conn)
2561     root = tree.getroot()
2562     urn = '{urn:schemas-upnp-org:device-1-0}'
2563     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
2564     res = {}
2565     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
2566     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
2567     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
2568     return res
2569
2570 def upnp_soap_action(conn, path, action, include_soap_action=True, soap_action_override=None):
2571     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
2572     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
2573     ET.register_namespace('soapenv', soapns)
2574     ET.register_namespace('wfa', wpsns)
2575     attrib = {}
2576     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
2577     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
2578     body = ET.SubElement(root, "{%s}Body" % soapns)
2579     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
2580     tree = ET.ElementTree(root)
2581     soap = StringIO.StringIO()
2582     tree.write(soap, xml_declaration=True, encoding='utf-8')
2583
2584     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2585     if include_soap_action:
2586         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
2587     elif soap_action_override:
2588         headers["SOAPAction"] = soap_action_override
2589     conn.request("POST", path, soap.getvalue(), headers)
2590     return conn.getresponse()
2591
2592 def test_ap_wps_upnp(dev, apdev):
2593     """WPS AP and UPnP operations"""
2594     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2595     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2596
2597     location = ssdp_get_location(ap_uuid)
2598     urls = upnp_get_urls(location)
2599
2600     conn = urllib.urlopen(urls['scpd_url'])
2601     scpd = conn.read()
2602
2603     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"))
2604     if conn.getcode() != 404:
2605         raise Exception("Unexpected HTTP response to GET unknown URL")
2606
2607     url = urlparse.urlparse(location)
2608     conn = httplib.HTTPConnection(url.netloc)
2609     #conn.set_debuglevel(1)
2610     headers = { "Content-type": 'text/xml; charset="utf-8"',
2611                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
2612     conn.request("POST", "hello", "\r\n\r\n", headers)
2613     resp = conn.getresponse()
2614     if resp.status != 404:
2615         raise Exception("Unexpected HTTP response: %d" % resp.status)
2616
2617     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
2618     resp = conn.getresponse()
2619     if resp.status != 501:
2620         raise Exception("Unexpected HTTP response: %d" % resp.status)
2621
2622     headers = { "Content-type": 'text/xml; charset="utf-8"',
2623                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
2624     ctrlurl = urlparse.urlparse(urls['control_url'])
2625     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
2626     resp = conn.getresponse()
2627     if resp.status != 401:
2628         raise Exception("Unexpected HTTP response: %d" % resp.status)
2629
2630     logger.debug("GetDeviceInfo without SOAPAction header")
2631     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2632                             include_soap_action=False)
2633     if resp.status != 401:
2634         raise Exception("Unexpected HTTP response: %d" % resp.status)
2635
2636     logger.debug("GetDeviceInfo with invalid SOAPAction header")
2637     for act in [ "foo",
2638                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
2639                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
2640                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
2641         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2642                                 include_soap_action=False,
2643                                 soap_action_override=act)
2644         if resp.status != 401:
2645             raise Exception("Unexpected HTTP response: %d" % resp.status)
2646
2647     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
2648     if resp.status != 200:
2649         raise Exception("Unexpected HTTP response: %d" % resp.status)
2650     dev = resp.read()
2651     if "NewDeviceInfo" not in dev:
2652         raise Exception("Unexpected GetDeviceInfo response")
2653
2654     logger.debug("PutMessage without required parameters")
2655     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
2656     if resp.status != 600:
2657         raise Exception("Unexpected HTTP response: %d" % resp.status)
2658
2659     logger.debug("PutWLANResponse without required parameters")
2660     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
2661     if resp.status != 600:
2662         raise Exception("Unexpected HTTP response: %d" % resp.status)
2663
2664     logger.debug("SetSelectedRegistrar from unregistered ER")
2665     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
2666     if resp.status != 501:
2667         raise Exception("Unexpected HTTP response: %d" % resp.status)
2668
2669     logger.debug("Unknown action")
2670     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
2671     if resp.status != 401:
2672         raise Exception("Unexpected HTTP response: %d" % resp.status)
2673
2674 def test_ap_wps_upnp_subscribe(dev, apdev):
2675     """WPS AP and UPnP event subscription"""
2676     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2677     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2678
2679     location = ssdp_get_location(ap_uuid)
2680     urls = upnp_get_urls(location)
2681     eventurl = urlparse.urlparse(urls['event_sub_url'])
2682
2683     url = urlparse.urlparse(location)
2684     conn = httplib.HTTPConnection(url.netloc)
2685     #conn.set_debuglevel(1)
2686     headers = { "callback": '<http://127.0.0.1:12345/event>',
2687                 "timeout": "Second-1234" }
2688     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
2689     resp = conn.getresponse()
2690     if resp.status != 412:
2691         raise Exception("Unexpected HTTP response: %d" % resp.status)
2692
2693     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2694     resp = conn.getresponse()
2695     if resp.status != 412:
2696         raise Exception("Unexpected HTTP response: %d" % resp.status)
2697
2698     headers = { "NT": "upnp:event",
2699                 "timeout": "Second-1234" }
2700     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2701     resp = conn.getresponse()
2702     if resp.status != 412:
2703         raise Exception("Unexpected HTTP response: %d" % resp.status)
2704
2705     headers = { "callback": '<http://127.0.0.1:12345/event>',
2706                 "NT": "upnp:foobar",
2707                 "timeout": "Second-1234" }
2708     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2709     resp = conn.getresponse()
2710     if resp.status != 400:
2711         raise Exception("Unexpected HTTP response: %d" % resp.status)
2712
2713     logger.debug("Valid subscription")
2714     headers = { "callback": '<http://127.0.0.1:12345/event>',
2715                 "NT": "upnp:event",
2716                 "timeout": "Second-1234" }
2717     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2718     resp = conn.getresponse()
2719     if resp.status != 200:
2720         raise Exception("Unexpected HTTP response: %d" % resp.status)
2721     sid = resp.getheader("sid")
2722     logger.debug("Subscription SID " + sid)
2723
2724     logger.debug("Invalid re-subscription")
2725     headers = { "NT": "upnp:event",
2726                 "sid": "123456734567854",
2727                 "timeout": "Second-1234" }
2728     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2729     resp = conn.getresponse()
2730     if resp.status != 400:
2731         raise Exception("Unexpected HTTP response: %d" % resp.status)
2732
2733     logger.debug("Invalid re-subscription")
2734     headers = { "NT": "upnp:event",
2735                 "sid": "uuid:123456734567854",
2736                 "timeout": "Second-1234" }
2737     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2738     resp = conn.getresponse()
2739     if resp.status != 400:
2740         raise Exception("Unexpected HTTP response: %d" % resp.status)
2741
2742     logger.debug("Invalid re-subscription")
2743     headers = { "callback": '<http://127.0.0.1:12345/event>',
2744                 "NT": "upnp:event",
2745                 "sid": sid,
2746                 "timeout": "Second-1234" }
2747     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2748     resp = conn.getresponse()
2749     if resp.status != 400:
2750         raise Exception("Unexpected HTTP response: %d" % resp.status)
2751
2752     logger.debug("SID mismatch in re-subscription")
2753     headers = { "NT": "upnp:event",
2754                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2755                 "timeout": "Second-1234" }
2756     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2757     resp = conn.getresponse()
2758     if resp.status != 412:
2759         raise Exception("Unexpected HTTP response: %d" % resp.status)
2760
2761     logger.debug("Valid re-subscription")
2762     headers = { "NT": "upnp:event",
2763                 "sid": sid,
2764                 "timeout": "Second-1234" }
2765     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2766     resp = conn.getresponse()
2767     if resp.status != 200:
2768         raise Exception("Unexpected HTTP response: %d" % resp.status)
2769     sid2 = resp.getheader("sid")
2770     logger.debug("Subscription SID " + sid2)
2771
2772     if sid != sid2:
2773         raise Exception("Unexpected SID change")
2774
2775     logger.debug("Valid re-subscription")
2776     headers = { "NT": "upnp:event",
2777                 "sid": "uuid: \t \t" + sid.split(':')[1],
2778                 "timeout": "Second-1234" }
2779     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2780     resp = conn.getresponse()
2781     if resp.status != 200:
2782         raise Exception("Unexpected HTTP response: %d" % resp.status)
2783
2784     logger.debug("Invalid unsubscription")
2785     headers = { "sid": sid }
2786     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2787     resp = conn.getresponse()
2788     if resp.status != 412:
2789         raise Exception("Unexpected HTTP response: %d" % resp.status)
2790     headers = { "foo": "bar" }
2791     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2792     resp = conn.getresponse()
2793     if resp.status != 412:
2794         raise Exception("Unexpected HTTP response: %d" % resp.status)
2795
2796     logger.debug("Valid unsubscription")
2797     headers = { "sid": sid }
2798     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2799     resp = conn.getresponse()
2800     if resp.status != 200:
2801         raise Exception("Unexpected HTTP response: %d" % resp.status)
2802
2803     logger.debug("Unsubscription for not existing SID")
2804     headers = { "sid": sid }
2805     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2806     resp = conn.getresponse()
2807     if resp.status != 412:
2808         raise Exception("Unexpected HTTP response: %d" % resp.status)
2809
2810     logger.debug("Invalid unsubscription")
2811     headers = { "sid": " \t \tfoo" }
2812     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2813     resp = conn.getresponse()
2814     if resp.status != 400:
2815         raise Exception("Unexpected HTTP response: %d" % resp.status)
2816
2817     logger.debug("Invalid unsubscription")
2818     headers = { "sid": "uuid:\t \tfoo" }
2819     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2820     resp = conn.getresponse()
2821     if resp.status != 400:
2822         raise Exception("Unexpected HTTP response: %d" % resp.status)
2823
2824     logger.debug("Invalid unsubscription")
2825     headers = { "NT": "upnp:event",
2826                 "sid": sid }
2827     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2828     resp = conn.getresponse()
2829     if resp.status != 400:
2830         raise Exception("Unexpected HTTP response: %d" % resp.status)
2831     headers = { "callback": '<http://127.0.0.1:12345/event>',
2832                 "sid": sid }
2833     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2834     resp = conn.getresponse()
2835     if resp.status != 400:
2836         raise Exception("Unexpected HTTP response: %d" % resp.status)
2837
2838     logger.debug("Valid subscription with multiple callbacks")
2839     headers = { "callback": '<http://127.0.0.1:12345/event> <http://127.0.0.1:12345/event>\t<http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event>',
2840                 "NT": "upnp:event",
2841                 "timeout": "Second-1234" }
2842     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2843     resp = conn.getresponse()
2844     if resp.status != 200:
2845         raise Exception("Unexpected HTTP response: %d" % resp.status)
2846     sid = resp.getheader("sid")
2847     logger.debug("Subscription SID " + sid)
2848
2849     # Force subscription to be deleted due to errors
2850     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2851     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2852     with alloc_fail(hapd, 1, "event_build_message"):
2853         for i in range(10):
2854             dev[1].dump_monitor()
2855             dev[2].dump_monitor()
2856             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2857             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2858             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2859             dev[1].request("WPS_CANCEL")
2860             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2861             dev[2].request("WPS_CANCEL")
2862             if i % 4 == 1:
2863                 time.sleep(1)
2864             else:
2865                 time.sleep(0.1)
2866     time.sleep(0.2)
2867
2868     headers = { "sid": sid }
2869     conn.request("UNSUBSCRIBE", eventurl.path, "", headers)
2870     resp = conn.getresponse()
2871     if resp.status != 200 and resp.status != 412:
2872         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2873
2874     headers = { "callback": '<http://127.0.0.1:12345/event>',
2875                 "NT": "upnp:event",
2876                 "timeout": "Second-1234" }
2877     with alloc_fail(hapd, 1, "http_client_addr;event_send_start"):
2878         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2879         resp = conn.getresponse()
2880         if resp.status != 200:
2881             raise Exception("Unexpected HTTP response for SUBSCRIBE: %d" % resp.status)
2882         sid = resp.getheader("sid")
2883         logger.debug("Subscription SID " + sid)
2884
2885     headers = { "sid": sid }
2886     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2887     resp = conn.getresponse()
2888     if resp.status != 200:
2889         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2890
2891     headers = { "callback": '<http://127.0.0.1:12345/event>',
2892                 "NT": "upnp:event",
2893                 "timeout": "Second-1234" }
2894     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2895     resp = conn.getresponse()
2896     if resp.status != 200:
2897         raise Exception("Unexpected HTTP response: %d" % resp.status)
2898     sid = resp.getheader("sid")
2899     logger.debug("Subscription SID " + sid)
2900
2901     with alloc_fail(hapd, 1, "=event_add"):
2902         for i in range(2):
2903             dev[1].dump_monitor()
2904             dev[2].dump_monitor()
2905             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2906             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2907             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2908             dev[1].request("WPS_CANCEL")
2909             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2910             dev[2].request("WPS_CANCEL")
2911             if i == 0:
2912                 time.sleep(1)
2913             else:
2914                 time.sleep(0.1)
2915
2916     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2917     resp = conn.getresponse()
2918     if resp.status != 200:
2919         raise Exception("Unexpected HTTP response: %d" % resp.status)
2920
2921     with alloc_fail(hapd, 1, "wpabuf_dup;event_add"):
2922         dev[1].dump_monitor()
2923         dev[2].dump_monitor()
2924         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2925         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2926         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2927         dev[1].request("WPS_CANCEL")
2928         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2929         dev[2].request("WPS_CANCEL")
2930         time.sleep(0.1)
2931
2932     with fail_test(hapd, 1, "os_get_random;uuid_make;subscription_start"):
2933         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2934         resp = conn.getresponse()
2935         if resp.status != 500:
2936             raise Exception("Unexpected HTTP response: %d" % resp.status)
2937
2938     with alloc_fail(hapd, 1, "=subscription_start"):
2939         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2940         resp = conn.getresponse()
2941         if resp.status != 500:
2942             raise Exception("Unexpected HTTP response: %d" % resp.status)
2943
2944     headers = { "callback": '',
2945                 "NT": "upnp:event",
2946                 "timeout": "Second-1234" }
2947     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2948     resp = conn.getresponse()
2949     if resp.status != 500:
2950         raise Exception("Unexpected HTTP response: %d" % resp.status)
2951
2952     headers = { "callback": ' <',
2953                 "NT": "upnp:event",
2954                 "timeout": "Second-1234" }
2955     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2956     resp = conn.getresponse()
2957     if resp.status != 500:
2958         raise Exception("Unexpected HTTP response: %d" % resp.status)
2959
2960     headers = { "callback": '<http://127.0.0.1:12345/event>',
2961                 "NT": "upnp:event",
2962                 "timeout": "Second-1234" }
2963     with alloc_fail(hapd, 1, "wpabuf_alloc;subscription_first_event"):
2964         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2965         resp = conn.getresponse()
2966         if resp.status != 500:
2967             raise Exception("Unexpected HTTP response: %d" % resp.status)
2968
2969     with alloc_fail(hapd, 1, "event_add;subscription_first_event"):
2970         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2971         resp = conn.getresponse()
2972         if resp.status != 500:
2973             raise Exception("Unexpected HTTP response: %d" % resp.status)
2974
2975     with alloc_fail(hapd, 1, "subscr_addr_add_url"):
2976         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2977         resp = conn.getresponse()
2978         if resp.status != 500:
2979             raise Exception("Unexpected HTTP response: %d" % resp.status)
2980
2981     with alloc_fail(hapd, 2, "subscr_addr_add_url"):
2982         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2983         resp = conn.getresponse()
2984         if resp.status != 500:
2985             raise Exception("Unexpected HTTP response: %d" % resp.status)
2986
2987     for i in range(6):
2988         headers = { "callback": '<http://127.0.0.1:%d/event>' % (12345 + i),
2989                     "NT": "upnp:event",
2990                     "timeout": "Second-1234" }
2991         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2992         resp = conn.getresponse()
2993         if resp.status != 200:
2994             raise Exception("Unexpected HTTP response: %d" % resp.status)
2995
2996     with alloc_fail(hapd, 1, "=upnp_wps_device_send_wlan_event"):
2997         dev[1].dump_monitor()
2998         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2999         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3000         dev[1].request("WPS_CANCEL")
3001         time.sleep(0.1)
3002
3003     with alloc_fail(hapd, 1, "wpabuf_alloc;upnp_wps_device_send_event"):
3004         dev[1].dump_monitor()
3005         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3006         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3007         dev[1].request("WPS_CANCEL")
3008         time.sleep(0.1)
3009
3010     with alloc_fail(hapd, 1, "base64_encode;upnp_wps_device_send_wlan_event"):
3011         dev[1].dump_monitor()
3012         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3013         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3014         dev[1].request("WPS_CANCEL")
3015         time.sleep(0.1)
3016
3017     hapd.disable()
3018     with alloc_fail(hapd, 1, "get_netif_info"):
3019         if "FAIL" not in hapd.request("ENABLE"):
3020             raise Exception("ENABLE succeeded during OOM")
3021
3022 def test_ap_wps_upnp_subscribe_events(dev, apdev):
3023     """WPS AP and UPnP event subscription and many events"""
3024     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3025     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3026
3027     location = ssdp_get_location(ap_uuid)
3028     urls = upnp_get_urls(location)
3029     eventurl = urlparse.urlparse(urls['event_sub_url'])
3030
3031     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
3032         def handle(self):
3033             data = self.rfile.readline().strip()
3034             logger.debug(data)
3035             self.wfile.write(gen_wps_event())
3036
3037     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
3038     server.timeout = 1
3039
3040     url = urlparse.urlparse(location)
3041     conn = httplib.HTTPConnection(url.netloc)
3042
3043     headers = { "callback": '<http://127.0.0.1:12345/event>',
3044                 "NT": "upnp:event",
3045                 "timeout": "Second-1234" }
3046     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3047     resp = conn.getresponse()
3048     if resp.status != 200:
3049         raise Exception("Unexpected HTTP response: %d" % resp.status)
3050     sid = resp.getheader("sid")
3051     logger.debug("Subscription SID " + sid)
3052
3053     # Fetch the first event message
3054     server.handle_request()
3055
3056     # Force subscription event queue to reach the maximum length by generating
3057     # new proxied events without the ER fetching any of the pending events.
3058     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3059     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
3060     for i in range(16):
3061         dev[1].dump_monitor()
3062         dev[2].dump_monitor()
3063         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3064         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3065         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3066         dev[1].request("WPS_CANCEL")
3067         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3068         dev[2].request("WPS_CANCEL")
3069         if i % 4 == 1:
3070             time.sleep(1)
3071         else:
3072             time.sleep(0.1)
3073
3074     hapd.request("WPS_PIN any 12345670")
3075     dev[1].dump_monitor()
3076     dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3077     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=10)
3078     if ev is None:
3079         raise Exception("WPS success not reported")
3080
3081     # Close the WPS ER HTTP server without fetching all the pending events.
3082     # This tests hostapd code path that clears subscription and the remaining
3083     # event queue when the interface is deinitialized.
3084     server.handle_request()
3085     server.server_close()
3086
3087     dev[1].wait_connected()
3088
3089 def test_ap_wps_upnp_http_proto(dev, apdev):
3090     """WPS AP and UPnP/HTTP protocol testing"""
3091     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3092     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3093
3094     location = ssdp_get_location(ap_uuid)
3095
3096     url = urlparse.urlparse(location)
3097     conn = httplib.HTTPConnection(url.netloc, timeout=0.2)
3098     #conn.set_debuglevel(1)
3099
3100     conn.request("HEAD", "hello")
3101     resp = conn.getresponse()
3102     if resp.status != 501:
3103         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3104     conn.close()
3105
3106     for cmd in [ "PUT", "DELETE", "TRACE", "CONNECT", "M-SEARCH", "M-POST" ]:
3107         try:
3108             conn.request(cmd, "hello")
3109             resp = conn.getresponse()
3110         except Exception, e:
3111             pass
3112         conn.close()
3113
3114     headers = { "Content-Length": 'abc' }
3115     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3116     try:
3117         resp = conn.getresponse()
3118     except Exception, e:
3119         pass
3120     conn.close()
3121
3122     headers = { "Content-Length": '-10' }
3123     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3124     try:
3125         resp = conn.getresponse()
3126     except Exception, e:
3127         pass
3128     conn.close()
3129
3130     headers = { "Content-Length": '10000000000000' }
3131     conn.request("HEAD", "hello", "\r\n\r\nhello", headers)
3132     try:
3133         resp = conn.getresponse()
3134     except Exception, e:
3135         pass
3136     conn.close()
3137
3138     headers = { "Transfer-Encoding": 'abc' }
3139     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3140     resp = conn.getresponse()
3141     if resp.status != 501:
3142         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3143     conn.close()
3144
3145     headers = { "Transfer-Encoding": 'chunked' }
3146     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3147     resp = conn.getresponse()
3148     if resp.status != 501:
3149         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3150     conn.close()
3151
3152     # Too long a header
3153     conn.request("HEAD", 5000 * 'A')
3154     try:
3155         resp = conn.getresponse()
3156     except Exception, e:
3157         pass
3158     conn.close()
3159
3160     # Long URL but within header length limits
3161     conn.request("HEAD", 3000 * 'A')
3162     resp = conn.getresponse()
3163     if resp.status != 501:
3164         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3165     conn.close()
3166
3167     headers = { "Content-Length": '20' }
3168     conn.request("POST", "hello", 10 * 'A' + "\r\n\r\n", headers)
3169     try:
3170         resp = conn.getresponse()
3171     except Exception, e:
3172         pass
3173     conn.close()
3174
3175     conn.request("POST", "hello", 5000 * 'A' + "\r\n\r\n")
3176     resp = conn.getresponse()
3177     if resp.status != 404:
3178         raise Exception("Unexpected HTTP response: %d" % resp.status)
3179     conn.close()
3180
3181     conn.request("POST", "hello", 60000 * 'A' + "\r\n\r\n")
3182     try:
3183         resp = conn.getresponse()
3184     except Exception, e:
3185         pass
3186     conn.close()
3187
3188 def test_ap_wps_upnp_http_proto_chunked(dev, apdev):
3189     """WPS AP and UPnP/HTTP protocol testing for chunked encoding"""
3190     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3191     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3192
3193     location = ssdp_get_location(ap_uuid)
3194
3195     url = urlparse.urlparse(location)
3196     conn = httplib.HTTPConnection(url.netloc)
3197     #conn.set_debuglevel(1)
3198
3199     headers = { "Transfer-Encoding": 'chunked' }
3200     conn.request("POST", "hello",
3201                  "a\r\nabcdefghij\r\n" + "2\r\nkl\r\n" + "0\r\n\r\n",
3202                  headers)
3203     resp = conn.getresponse()
3204     if resp.status != 404:
3205         raise Exception("Unexpected HTTP response: %d" % resp.status)
3206     conn.close()
3207
3208     conn.putrequest("POST", "hello")
3209     conn.putheader('Transfer-Encoding', 'chunked')
3210     conn.endheaders()
3211     conn.send("a\r\nabcdefghij\r\n")
3212     time.sleep(0.1)
3213     conn.send("2\r\nkl\r\n")
3214     conn.send("0\r\n\r\n")
3215     resp = conn.getresponse()
3216     if resp.status != 404:
3217         raise Exception("Unexpected HTTP response: %d" % resp.status)
3218     conn.close()
3219
3220     conn.putrequest("POST", "hello")
3221     conn.putheader('Transfer-Encoding', 'chunked')
3222     conn.endheaders()
3223     completed = False
3224     try:
3225         for i in range(20000):
3226             conn.send("1\r\nZ\r\n")
3227         conn.send("0\r\n\r\n")
3228         resp = conn.getresponse()
3229         completed = True
3230     except Exception, e:
3231         pass
3232     conn.close()
3233     if completed:
3234         raise Exception("Too long chunked request did not result in connection reset")
3235
3236     headers = { "Transfer-Encoding": 'chunked' }
3237     conn.request("POST", "hello", "80000000\r\na", headers)
3238     try:
3239         resp = conn.getresponse()
3240     except Exception, e:
3241         pass
3242     conn.close()
3243
3244     conn.request("POST", "hello", "10000000\r\na", headers)
3245     try:
3246         resp = conn.getresponse()
3247     except Exception, e:
3248         pass
3249     conn.close()
3250
3251 def test_ap_wps_disabled(dev, apdev):
3252     """WPS operations while WPS is disabled"""
3253     ssid = "test-wps-disabled"
3254     hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid })
3255     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3256     if "FAIL" not in hapd.request("WPS_PBC"):
3257         raise Exception("WPS_PBC succeeded unexpectedly")
3258     if "FAIL" not in hapd.request("WPS_CANCEL"):
3259         raise Exception("WPS_CANCEL succeeded unexpectedly")
3260
3261 def test_ap_wps_mixed_cred(dev, apdev):
3262     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
3263     ssid = "test-wps-wep"
3264     hostapd.add_ap(apdev[0]['ifname'],
3265                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3266                      "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" })
3267     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3268     hapd.request("WPS_PBC")
3269     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3270     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3271     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
3272     if ev is None:
3273         raise Exception("WPS-SUCCESS event timed out")
3274     nets = dev[0].list_networks()
3275     if len(nets) != 1:
3276         raise Exception("Unexpected number of network blocks")
3277     id = nets[0]['id']
3278     proto = dev[0].get_network(id, "proto")
3279     if proto != "WPA RSN":
3280         raise Exception("Unexpected merged proto field value: " + proto)
3281     pairwise = dev[0].get_network(id, "pairwise")
3282     if pairwise != "CCMP TKIP" and pairwise != "CCMP GCMP TKIP":
3283         raise Exception("Unexpected merged pairwise field value: " + pairwise)
3284
3285 def test_ap_wps_while_connected(dev, apdev):
3286     """WPS PBC provisioning while connected to another AP"""
3287     ssid = "test-wps-conf"
3288     hostapd.add_ap(apdev[0]['ifname'],
3289                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3290                      "wpa_passphrase": "12345678", "wpa": "2",
3291                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3292     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3293
3294     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
3295     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3296
3297     logger.info("WPS provisioning step")
3298     hapd.request("WPS_PBC")
3299     dev[0].dump_monitor()
3300     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3301     dev[0].wait_connected(timeout=30)
3302     status = dev[0].get_status()
3303     if status['bssid'] != apdev[0]['bssid']:
3304         raise Exception("Unexpected BSSID")
3305
3306 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
3307     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
3308     ssid = "test-wps-conf"
3309     hostapd.add_ap(apdev[0]['ifname'],
3310                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3311                      "wpa_passphrase": "12345678", "wpa": "2",
3312                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3313     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3314
3315     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
3316
3317     try:
3318         dev[0].request("STA_AUTOCONNECT 0")
3319         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3320
3321         logger.info("WPS provisioning step")
3322         hapd.request("WPS_PBC")
3323         dev[0].dump_monitor()
3324         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3325         dev[0].wait_connected(timeout=30)
3326         status = dev[0].get_status()
3327         if status['bssid'] != apdev[0]['bssid']:
3328             raise Exception("Unexpected BSSID")
3329     finally:
3330         dev[0].request("STA_AUTOCONNECT 1")
3331
3332 def test_ap_wps_from_event(dev, apdev):
3333     """WPS PBC event on AP to enable PBC"""
3334     ssid = "test-wps-conf"
3335     hapd = hostapd.add_ap(apdev[0]['ifname'],
3336                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3337                             "wpa_passphrase": "12345678", "wpa": "2",
3338                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3339     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3340     dev[0].dump_monitor()
3341     hapd.dump_monitor()
3342     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3343
3344     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
3345     if ev is None:
3346         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
3347     vals = ev.split(' ')
3348     if vals[1] != dev[0].p2p_interface_addr():
3349         raise Exception("Unexpected enrollee address: " + vals[1])
3350     if vals[5] != '4':
3351         raise Exception("Unexpected Device Password Id: " + vals[5])
3352     hapd.request("WPS_PBC")
3353     dev[0].wait_connected(timeout=30)
3354
3355 def test_ap_wps_ap_scan_2(dev, apdev):
3356     """AP_SCAN 2 for WPS"""
3357     ssid = "test-wps-conf"
3358     hapd = hostapd.add_ap(apdev[0]['ifname'],
3359                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3360                             "wpa_passphrase": "12345678", "wpa": "2",
3361                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3362     hapd.request("WPS_PBC")
3363
3364     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
3365     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
3366
3367     if "OK" not in wpas.request("AP_SCAN 2"):
3368         raise Exception("Failed to set AP_SCAN 2")
3369
3370     wpas.flush_scan_cache()
3371     wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
3372     wpas.request("WPS_PBC " + apdev[0]['bssid'])
3373     ev = wpas.wait_event(["WPS-SUCCESS"], timeout=15)
3374     if ev is None:
3375         raise Exception("WPS-SUCCESS event timed out")
3376     wpas.wait_connected(timeout=30)
3377     wpas.request("DISCONNECT")
3378     wpas.request("BSS_FLUSH 0")
3379     wpas.dump_monitor()
3380     wpas.request("REASSOCIATE")
3381     wpas.wait_connected(timeout=30)
3382
3383 def test_ap_wps_eapol_workaround(dev, apdev):
3384     """EAPOL workaround code path for 802.1X header length mismatch"""
3385     ssid = "test-wps"
3386     hostapd.add_ap(apdev[0]['ifname'],
3387                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
3388     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3389     bssid = apdev[0]['bssid']
3390     hapd.request("SET ext_eapol_frame_io 1")
3391     dev[0].request("SET ext_eapol_frame_io 1")
3392     hapd.request("WPS_PBC")
3393     dev[0].request("WPS_PBC")
3394
3395     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3396     if ev is None:
3397         raise Exception("Timeout on EAPOL-TX from hostapd")
3398
3399     res = dev[0].request("EAPOL_RX " + bssid + " 020000040193000501FFFF")
3400     if "OK" not in res:
3401         raise Exception("EAPOL_RX to wpa_supplicant failed")
3402
3403 def test_ap_wps_iteration(dev, apdev):
3404     """WPS PIN and iterate through APs without selected registrar"""
3405     ssid = "test-wps-conf"
3406     hapd = hostapd.add_ap(apdev[0]['ifname'],
3407                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3408                             "wpa_passphrase": "12345678", "wpa": "2",
3409                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3410
3411     ssid2 = "test-wps-conf2"
3412     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3413                            { "ssid": ssid2, "eap_server": "1", "wps_state": "2",
3414                              "wpa_passphrase": "12345678", "wpa": "2",
3415                              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3416
3417     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3418     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
3419     dev[0].dump_monitor()
3420     pin = dev[0].request("WPS_PIN any")
3421
3422     # Wait for iteration through all WPS APs to happen before enabling any
3423     # Registrar.
3424     for i in range(2):
3425         ev = dev[0].wait_event(["Associated with"], timeout=30)
3426         if ev is None:
3427             raise Exception("No association seen")
3428         ev = dev[0].wait_event(["WPS-M2D"], timeout=10)
3429         if ev is None:
3430             raise Exception("No M2D from AP")
3431         dev[0].wait_disconnected()
3432
3433     # Verify that each AP requested PIN
3434     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3435     if ev is None:
3436         raise Exception("No WPS-PIN-NEEDED event from AP")
3437     ev = hapd2.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3438     if ev is None:
3439         raise Exception("No WPS-PIN-NEEDED event from AP2")
3440
3441     # Provide PIN to one of the APs and verify that connection gets formed
3442     hapd.request("WPS_PIN any " + pin)
3443     dev[0].wait_connected(timeout=30)
3444
3445 def test_ap_wps_iteration_error(dev, apdev):
3446     """WPS AP iteration on no Selected Registrar and error case with an AP"""
3447     ssid = "test-wps-conf-pin"
3448     hapd = hostapd.add_ap(apdev[0]['ifname'],
3449                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3450                             "wpa_passphrase": "12345678", "wpa": "2",
3451                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3452                             "wps_independent": "1" })
3453     hapd.request("SET ext_eapol_frame_io 1")
3454     bssid = apdev[0]['bssid']
3455     pin = dev[0].wps_read_pin()
3456     dev[0].request("WPS_PIN any " + pin)
3457
3458     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3459     if ev is None:
3460         raise Exception("No EAPOL-TX (EAP-Request/Identity) from hostapd")
3461     dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
3462
3463     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3464     if ev is None:
3465         raise Exception("No EAPOL-TX (EAP-WSC/Start) from hostapd")
3466     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
3467     if ev is None:
3468         raise Exception("No CTRL-EVENT-EAP-STARTED")
3469
3470     # Do not forward any more EAPOL frames to test wpa_supplicant behavior for
3471     # a case with an incorrectly behaving WPS AP.
3472
3473     # Start the real target AP and activate registrar on it.
3474     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3475                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3476                             "wpa_passphrase": "12345678", "wpa": "2",
3477                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3478                             "wps_independent": "1" })
3479     hapd2.request("WPS_PIN any " + pin)
3480
3481     dev[0].wait_disconnected(timeout=15)
3482     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
3483     if ev is None:
3484         raise Exception("No CTRL-EVENT-EAP-STARTED for the second AP")
3485     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
3486     if ev is None:
3487         raise Exception("No WPS-CRED-RECEIVED for the second AP")
3488     dev[0].wait_connected(timeout=15)
3489
3490 def test_ap_wps_priority(dev, apdev):
3491     """WPS PIN provisioning with configured AP and wps_priority"""
3492     ssid = "test-wps-conf-pin"
3493     hostapd.add_ap(apdev[0]['ifname'],
3494                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3495                      "wpa_passphrase": "12345678", "wpa": "2",
3496                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3497     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3498     logger.info("WPS provisioning step")
3499     pin = dev[0].wps_read_pin()
3500     hapd.request("WPS_PIN any " + pin)
3501     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3502     dev[0].dump_monitor()
3503     try:
3504         dev[0].request("SET wps_priority 6")
3505         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3506         dev[0].wait_connected(timeout=30)
3507         netw = dev[0].list_networks()
3508         prio = dev[0].get_network(netw[0]['id'], 'priority')
3509         if prio != '6':
3510             raise Exception("Unexpected network priority: " + prio)
3511     finally:
3512         dev[0].request("SET wps_priority 0")
3513
3514 def test_ap_wps_and_non_wps(dev, apdev):
3515     """WPS and non-WPS AP in single hostapd process"""
3516     params = { "ssid": "wps", "eap_server": "1", "wps_state": "1" }
3517     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3518
3519     params = { "ssid": "no wps" }
3520     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
3521
3522     appin = hapd.request("WPS_AP_PIN random")
3523     if "FAIL" in appin:
3524         raise Exception("Could not generate random AP PIN")
3525     if appin not in hapd.request("WPS_AP_PIN get"):
3526         raise Exception("Could not fetch current AP PIN")
3527
3528     if "FAIL" in hapd.request("WPS_PBC"):
3529         raise Exception("WPS_PBC failed")
3530     if "FAIL" in hapd.request("WPS_CANCEL"):
3531         raise Exception("WPS_CANCEL failed")
3532
3533 def test_ap_wps_init_oom(dev, apdev):
3534     """Initial AP configuration and OOM during PSK generation"""
3535     ssid = "test-wps"
3536     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
3537     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3538
3539     with alloc_fail(hapd, 1, "base64_encode;wps_build_cred"):
3540         pin = dev[0].wps_read_pin()
3541         hapd.request("WPS_PIN any " + pin)
3542         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3543         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3544         dev[0].wait_disconnected()
3545
3546     hapd.request("WPS_PIN any " + pin)
3547     dev[0].wait_connected(timeout=30)
3548
3549 def test_ap_wps_er_oom(dev, apdev):
3550     """WPS ER OOM in XML processing"""
3551     try:
3552         _test_ap_wps_er_oom(dev, apdev)
3553     finally:
3554         dev[0].request("WPS_ER_STOP")
3555         dev[1].request("WPS_CANCEL")
3556         dev[0].request("DISCONNECT")
3557
3558 def _test_ap_wps_er_oom(dev, apdev):
3559     ssid = "wps-er-ap-config"
3560     ap_pin = "12345670"
3561     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3562     hostapd.add_ap(apdev[0]['ifname'],
3563                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3564                      "wpa_passphrase": "12345678", "wpa": "2",
3565                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3566                      "device_name": "Wireless AP", "manufacturer": "Company",
3567                      "model_name": "WAP", "model_number": "123",
3568                      "serial_number": "12345", "device_type": "6-0050F204-1",
3569                      "os_version": "01020300",
3570                      "config_methods": "label push_button",
3571                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
3572
3573     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
3574
3575     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3576         dev[0].request("WPS_ER_START ifname=lo")
3577         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=3)
3578         if ev is not None:
3579             raise Exception("Unexpected AP discovery")
3580
3581     dev[0].request("WPS_ER_STOP")
3582     dev[0].request("WPS_ER_START ifname=lo")
3583     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3584     if ev is None:
3585         raise Exception("AP discovery timed out")
3586
3587     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3588     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3589         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
3590         ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
3591         if ev is None:
3592             raise Exception("PBC scan failed")
3593         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
3594         if ev is None:
3595             raise Exception("Enrollee discovery timed out")
3596
3597 def test_ap_wps_er_init_oom(dev, apdev):
3598     """WPS ER and OOM during init"""
3599     try:
3600         _test_ap_wps_er_init_oom(dev, apdev)
3601     finally:
3602         dev[0].request("WPS_ER_STOP")
3603
3604 def _test_ap_wps_er_init_oom(dev, apdev):
3605     with alloc_fail(dev[0], 1, "wps_er_init"):
3606         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3607             raise Exception("WPS_ER_START succeeded during OOM")
3608     with alloc_fail(dev[0], 1, "http_server_init"):
3609         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3610             raise Exception("WPS_ER_START succeeded during OOM")
3611     with alloc_fail(dev[0], 2, "http_server_init"):
3612         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3613             raise Exception("WPS_ER_START succeeded during OOM")
3614     with alloc_fail(dev[0], 1, "eloop_register_sock;wps_er_ssdp_init"):
3615         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3616             raise Exception("WPS_ER_START succeeded during OOM")
3617     with fail_test(dev[0], 1, "os_get_random;wps_er_init"):
3618         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3619             raise Exception("WPS_ER_START succeeded during os_get_random failure")
3620
3621 def test_ap_wps_er_init_fail(dev, apdev):
3622     """WPS ER init failure"""
3623     if "FAIL" not in dev[0].request("WPS_ER_START ifname=does-not-exist"):
3624         dev[0].request("WPS_ER_STOP")
3625         raise Exception("WPS_ER_START with non-existing ifname succeeded")
3626
3627 def test_ap_wps_wpa_cli_action(dev, apdev, test_params):
3628     """WPS events and wpa_cli action script"""
3629     logdir = os.path.abspath(test_params['logdir'])
3630     pidfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.pid')
3631     logfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.res')
3632     actionfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.action.sh')
3633
3634     with open(actionfile, 'w') as f:
3635         f.write('#!/bin/sh\n')
3636         f.write('echo $* >> %s\n' % logfile)
3637         # Kill the process and wait some time before returning to allow all the
3638         # pending events to be processed with some of this happening after the
3639         # eloop SIGALRM signal has been scheduled.
3640         f.write('if [ $2 = "WPS-SUCCESS" -a -r %s ]; then kill `cat %s`; sleep 1; fi\n' % (pidfile, pidfile))
3641
3642     os.chmod(actionfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
3643              stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
3644
3645     ssid = "test-wps-conf"
3646     hostapd.add_ap(apdev[0]['ifname'],
3647                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3648                      "wpa_passphrase": "12345678", "wpa": "2",
3649                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3650     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3651
3652     prg = os.path.join(test_params['logdir'],
3653                        'alt-wpa_supplicant/wpa_supplicant/wpa_cli')
3654     if not os.path.exists(prg):
3655         prg = '../../wpa_supplicant/wpa_cli'
3656     arg = [ prg, '-P', pidfile, '-B', '-i', dev[0].ifname, '-a', actionfile ]
3657     subprocess.call(arg)
3658
3659     arg = [ 'ps', 'ax' ]
3660     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3661     out = cmd.communicate()[0]
3662     cmd.wait()
3663     logger.debug("Processes:\n" + out)
3664     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) not in out:
3665         raise Exception("Did not see wpa_cli running")
3666
3667     hapd.request("WPS_PIN any 12345670")
3668     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3669     dev[0].dump_monitor()
3670     dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3671     dev[0].wait_connected(timeout=30)
3672
3673     for i in range(30):
3674         if not os.path.exists(pidfile):
3675             break
3676         time.sleep(0.1)
3677
3678     if not os.path.exists(logfile):
3679         raise Exception("wpa_cli action results file not found")
3680     with open(logfile, 'r') as f:
3681         res = f.read()
3682     if "WPS-SUCCESS" not in res:
3683         raise Exception("WPS-SUCCESS event not seen in action file")
3684
3685     arg = [ 'ps', 'ax' ]
3686     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3687     out = cmd.communicate()[0]
3688     cmd.wait()
3689     logger.debug("Remaining processes:\n" + out)
3690     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) in out:
3691         raise Exception("wpa_cli still running")
3692
3693     if os.path.exists(pidfile):
3694         raise Exception("PID file not removed")
3695
3696 def test_ap_wps_er_ssdp_proto(dev, apdev):
3697     """WPS ER SSDP protocol testing"""
3698     try:
3699         _test_ap_wps_er_ssdp_proto(dev, apdev)
3700     finally:
3701         dev[0].request("WPS_ER_STOP")
3702
3703 def _test_ap_wps_er_ssdp_proto(dev, apdev):
3704     socket.setdefaulttimeout(1)
3705     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3706     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3707     sock.bind(("239.255.255.250", 1900))
3708     if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo foo"):
3709         raise Exception("Invalid filter accepted")
3710     if "OK" not in dev[0].request("WPS_ER_START ifname=lo 1.2.3.4"):
3711         raise Exception("WPS_ER_START with filter failed")
3712     (msg,addr) = sock.recvfrom(1000)
3713     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3714     if "M-SEARCH" not in msg:
3715         raise Exception("Not an M-SEARCH")
3716     sock.sendto("FOO", addr)
3717     time.sleep(0.1)
3718     dev[0].request("WPS_ER_STOP")
3719
3720     dev[0].request("WPS_ER_START ifname=lo")
3721     (msg,addr) = sock.recvfrom(1000)
3722     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3723     if "M-SEARCH" not in msg:
3724         raise Exception("Not an M-SEARCH")
3725     sock.sendto("FOO", addr)
3726     sock.sendto("HTTP/1.1 200 OK\r\nFOO\r\n\r\n", addr)
3727     sock.sendto("HTTP/1.1 200 OK\r\nNTS:foo\r\n\r\n", addr)
3728     sock.sendto("HTTP/1.1 200 OK\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3729     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   foo=1\r\n\r\n", addr)
3730     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   max-age=1\r\n\r\n", addr)
3731     sock.sendto("HTTP/1.1 200 OK\r\nusn:\r\n\r\n", addr)
3732     sock.sendto("HTTP/1.1 200 OK\r\nusn:foo\r\n\r\n", addr)
3733     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:\r\n\r\n", addr)
3734     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     \r\n\r\n", addr)
3735     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     foo\r\n\r\n", addr)
3736     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\n\r\n", addr)
3737     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3738     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\n\r\n", addr)
3739     with alloc_fail(dev[0], 1, "wps_er_ap_add"):
3740         sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\ncache-control:max-age=1\r\n\r\n", addr)
3741         time.sleep(0.1)
3742     with alloc_fail(dev[0], 2, "wps_er_ap_add"):
3743         sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\ncache-control:max-age=1\r\n\r\n", addr)
3744         time.sleep(0.1)
3745
3746     # Add an AP with bogus URL
3747     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\ncache-control:max-age=1\r\n\r\n", addr)
3748     # Update timeout on AP without updating URL
3749     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://127.0.0.1:12345/foo.xml\r\ncache-control:max-age=1\r\n\r\n", addr)
3750     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3751     if ev is None:
3752         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3753
3754     # Add an AP with a valid URL (but no server listing to it)
3755     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://127.0.0.1:12345/foo.xml\r\ncache-control:max-age=1\r\n\r\n", addr)
3756     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3757     if ev is None:
3758         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3759
3760     sock.close()
3761
3762 wps_event_url = None
3763
3764 def gen_upnp_info(eventSubURL='wps_event', controlURL='wps_control',
3765                   udn='uuid:27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'):
3766     payload = '''<?xml version="1.0"?>
3767 <root xmlns="urn:schemas-upnp-org:device-1-0">
3768 <specVersion>
3769 <major>1</major>
3770 <minor>0</minor>
3771 </specVersion>
3772 <device>
3773 <deviceType>urn:schemas-wifialliance-org:device:WFADevice:1</deviceType>
3774 <friendlyName>WPS Access Point</friendlyName>
3775 <manufacturer>Company</manufacturer>
3776 <modelName>WAP</modelName>
3777 <modelNumber>123</modelNumber>
3778 <serialNumber>12345</serialNumber>
3779 '''
3780     if udn:
3781         payload += '<UDN>' + udn + '</UDN>'
3782     payload += '''<serviceList>
3783 <service>
3784 <serviceType>urn:schemas-wifialliance-org:service:WFAWLANConfig:1</serviceType>
3785 <serviceId>urn:wifialliance-org:serviceId:WFAWLANConfig1</serviceId>
3786 <SCPDURL>wps_scpd.xml</SCPDURL>
3787 '''
3788     if controlURL:
3789         payload += '<controlURL>' + controlURL + '</controlURL>\n'
3790     if eventSubURL:
3791         payload += '<eventSubURL>' + eventSubURL + '</eventSubURL>\n'
3792     payload += '''</service>
3793 </serviceList>
3794 </device>
3795 </root>
3796 '''
3797     hdr = 'HTTP/1.1 200 OK\r\n' + \
3798           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3799           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3800           'Connection: close\r\n' + \
3801           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3802           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3803     return hdr + payload
3804
3805 def gen_wps_control(payload_override=None):
3806     payload = '''<?xml version="1.0"?>
3807 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3808 <s:Body>
3809 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3810 <NewDeviceInfo>EEoAARAQIgABBBBHABAn6oAanlxOc72C+Jy80Q1+ECAABgIAAAADABAaABCJZ7DPtbU3Ust9
3811 Z3wJF07WEDIAwH45D3i1OqB7eJGwTzqeapS71h3KyXncK2xJZ+xqScrlorNEg6LijBJzG2Ca
3812 +FZli0iliDJd397yAx/jk4nFXco3q5ylBSvSw9dhJ5u1xBKSnTilKGlUHPhLP75PUqM3fot9
3813 7zwtFZ4bx6x1sBA6oEe2d0aUJmLumQGCiKEIWlnxs44zego/2tAe81bDzdPBM7o5HH/FUhD+
3814 KoGzFXp51atP+1n9Vta6AkI0Vye99JKLcC6Md9dMJltSVBgd4Xc4lRAEAAIAIxAQAAIADRAN
3815 AAEBEAgAAgAEEEQAAQIQIQAHQ29tcGFueRAjAANXQVAQJAADMTIzEEIABTEyMzQ1EFQACAAG
3816 AFDyBAABEBEAC1dpcmVsZXNzIEFQEDwAAQEQAgACAAAQEgACAAAQCQACAAAQLQAEgQIDABBJ
3817 AAYANyoAASA=
3818 </NewDeviceInfo>
3819 </u:GetDeviceInfoResponse>
3820 </s:Body>
3821 </s:Envelope>
3822 '''
3823     if payload_override:
3824         payload = payload_override
3825     hdr = 'HTTP/1.1 200 OK\r\n' + \
3826           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3827           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3828           'Connection: close\r\n' + \
3829           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3830           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3831     return hdr + payload
3832
3833 def gen_wps_event(sid='uuid:7eb3342a-8a5f-47fe-a585-0785bfec6d8a'):
3834     payload = ""
3835     hdr = 'HTTP/1.1 200 OK\r\n' + \
3836           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3837           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3838           'Connection: close\r\n' + \
3839           'Content-Length: ' + str(len(payload)) + '\r\n'
3840     if sid:
3841         hdr += 'SID: ' + sid + '\r\n'
3842     hdr += 'Timeout: Second-1801\r\n' + \
3843           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3844     return hdr + payload
3845
3846 class WPSAPHTTPServer(SocketServer.StreamRequestHandler):
3847     def handle(self):
3848         data = self.rfile.readline().strip()
3849         logger.info("HTTP server received: " + data)
3850         while True:
3851             hdr = self.rfile.readline().strip()
3852             if len(hdr) == 0:
3853                 break
3854             logger.info("HTTP header: " + hdr)
3855             if "CALLBACK:" in hdr:
3856                 global wps_event_url
3857                 wps_event_url = hdr.split(' ')[1].strip('<>')
3858
3859         if "GET /foo.xml" in data:
3860             self.handle_upnp_info()
3861         elif "POST /wps_control" in data:
3862             self.handle_wps_control()
3863         elif "SUBSCRIBE /wps_event" in data:
3864             self.handle_wps_event()
3865         else:
3866             self.handle_others(data)
3867
3868     def handle_upnp_info(self):
3869         self.wfile.write(gen_upnp_info())
3870
3871     def handle_wps_control(self):
3872         self.wfile.write(gen_wps_control())
3873
3874     def handle_wps_event(self):
3875         self.wfile.write(gen_wps_event())
3876
3877     def handle_others(self, data):
3878         logger.info("Ignore HTTP request: " + data)
3879
3880 class MyTCPServer(SocketServer.TCPServer):
3881     def __init__(self, addr, handler):
3882         self.allow_reuse_address = True
3883         SocketServer.TCPServer.__init__(self, addr, handler)
3884
3885 def wps_er_start(dev, http_server, max_age=1, wait_m_search=False,
3886                  location_url=None):
3887     socket.setdefaulttimeout(1)
3888     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3889     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3890     sock.bind(("239.255.255.250", 1900))
3891     dev.request("WPS_ER_START ifname=lo")
3892     for i in range(100):
3893         (msg,addr) = sock.recvfrom(1000)
3894         logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3895         if "M-SEARCH" in msg:
3896             break
3897         if not wait_m_search:
3898             raise Exception("Not an M-SEARCH")
3899         if i == 99:
3900             raise Exception("No M-SEARCH seen")
3901
3902     # Add an AP with a valid URL and server listing to it
3903     server = MyTCPServer(("127.0.0.1", 12345), http_server)
3904     if not location_url:
3905         location_url = 'http://127.0.0.1:12345/foo.xml'
3906     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:%s\r\ncache-control:max-age=%d\r\n\r\n" % (location_url, max_age), addr)
3907     server.timeout = 1
3908     return server,sock
3909
3910 def wps_er_stop(dev, sock, server, on_alloc_fail=False):
3911     sock.close()
3912     server.server_close()
3913
3914     if on_alloc_fail:
3915         done = False
3916         for i in range(50):
3917             res = dev.request("GET_ALLOC_FAIL")
3918             if res.startswith("0:"):
3919                 done = True
3920                 break
3921             time.sleep(0.1)
3922         if not done:
3923             raise Exception("No allocation failure reported")
3924     else:
3925         ev = dev.wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3926         if ev is None:
3927             raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3928     dev.request("WPS_ER_STOP")
3929
3930 def run_wps_er_proto_test(dev, handler, no_event_url=False, location_url=None):
3931     try:
3932         uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3933         server,sock = wps_er_start(dev, handler, location_url=location_url)
3934         global wps_event_url
3935         wps_event_url = None
3936         server.handle_request()
3937         server.handle_request()
3938         server.handle_request()
3939         server.server_close()
3940         if no_event_url:
3941             if wps_event_url:
3942                 raise Exception("Received event URL unexpectedly")
3943             return
3944         if wps_event_url is None:
3945             raise Exception("Did not get event URL")
3946         logger.info("Event URL: " + wps_event_url)
3947     finally:
3948             dev.request("WPS_ER_STOP")
3949
3950 def send_wlanevent(url, uuid, data):
3951     conn = httplib.HTTPConnection(url.netloc)
3952     payload = '''<?xml version="1.0" encoding="utf-8"?>
3953 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
3954 <e:property><STAStatus>1</STAStatus></e:property>
3955 <e:property><APStatus>1</APStatus></e:property>
3956 <e:property><WLANEvent>'''
3957     payload += base64.b64encode(data)
3958     payload += '</WLANEvent></e:property></e:propertyset>'
3959     headers = { "Content-type": 'text/xml; charset="utf-8"',
3960                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3961                 "HOST": url.netloc,
3962                 "NT": "upnp:event",
3963                 "SID": "uuid:" + uuid,
3964                 "SEQ": "0",
3965                 "Content-Length": str(len(payload)) }
3966     conn.request("NOTIFY", url.path, payload, headers)
3967     resp = conn.getresponse()
3968     if resp.status != 200:
3969         raise Exception("Unexpected HTTP response: %d" % resp.status)
3970
3971 def test_ap_wps_er_http_proto(dev, apdev):
3972     """WPS ER HTTP protocol testing"""
3973     try:
3974         _test_ap_wps_er_http_proto(dev, apdev)
3975     finally:
3976         dev[0].request("WPS_ER_STOP")
3977
3978 def _test_ap_wps_er_http_proto(dev, apdev):
3979     uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3980     server,sock = wps_er_start(dev[0], WPSAPHTTPServer, max_age=15)
3981     global wps_event_url
3982     wps_event_url = None
3983     server.handle_request()
3984     server.handle_request()
3985     server.handle_request()
3986     server.server_close()
3987     if wps_event_url is None:
3988         raise Exception("Did not get event URL")
3989     logger.info("Event URL: " + wps_event_url)
3990
3991     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3992     if ev is None:
3993         raise Exception("No WPS-ER-AP-ADD event")
3994     if uuid not in ev:
3995         raise Exception("UUID mismatch")
3996
3997     sock.close()
3998
3999     logger.info("Valid Probe Request notification")
4000     url = urlparse.urlparse(wps_event_url)
4001     conn = httplib.HTTPConnection(url.netloc)
4002     payload = '''<?xml version="1.0" encoding="utf-8"?>
4003 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
4004 <e:property><STAStatus>1</STAStatus></e:property>
4005 <e:property><APStatus>1</APStatus></e:property>
4006 <e:property><WLANEvent>ATAyOjAwOjAwOjAwOjAwOjAwEEoAARAQOgABAhAIAAIxSBBHABA2LbR7pTpRkYj7VFi5hrLk
4007 EFQACAAAAAAAAAAAEDwAAQMQAgACAAAQCQACAAAQEgACAAAQIQABIBAjAAEgECQAASAQEQAI
4008 RGV2aWNlIEEQSQAGADcqAAEg
4009 </WLANEvent></e:property>
4010 </e:propertyset>
4011 '''
4012     headers = { "Content-type": 'text/xml; charset="utf-8"',
4013                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4014                 "HOST": url.netloc,
4015                 "NT": "upnp:event",
4016                 "SID": "uuid:" + uuid,
4017                 "SEQ": "0",
4018                 "Content-Length": str(len(payload)) }
4019     conn.request("NOTIFY", url.path, payload, headers)
4020     resp = conn.getresponse()
4021     if resp.status != 200:
4022         raise Exception("Unexpected HTTP response: %d" % resp.status)
4023
4024     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=5)
4025     if ev is None:
4026         raise Exception("No WPS-ER-ENROLLEE-ADD event")
4027     if "362db47b-a53a-5191-88fb-5458b986b2e4" not in ev:
4028         raise Exception("No Enrollee UUID match")
4029
4030     logger.info("Incorrect event URL AP id")
4031     conn = httplib.HTTPConnection(url.netloc)
4032     conn.request("NOTIFY", url.path + '123', payload, headers)
4033     resp = conn.getresponse()
4034     if resp.status != 404:
4035         raise Exception("Unexpected HTTP response: %d" % resp.status)
4036
4037     logger.info("Missing AP id")
4038     conn = httplib.HTTPConnection(url.netloc)
4039     conn.request("NOTIFY", '/event/' + url.path.split('/')[2],
4040                  payload, headers)
4041     time.sleep(0.1)
4042
4043     logger.info("Incorrect event URL event id")
4044     conn = httplib.HTTPConnection(url.netloc)
4045     conn.request("NOTIFY", '/event/123456789/123', payload, headers)
4046     time.sleep(0.1)
4047
4048     logger.info("Incorrect event URL prefix")
4049     conn = httplib.HTTPConnection(url.netloc)
4050     conn.request("NOTIFY", '/foobar/123456789/123', payload, headers)
4051     resp = conn.getresponse()
4052     if resp.status != 404:
4053         raise Exception("Unexpected HTTP response: %d" % resp.status)
4054
4055     logger.info("Unsupported request")
4056     conn = httplib.HTTPConnection(url.netloc)
4057     conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4058     resp = conn.getresponse()
4059     if resp.status != 501:
4060         raise Exception("Unexpected HTTP response: %d" % resp.status)
4061
4062     logger.info("Unsupported request and OOM")
4063     with alloc_fail(dev[0], 1, "wps_er_http_req"):
4064         conn = httplib.HTTPConnection(url.netloc)
4065         conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4066         time.sleep(0.5)
4067
4068     logger.info("Too short WLANEvent")
4069     data = '\x00'
4070     send_wlanevent(url, uuid, data)
4071
4072     logger.info("Invalid WLANEventMAC")
4073     data = '\x00qwertyuiopasdfghjklzxcvbnm'
4074     send_wlanevent(url, uuid, data)
4075
4076     logger.info("Unknown WLANEventType")
4077     data = '\xff02:00:00:00:00:00'
4078     send_wlanevent(url, uuid, data)
4079
4080     logger.info("Probe Request notification without any attributes")
4081     data = '\x0102:00:00:00:00:00'
4082     send_wlanevent(url, uuid, data)
4083
4084     logger.info("Probe Request notification with invalid attribute")
4085     data = '\x0102:00:00:00:00:00\xff'
4086     send_wlanevent(url, uuid, data)
4087
4088     logger.info("EAP message without any attributes")
4089     data = '\x0202:00:00:00:00:00'
4090     send_wlanevent(url, uuid, data)
4091
4092     logger.info("EAP message with invalid attribute")
4093     data = '\x0202:00:00:00:00:00\xff'
4094     send_wlanevent(url, uuid, data)
4095
4096     logger.info("EAP message from new STA and not M1")
4097     data = '\x0202:ff:ff:ff:ff:ff' + '\x10\x22\x00\x01\x05'
4098     send_wlanevent(url, uuid, data)
4099
4100     logger.info("EAP message: M1")
4101     data = '\x0202:00:00:00:00:00'
4102     data += '\x10\x22\x00\x01\x04'
4103     data += '\x10\x47\x00\x10' + 16*'\x00'
4104     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4105     data += '\x10\x1a\x00\x10' + 16*'\x00'
4106     data += '\x10\x32\x00\xc0' + 192*'\x00'
4107     data += '\x10\x04\x00\x02\x00\x00'
4108     data += '\x10\x10\x00\x02\x00\x00'
4109     data += '\x10\x0d\x00\x01\x00'
4110     data += '\x10\x08\x00\x02\x00\x00'
4111     data += '\x10\x44\x00\x01\x00'
4112     data += '\x10\x21\x00\x00'
4113     data += '\x10\x23\x00\x00'
4114     data += '\x10\x24\x00\x00'
4115     data += '\x10\x42\x00\x00'
4116     data += '\x10\x54\x00\x08' + 8*'\x00'
4117     data += '\x10\x11\x00\x00'
4118     data += '\x10\x3c\x00\x01\x00'
4119     data += '\x10\x02\x00\x02\x00\x00'
4120     data += '\x10\x12\x00\x02\x00\x00'
4121     data += '\x10\x09\x00\x02\x00\x00'
4122     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4123     m1 = data
4124     send_wlanevent(url, uuid, data)
4125
4126     logger.info("EAP message: WSC_ACK")
4127     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0d'
4128     send_wlanevent(url, uuid, data)
4129
4130     logger.info("EAP message: M1")
4131     send_wlanevent(url, uuid, m1)
4132
4133     logger.info("EAP message: WSC_NACK")
4134     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0e'
4135     send_wlanevent(url, uuid, data)
4136
4137     logger.info("EAP message: M1 - Too long attribute values")
4138     data = '\x0202:00:00:00:00:00'
4139     data += '\x10\x11\x00\x21' + 33*'\x00'
4140     data += '\x10\x45\x00\x21' + 33*'\x00'
4141     data += '\x10\x42\x00\x21' + 33*'\x00'
4142     data += '\x10\x24\x00\x21' + 33*'\x00'
4143     data += '\x10\x23\x00\x21' + 33*'\x00'
4144     data += '\x10\x21\x00\x41' + 65*'\x00'
4145     data += '\x10\x49\x00\x09\x00\x37\x2a\x05\x02\x00\x00\x05\x00'
4146     send_wlanevent(url, uuid, data)
4147
4148     logger.info("EAP message: M1 missing UUID-E")
4149     data = '\x0202:00:00:00:00:00'
4150     data += '\x10\x22\x00\x01\x04'
4151     send_wlanevent(url, uuid, data)
4152
4153     logger.info("EAP message: M1 missing MAC Address")
4154     data += '\x10\x47\x00\x10' + 16*'\x00'
4155     send_wlanevent(url, uuid, data)
4156
4157     logger.info("EAP message: M1 missing Enrollee Nonce")
4158     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4159     send_wlanevent(url, uuid, data)
4160
4161     logger.info("EAP message: M1 missing Public Key")
4162     data += '\x10\x1a\x00\x10' + 16*'\x00'
4163     send_wlanevent(url, uuid, data)
4164
4165     logger.info("EAP message: M1 missing Authentication Type flags")
4166     data += '\x10\x32\x00\xc0' + 192*'\x00'
4167     send_wlanevent(url, uuid, data)
4168
4169     logger.info("EAP message: M1 missing Encryption Type Flags")
4170     data += '\x10\x04\x00\x02\x00\x00'
4171     send_wlanevent(url, uuid, data)
4172
4173     logger.info("EAP message: M1 missing Connection Type flags")
4174     data += '\x10\x10\x00\x02\x00\x00'
4175     send_wlanevent(url, uuid, data)
4176
4177     logger.info("EAP message: M1 missing Config Methods")
4178     data += '\x10\x0d\x00\x01\x00'
4179     send_wlanevent(url, uuid, data)
4180
4181     logger.info("EAP message: M1 missing Wi-Fi Protected Setup State")
4182     data += '\x10\x08\x00\x02\x00\x00'
4183     send_wlanevent(url, uuid, data)
4184
4185     logger.info("EAP message: M1 missing Manufacturer")
4186     data += '\x10\x44\x00\x01\x00'
4187     send_wlanevent(url, uuid, data)
4188
4189     logger.info("EAP message: M1 missing Model Name")
4190     data += '\x10\x21\x00\x00'
4191     send_wlanevent(url, uuid, data)
4192
4193     logger.info("EAP message: M1 missing Model Number")
4194     data += '\x10\x23\x00\x00'
4195     send_wlanevent(url, uuid, data)
4196
4197     logger.info("EAP message: M1 missing Serial Number")
4198     data += '\x10\x24\x00\x00'
4199     send_wlanevent(url, uuid, data)
4200
4201     logger.info("EAP message: M1 missing Primary Device Type")
4202     data += '\x10\x42\x00\x00'
4203     send_wlanevent(url, uuid, data)
4204
4205     logger.info("EAP message: M1 missing Device Name")
4206     data += '\x10\x54\x00\x08' + 8*'\x00'
4207     send_wlanevent(url, uuid, data)
4208
4209     logger.info("EAP message: M1 missing RF Bands")
4210     data += '\x10\x11\x00\x00'
4211     send_wlanevent(url, uuid, data)
4212
4213     logger.info("EAP message: M1 missing Association State")
4214     data += '\x10\x3c\x00\x01\x00'
4215     send_wlanevent(url, uuid, data)
4216
4217     logger.info("EAP message: M1 missing Device Password ID")
4218     data += '\x10\x02\x00\x02\x00\x00'
4219     send_wlanevent(url, uuid, data)
4220
4221     logger.info("EAP message: M1 missing Configuration Error")
4222     data += '\x10\x12\x00\x02\x00\x00'
4223     send_wlanevent(url, uuid, data)
4224
4225     logger.info("EAP message: M1 missing OS Version")
4226     data += '\x10\x09\x00\x02\x00\x00'
4227     send_wlanevent(url, uuid, data)
4228
4229     logger.info("Check max concurrent requests")
4230     addr = (url.hostname, url.port)
4231     socks = {}
4232     for i in range(20):
4233         socks[i] = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4234                                  socket.IPPROTO_TCP)
4235         socks[i].connect(addr)
4236     for i in range(20):
4237         socks[i].send("GET / HTTP/1.1\r\n\r\n")
4238     count = 0
4239     for i in range(20):
4240         try:
4241             res = socks[i].recv(100)
4242             if "HTTP/1" in res:
4243                 count += 1
4244         except:
4245             pass
4246         socks[i].close()
4247     logger.info("%d concurrent HTTP GET operations returned response" % count)
4248     if count < 10:
4249         raise Exception("Too few concurrent HTTP connections accepted")
4250
4251     logger.info("OOM in HTTP server")
4252     for func in [ "http_request_init", "httpread_create",
4253                   "eloop_register_timeout;httpread_create",
4254                   "eloop_register_sock;httpread_create",
4255                   "httpread_hdr_analyze" ]:
4256         with alloc_fail(dev[0], 1, func):
4257             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4258                                  socket.IPPROTO_TCP)
4259             sock.connect(addr)
4260             sock.send("GET / HTTP/1.1\r\n\r\n")
4261             try:
4262                 sock.recv(100)
4263             except:
4264                 pass
4265             sock.close()
4266
4267     logger.info("Invalid HTTP header")
4268     for req in [ " GET / HTTP/1.1\r\n\r\n",
4269                  "HTTP/1.1 200 OK\r\n\r\n",
4270                  "HTTP/\r\n\r\n",
4271                  "GET %%a%aa% HTTP/1.1\r\n\r\n",
4272                  "GET / HTTP/1.1\r\n FOO\r\n\r\n",
4273                  "NOTIFY / HTTP/1.1\r\n" + 4097*'a' + '\r\n\r\n',
4274                  "NOTIFY / HTTP/1.1\r\n\r\n" + 8193*'a',
4275                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n foo\r\n",
4276                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n1\r\nfoo\r\n",
4277                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\n",
4278                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\naa\ra\r\n\ra" ]:
4279         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4280                              socket.IPPROTO_TCP)
4281         sock.settimeout(0.1)
4282         sock.connect(addr)
4283         sock.send(req)
4284         try:
4285             sock.recv(100)
4286         except:
4287             pass
4288         sock.close()
4289
4290     with alloc_fail(dev[0], 2, "httpread_read_handler"):
4291         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4292                              socket.IPPROTO_TCP)
4293         sock.connect(addr)
4294         sock.send("NOTIFY / HTTP/1.1\r\n\r\n" + 4500*'a')
4295         try:
4296             sock.recv(100)
4297         except:
4298             pass
4299         sock.close()
4300
4301     conn = httplib.HTTPConnection(url.netloc)
4302     payload = '<foo'
4303     headers = { "Content-type": 'text/xml; charset="utf-8"',
4304                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4305                 "HOST": url.netloc,
4306                 "NT": "upnp:event",
4307                 "SID": "uuid:" + uuid,
4308                 "SEQ": "0",
4309                 "Content-Length": str(len(payload)) }
4310     conn.request("NOTIFY", url.path, payload, headers)
4311     resp = conn.getresponse()
4312     if resp.status != 200:
4313         raise Exception("Unexpected HTTP response: %d" % resp.status)
4314
4315     conn = httplib.HTTPConnection(url.netloc)
4316     payload = '<WLANEvent foo></WLANEvent>'
4317     headers = { "Content-type": 'text/xml; charset="utf-8"',
4318                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4319                 "HOST": url.netloc,
4320                 "NT": "upnp:event",
4321                 "SID": "uuid:" + uuid,
4322                 "SEQ": "0",
4323                 "Content-Length": str(len(payload)) }
4324     conn.request("NOTIFY", url.path, payload, headers)
4325     resp = conn.getresponse()
4326     if resp.status != 200:
4327         raise Exception("Unexpected HTTP response: %d" % resp.status)
4328
4329     with alloc_fail(dev[0], 1, "xml_get_first_item"):
4330         send_wlanevent(url, uuid, '')
4331
4332     with alloc_fail(dev[0], 1, "wpabuf_alloc_ext_data;xml_get_base64_item"):
4333         send_wlanevent(url, uuid, 'foo')
4334
4335     for func in [ "wps_init",
4336                   "wps_process_manufacturer",
4337                   "wps_process_model_name",
4338                   "wps_process_model_number",
4339                   "wps_process_serial_number",
4340                   "wps_process_dev_name" ]:
4341         with alloc_fail(dev[0], 1, func):
4342             send_wlanevent(url, uuid, m1)
4343
4344 def test_ap_wps_er_http_proto_no_event_sub_url(dev, apdev):
4345     """WPS ER HTTP protocol testing - no eventSubURL"""
4346     class WPSAPHTTPServer_no_event_sub_url(WPSAPHTTPServer):
4347         def handle_upnp_info(self):
4348             self.wfile.write(gen_upnp_info(eventSubURL=None))
4349     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_event_sub_url,
4350                           no_event_url=True)
4351
4352 def test_ap_wps_er_http_proto_event_sub_url_dns(dev, apdev):
4353     """WPS ER HTTP protocol testing - DNS name in eventSubURL"""
4354     class WPSAPHTTPServer_event_sub_url_dns(WPSAPHTTPServer):
4355         def handle_upnp_info(self):
4356             self.wfile.write(gen_upnp_info(eventSubURL='http://example.com/wps_event'))
4357     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_event_sub_url_dns,
4358                           no_event_url=True)
4359
4360 def test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4361     """WPS ER HTTP protocol testing - subscribe OOM"""
4362     try:
4363         _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev)
4364     finally:
4365         dev[0].request("WPS_ER_STOP")
4366
4367 def _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4368     tests = [ (1, "http_client_url_parse"),
4369               (1, "wpabuf_alloc;wps_er_subscribe"),
4370               (1, "http_client_addr"),
4371               (1, "eloop_register_sock;http_client_addr"),
4372               (1, "eloop_register_timeout;http_client_addr") ]
4373     for count,func in tests:
4374         with alloc_fail(dev[0], count, func):
4375             server,sock = wps_er_start(dev[0], WPSAPHTTPServer)
4376             server.handle_request()
4377             server.handle_request()
4378             wps_er_stop(dev[0], sock, server, on_alloc_fail=True)
4379
4380 def test_ap_wps_er_http_proto_no_sid(dev, apdev):
4381     """WPS ER HTTP protocol testing - no SID"""
4382     class WPSAPHTTPServer_no_sid(WPSAPHTTPServer):
4383         def handle_wps_event(self):
4384             self.wfile.write(gen_wps_event(sid=None))
4385     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_sid)
4386
4387 def test_ap_wps_er_http_proto_invalid_sid_no_uuid(dev, apdev):
4388     """WPS ER HTTP protocol testing - invalid SID - no UUID"""
4389     class WPSAPHTTPServer_invalid_sid_no_uuid(WPSAPHTTPServer):
4390         def handle_wps_event(self):
4391             self.wfile.write(gen_wps_event(sid='FOO'))
4392     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_no_uuid)
4393
4394 def test_ap_wps_er_http_proto_invalid_sid_uuid(dev, apdev):
4395     """WPS ER HTTP protocol testing - invalid SID UUID"""
4396     class WPSAPHTTPServer_invalid_sid_uuid(WPSAPHTTPServer):
4397         def handle_wps_event(self):
4398             self.wfile.write(gen_wps_event(sid='uuid:FOO'))
4399     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_uuid)
4400
4401 def test_ap_wps_er_http_proto_subscribe_failing(dev, apdev):
4402     """WPS ER HTTP protocol testing - SUBSCRIBE failing"""
4403     class WPSAPHTTPServer_fail_subscribe(WPSAPHTTPServer):
4404         def handle_wps_event(self):
4405             payload = ""
4406             hdr = 'HTTP/1.1 404 Not Found\r\n' + \
4407                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4408                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4409                   'Connection: close\r\n' + \
4410                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4411                   'Timeout: Second-1801\r\n' + \
4412                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4413             self.wfile.write(hdr + payload)
4414     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_fail_subscribe)
4415
4416 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4417     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4418     class WPSAPHTTPServer_subscribe_invalid_response(WPSAPHTTPServer):
4419         def handle_wps_event(self):
4420             payload = ""
4421             hdr = 'HTTP/1.1 FOO\r\n' + \
4422                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4423                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4424                   'Connection: close\r\n' + \
4425                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4426                   'Timeout: Second-1801\r\n' + \
4427                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4428             self.wfile.write(hdr + payload)
4429     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_subscribe_invalid_response)
4430
4431 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4432     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4433     class WPSAPHTTPServer_invalid_m1(WPSAPHTTPServer):
4434         def handle_wps_control(self):
4435             payload = '''<?xml version="1.0"?>
4436 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
4437 <s:Body>
4438 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
4439 <NewDeviceInfo>Rk9P</NewDeviceInfo>
4440 </u:GetDeviceInfoResponse>
4441 </s:Body>
4442 </s:Envelope>
4443 '''
4444             self.wfile.write(gen_wps_control(payload_override=payload))
4445     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_m1, no_event_url=True)
4446
4447 def test_ap_wps_er_http_proto_upnp_info_no_device(dev, apdev):
4448     """WPS ER HTTP protocol testing - No device in UPnP info"""
4449     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4450         def handle_upnp_info(self):
4451             payload = '''<?xml version="1.0"?>
4452 <root xmlns="urn:schemas-upnp-org:device-1-0">
4453 <specVersion>
4454 <major>1</major>
4455 <minor>0</minor>
4456 </specVersion>
4457 </root>
4458 '''
4459             hdr = 'HTTP/1.1 200 OK\r\n' + \
4460                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4461                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4462                   'Connection: close\r\n' + \
4463                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4464                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4465             self.wfile.write(hdr + payload)
4466     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4467
4468 def test_ap_wps_er_http_proto_upnp_info_no_device_type(dev, apdev):
4469     """WPS ER HTTP protocol testing - No deviceType in UPnP info"""
4470     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4471         def handle_upnp_info(self):
4472             payload = '''<?xml version="1.0"?>
4473 <root xmlns="urn:schemas-upnp-org:device-1-0">
4474 <specVersion>
4475 <major>1</major>
4476 <minor>0</minor>
4477 </specVersion>
4478 <device>
4479 </device>
4480 </root>
4481 '''
4482             hdr = 'HTTP/1.1 200 OK\r\n' + \
4483                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4484                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4485                   'Connection: close\r\n' + \
4486                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4487                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4488             self.wfile.write(hdr + payload)
4489     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4490
4491 def test_ap_wps_er_http_proto_upnp_info_invalid_udn_uuid(dev, apdev):
4492     """WPS ER HTTP protocol testing - Invalid UDN UUID"""
4493     class WPSAPHTTPServer_invalid_udn_uuid(WPSAPHTTPServer):
4494         def handle_upnp_info(self):
4495             self.wfile.write(gen_upnp_info(udn='uuid:foo'))
4496     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_udn_uuid)
4497
4498 def test_ap_wps_er_http_proto_no_control_url(dev, apdev):
4499     """WPS ER HTTP protocol testing - no controlURL"""
4500     class WPSAPHTTPServer_no_control_url(WPSAPHTTPServer):
4501         def handle_upnp_info(self):
4502             self.wfile.write(gen_upnp_info(controlURL=None))
4503     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_control_url,
4504                           no_event_url=True)
4505
4506 def test_ap_wps_er_http_proto_control_url_dns(dev, apdev):
4507     """WPS ER HTTP protocol testing - DNS name in controlURL"""
4508     class WPSAPHTTPServer_control_url_dns(WPSAPHTTPServer):
4509         def handle_upnp_info(self):
4510             self.wfile.write(gen_upnp_info(controlURL='http://example.com/wps_control'))
4511     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_control_url_dns,
4512                           no_event_url=True)
4513
4514 def test_ap_wps_http_timeout(dev, apdev):
4515     """WPS AP/ER and HTTP timeout"""
4516     try:
4517         _test_ap_wps_http_timeout(dev, apdev)
4518     finally:
4519         dev[0].request("WPS_ER_STOP")
4520
4521 def _test_ap_wps_http_timeout(dev, apdev):
4522     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
4523     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
4524
4525     location = ssdp_get_location(ap_uuid)
4526     url = urlparse.urlparse(location)
4527     addr = (url.hostname, url.port)
4528     logger.debug("Open HTTP connection to hostapd, but do not complete request")
4529     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4530                          socket.IPPROTO_TCP)
4531     sock.connect(addr)
4532     sock.send("G")
4533
4534     class DummyServer(SocketServer.StreamRequestHandler):
4535         def handle(self):
4536             logger.debug("DummyServer - start 31 sec wait")
4537             time.sleep(31)
4538             logger.debug("DummyServer - wait done")
4539
4540     logger.debug("Start WPS ER")
4541     server,sock2 = wps_er_start(dev[0], DummyServer, max_age=40,
4542                                 wait_m_search=True)
4543
4544     logger.debug("Start server to accept, but not complete, HTTP connection from WPS ER")
4545     # This will wait for 31 seconds..
4546     server.handle_request()
4547
4548     logger.debug("Complete HTTP connection with hostapd (that should have already closed the connection)")
4549     try:
4550         sock.send("ET / HTTP/1.1\r\n\r\n")
4551         res = sock.recv(100)
4552         sock.close()
4553     except:
4554         pass
4555
4556 def test_ap_wps_er_url_parse(dev, apdev):
4557     """WPS ER and URL parsing special cases"""
4558     try:
4559         _test_ap_wps_er_url_parse(dev, apdev)
4560     finally:
4561         dev[0].request("WPS_ER_STOP")
4562
4563 def _test_ap_wps_er_url_parse(dev, apdev):
4564     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4565     sock.settimeout(1)
4566     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4567     sock.bind(("239.255.255.250", 1900))
4568     dev[0].request("WPS_ER_START ifname=lo")
4569     (msg,addr) = sock.recvfrom(1000)
4570     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4571     if "M-SEARCH" not in msg:
4572         raise Exception("Not an M-SEARCH")
4573     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://127.0.0.1\r\ncache-control:max-age=1\r\n\r\n", addr)
4574     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4575     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://127.0.0.1/:foo\r\ncache-control:max-age=1\r\n\r\n", addr)
4576     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4577     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://255.255.255.255:0/foo.xml\r\ncache-control:max-age=1\r\n\r\n", addr)
4578     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4579
4580     sock.close()
4581
4582 def test_ap_wps_er_link_update(dev, apdev):
4583     """WPS ER and link update special cases"""
4584     class WPSAPHTTPServer_link_update(WPSAPHTTPServer):
4585         def handle_upnp_info(self):
4586             self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4587     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update)
4588
4589     class WPSAPHTTPServer_link_update2(WPSAPHTTPServer):
4590         def handle_others(self, data):
4591             if "GET / " in data:
4592                 self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4593     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update2,
4594                           location_url='http://127.0.0.1:12345')
4595
4596 def test_ap_wps_er_http_client(dev, apdev):
4597     """WPS ER and HTTP client special cases"""
4598     with alloc_fail(dev[0], 1, "http_link_update"):
4599         run_wps_er_proto_test(dev[0], WPSAPHTTPServer)
4600
4601     with alloc_fail(dev[0], 1, "wpabuf_alloc;http_client_url"):
4602         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4603
4604     with alloc_fail(dev[0], 1, "httpread_create;http_client_tx_ready"):
4605         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4606
4607     class WPSAPHTTPServer_req_as_resp(WPSAPHTTPServer):
4608         def handle_upnp_info(self):
4609             self.wfile.write("GET / HTTP/1.1\r\n\r\n")
4610     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_req_as_resp,
4611                           no_event_url=True)
4612
4613 def test_ap_wps_init_oom(dev, apdev):
4614     """wps_init OOM cases"""
4615     ssid = "test-wps"
4616     appin = "12345670"
4617     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4618                "ap_pin": appin }
4619     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4620     pin = dev[0].wps_read_pin()
4621
4622     with alloc_fail(hapd, 1, "wps_init"):
4623         hapd.request("WPS_PIN any " + pin)
4624         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4625         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4626         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4627         if ev is None:
4628             raise Exception("No EAP failure reported")
4629         dev[0].request("WPS_CANCEL")
4630
4631     with alloc_fail(dev[0], 2, "wps_init"):
4632         hapd.request("WPS_PIN any " + pin)
4633         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4634         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4635         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4636         if ev is None:
4637             raise Exception("No EAP failure reported")
4638         dev[0].request("WPS_CANCEL")
4639
4640     with alloc_fail(dev[0], 2, "wps_init"):
4641         hapd.request("WPS_PBC")
4642         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4643         dev[0].request("WPS_PBC %s" % (apdev[0]['bssid']))
4644         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4645         if ev is None:
4646             raise Exception("No EAP failure reported")
4647         dev[0].request("WPS_CANCEL")
4648
4649     dev[0].dump_monitor()
4650     new_ssid = "wps-new-ssid"
4651     new_passphrase = "1234567890"
4652     with alloc_fail(dev[0], 3, "wps_init"):
4653         dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
4654                        new_passphrase, no_wait=True)
4655         ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4656         if ev is None:
4657             raise Exception("No EAP failure reported")
4658
4659     dev[0].flush_scan_cache()
4660
4661 def test_ap_wps_invalid_assoc_req_elem(dev, apdev):
4662     """WPS and invalid IE in Association Request frame"""
4663     ssid = "test-wps"
4664     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4665     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4666     pin = "12345670"
4667     hapd.request("WPS_PIN any " + pin)
4668     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4669     try:
4670         dev[0].request("VENDOR_ELEM_ADD 13 dd050050f20410")
4671         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4672         for i in range(5):
4673             ev = hapd.wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
4674             if ev and "vendor=14122" in ev:
4675                 break
4676         if ev is None or "vendor=14122" not in ev:
4677             raise Exception("EAP-WSC not started")
4678         dev[0].request("WPS_CANCEL")
4679     finally:
4680         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
4681
4682 def test_ap_wps_pbc_pin_mismatch(dev, apdev):
4683     """WPS PBC/PIN mismatch"""
4684     ssid = "test-wps"
4685     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4686     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4687     hapd.request("SET wps_version_number 0x10")
4688     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4689     hapd.request("WPS_PBC")
4690     pin = dev[0].wps_read_pin()
4691     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4692     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4693     if ev is None:
4694         raise Exception("Scan did not complete")
4695     dev[0].request("WPS_CANCEL")
4696
4697     hapd.request("WPS_CANCEL")
4698     dev[0].flush_scan_cache()
4699
4700 def test_ap_wps_ie_invalid(dev, apdev):
4701     """WPS PIN attempt with AP that has invalid WSC IE"""
4702     ssid = "test-wps"
4703     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4704                "vendor_elements": "dd050050f20410" }
4705     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4706     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4707     hostapd.add_ap(apdev[1]['ifname'], params)
4708     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4709     pin = dev[0].wps_read_pin()
4710     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4711     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4712     if ev is None:
4713         raise Exception("Scan did not complete")
4714     dev[0].request("WPS_CANCEL")
4715
4716 def test_ap_wps_scan_prio_order(dev, apdev):
4717     """WPS scan priority ordering"""
4718     ssid = "test-wps"
4719     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4720     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4721     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4722     hostapd.add_ap(apdev[1]['ifname'], params)
4723     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4724     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4725     pin = dev[0].wps_read_pin()
4726     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4727     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4728     if ev is None:
4729         raise Exception("Scan did not complete")
4730     dev[0].request("WPS_CANCEL")
4731
4732 def test_ap_wps_probe_req_ie_oom(dev, apdev):
4733     """WPS ProbeReq IE OOM"""
4734     ssid = "test-wps"
4735     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4736     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4737     pin = dev[0].wps_read_pin()
4738     hapd.request("WPS_PIN any " + pin)
4739     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4740     with alloc_fail(dev[0], 1, "wps_build_probe_req_ie"):
4741         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4742         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4743         if ev is None:
4744             raise Exception("Association not seen")
4745     dev[0].request("WPS_CANCEL")
4746
4747     with alloc_fail(dev[0], 1, "wps_ie_encapsulate"):
4748         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4749         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4750         if ev is None:
4751             raise Exception("Association not seen")
4752     dev[0].request("WPS_CANCEL")
4753
4754 def test_ap_wps_assoc_req_ie_oom(dev, apdev):
4755     """WPS AssocReq IE OOM"""
4756     ssid = "test-wps"
4757     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4758     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4759     pin = dev[0].wps_read_pin()
4760     hapd.request("WPS_PIN any " + pin)
4761     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4762     with alloc_fail(dev[0], 1, "wps_build_assoc_req_ie"):
4763         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4764         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4765         if ev is None:
4766             raise Exception("Association not seen")
4767     dev[0].request("WPS_CANCEL")
4768
4769 def test_ap_wps_assoc_resp_ie_oom(dev, apdev):
4770     """WPS AssocResp IE OOM"""
4771     ssid = "test-wps"
4772     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4773     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4774     pin = dev[0].wps_read_pin()
4775     hapd.request("WPS_PIN any " + pin)
4776     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4777     with alloc_fail(hapd, 1, "wps_build_assoc_resp_ie"):
4778         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4779         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4780         if ev is None:
4781             raise Exception("Association not seen")
4782     dev[0].request("WPS_CANCEL")
4783
4784 def test_ap_wps_bss_info_errors(dev, apdev):
4785     """WPS BSS info errors"""
4786     params = { "ssid": "1",
4787                "vendor_elements": "dd0e0050f20410440001ff101100010a" }
4788     hostapd.add_ap(apdev[0]['ifname'], params)
4789     params = { 'ssid': "2", "vendor_elements": "dd050050f20410" }
4790     hostapd.add_ap(apdev[1]['ifname'], params)
4791     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4792     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4793     bss = dev[0].get_bss(apdev[0]['bssid'])
4794     logger.info("BSS: " + str(bss))
4795     if "wps_state" in bss:
4796         raise Exception("Unexpected wps_state in BSS info")
4797     if 'wps_device_name' not in bss:
4798         raise Exception("No wps_device_name in BSS info")
4799     if bss['wps_device_name'] != '_':
4800         raise Exception("Unexpected wps_device_name value")
4801     bss = dev[0].get_bss(apdev[1]['bssid'])
4802     logger.info("BSS: " + str(bss))
4803
4804     with alloc_fail(dev[0], 1, "=wps_attr_text"):
4805         bss = dev[0].get_bss(apdev[0]['bssid'])
4806         logger.info("BSS(OOM): " + str(bss))
4807
4808 def wps_run_pbc_fail_ap(apdev, dev, hapd):
4809     hapd.request("WPS_PBC")
4810     dev.scan_for_bss(apdev['bssid'], freq="2412")
4811     dev.request("WPS_PBC " + apdev['bssid'])
4812     ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4813     if ev is None:
4814         raise Exception("No EAP failure reported")
4815     dev.request("WPS_CANCEL")
4816     dev.wait_disconnected()
4817     for i in range(5):
4818         try:
4819             dev.flush_scan_cache()
4820             break
4821         except Exception, e:
4822             if str(e).startswith("Failed to trigger scan"):
4823                 # Try again
4824                 time.sleep(1)
4825             else:
4826                 raise
4827
4828 def wps_run_pbc_fail(apdev, dev):
4829     hapd = wps_start_ap(apdev)
4830     wps_run_pbc_fail_ap(apdev, dev, hapd)
4831
4832 def test_ap_wps_pk_oom(dev, apdev):
4833     """WPS and public key OOM"""
4834     with alloc_fail(dev[0], 1, "wps_build_public_key"):
4835         wps_run_pbc_fail(apdev[0], dev[0])
4836
4837 def test_ap_wps_pk_oom_ap(dev, apdev):
4838     """WPS and public key OOM on AP"""
4839     hapd = wps_start_ap(apdev[0])
4840     with alloc_fail(hapd, 1, "wps_build_public_key"):
4841         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4842
4843 def test_ap_wps_encr_oom_ap(dev, apdev):
4844     """WPS and encrypted settings decryption OOM on AP"""
4845     hapd = wps_start_ap(apdev[0])
4846     pin = dev[0].wps_read_pin()
4847     hapd.request("WPS_PIN any " + pin)
4848     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4849     with alloc_fail(hapd, 1, "wps_decrypt_encr_settings"):
4850         dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " " + pin)
4851         ev = hapd.wait_event(["WPS-FAIL"], timeout=10)
4852         if ev is None:
4853             raise Exception("No WPS-FAIL reported")
4854         dev[0].request("WPS_CANCEL")
4855     dev[0].wait_disconnected()
4856
4857 def test_ap_wps_encr_no_random_ap(dev, apdev):
4858     """WPS and no random data available for encryption on AP"""
4859     hapd = wps_start_ap(apdev[0])
4860     with fail_test(hapd, 1, "os_get_random;wps_build_encr_settings"):
4861         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4862
4863 def test_ap_wps_e_hash_no_random_sta(dev, apdev):
4864     """WPS and no random data available for e-hash on STA"""
4865     with fail_test(dev[0], 1, "os_get_random;wps_build_e_hash"):
4866         wps_run_pbc_fail(apdev[0], dev[0])
4867
4868 def test_ap_wps_m1_no_random(dev, apdev):
4869     """WPS and no random for M1 on STA"""
4870     with fail_test(dev[0], 1, "os_get_random;wps_build_m1"):
4871         wps_run_pbc_fail(apdev[0], dev[0])
4872
4873 def test_ap_wps_m1_oom(dev, apdev):
4874     """WPS and OOM for M1 on STA"""
4875     with alloc_fail(dev[0], 1, "wps_build_m1"):
4876         wps_run_pbc_fail(apdev[0], dev[0])
4877
4878 def test_ap_wps_m3_oom(dev, apdev):
4879     """WPS and OOM for M3 on STA"""
4880     with alloc_fail(dev[0], 1, "wps_build_m3"):
4881         wps_run_pbc_fail(apdev[0], dev[0])
4882
4883 def test_ap_wps_m5_oom(dev, apdev):
4884     """WPS and OOM for M5 on STA"""
4885     hapd = wps_start_ap(apdev[0])
4886     hapd.request("WPS_PBC")
4887     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4888     for i in range(1, 3):
4889         with alloc_fail(dev[0], i, "wps_build_m5"):
4890             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4891             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4892             if ev is None:
4893                 raise Exception("No EAP failure reported")
4894             dev[0].request("WPS_CANCEL")
4895             dev[0].wait_disconnected()
4896     dev[0].flush_scan_cache()
4897
4898 def test_ap_wps_m5_no_random(dev, apdev):
4899     """WPS and no random for M5 on STA"""
4900     with fail_test(dev[0], 1,
4901                    "os_get_random;wps_build_encr_settings;wps_build_m5"):
4902         wps_run_pbc_fail(apdev[0], dev[0])
4903
4904 def test_ap_wps_m7_oom(dev, apdev):
4905     """WPS and OOM for M7 on STA"""
4906     hapd = wps_start_ap(apdev[0])
4907     hapd.request("WPS_PBC")
4908     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4909     for i in range(1, 3):
4910         with alloc_fail(dev[0], i, "wps_build_m7"):
4911             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4912             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4913             if ev is None:
4914                 raise Exception("No EAP failure reported")
4915             dev[0].request("WPS_CANCEL")
4916             dev[0].wait_disconnected()
4917     dev[0].flush_scan_cache()
4918
4919 def test_ap_wps_m7_no_random(dev, apdev):
4920     """WPS and no random for M7 on STA"""
4921     with fail_test(dev[0], 1,
4922                    "os_get_random;wps_build_encr_settings;wps_build_m7"):
4923         wps_run_pbc_fail(apdev[0], dev[0])
4924
4925 def test_ap_wps_wsc_done_oom(dev, apdev):
4926     """WPS and OOM for WSC_Done on STA"""
4927     with alloc_fail(dev[0], 1, "wps_build_wsc_done"):
4928         wps_run_pbc_fail(apdev[0], dev[0])
4929
4930 def test_ap_wps_random_psk_fail(dev, apdev):
4931     """WPS and no random for PSK on AP"""
4932     ssid = "test-wps"
4933     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
4934     appin = "12345670"
4935     try:
4936         os.remove(pskfile)
4937     except:
4938         pass
4939
4940     try:
4941         with open(pskfile, "w") as f:
4942             f.write("# WPA PSKs\n")
4943
4944         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4945                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
4946                    "rsn_pairwise": "CCMP", "ap_pin": appin,
4947                    "wpa_psk_file": pskfile }
4948         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4949
4950         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4951         with fail_test(hapd, 1, "os_get_random;wps_build_cred_network_key"):
4952             dev[0].request("WPS_REG " + apdev[0]['bssid'] + " " + appin)
4953             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4954             if ev is None:
4955                 raise Exception("No EAP failure reported")
4956             dev[0].request("WPS_CANCEL")
4957         dev[0].wait_disconnected()
4958
4959         with fail_test(hapd, 1, "os_get_random;wps_build_cred"):
4960             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4961
4962         with alloc_fail(hapd, 1, "wps_build_cred"):
4963             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4964
4965         with alloc_fail(hapd, 2, "wps_build_cred"):
4966             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4967     finally:
4968         os.remove(pskfile)
4969
4970 def wps_ext_eap_identity_req(dev, hapd, bssid):
4971     logger.debug("EAP-Identity/Request")
4972     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
4973     if ev is None:
4974         raise Exception("Timeout on EAPOL-TX from hostapd")
4975     res = dev.request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
4976     if "OK" not in res:
4977         raise Exception("EAPOL_RX to wpa_supplicant failed")
4978
4979 def wps_ext_eap_identity_resp(hapd, dev, addr):
4980     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
4981     if ev is None:
4982         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
4983     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
4984     if "OK" not in res:
4985         raise Exception("EAPOL_RX to hostapd failed")
4986
4987 def wps_ext_eap_wsc(dst, src, src_addr, msg):
4988     logger.debug(msg)
4989     ev = src.wait_event(["EAPOL-TX"], timeout=10)
4990     if ev is None:
4991         raise Exception("Timeout on EAPOL-TX")
4992     res = dst.request("EAPOL_RX " + src_addr + " " + ev.split(' ')[2])
4993     if "OK" not in res:
4994         raise Exception("EAPOL_RX failed")
4995
4996 def wps_start_ext(apdev, dev, pbc=False, pin=None):
4997     addr = dev.own_addr()
4998     bssid = apdev['bssid']
4999     ssid = "test-wps-conf"
5000     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5001                "wpa_passphrase": "12345678", "wpa": "2",
5002                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
5003     hapd = hostapd.add_ap(apdev['ifname'], params)
5004
5005     if pbc:
5006         hapd.request("WPS_PBC")
5007     else:
5008         if pin is None:
5009             pin = dev.wps_read_pin()
5010         hapd.request("WPS_PIN any " + pin)
5011     dev.scan_for_bss(bssid, freq="2412")
5012     hapd.request("SET ext_eapol_frame_io 1")
5013     dev.request("SET ext_eapol_frame_io 1")
5014
5015     if pbc:
5016         dev.request("WPS_PBC " + bssid)
5017     else:
5018         dev.request("WPS_PIN " + bssid + " " + pin)
5019     return addr,bssid,hapd
5020
5021 def wps_auth_corrupt(dst, src, addr):
5022     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5023     if ev is None:
5024         raise Exception("Timeout on EAPOL-TX")
5025     src.request("SET ext_eapol_frame_io 0")
5026     dst.request("SET ext_eapol_frame_io 0")
5027     msg = ev.split(' ')[2]
5028     if msg[-24:-16] != '10050008':
5029         raise Exception("Could not find Authenticator attribute")
5030     # Corrupt Authenticator value
5031     msg = msg[:-1] + '%x' % ((int(msg[-1], 16) + 1) % 16)
5032     res = dst.request("EAPOL_RX " + addr + " " + msg)
5033     if "OK" not in res:
5034         raise Exception("EAPOL_RX failed")
5035
5036 def wps_fail_finish(hapd, dev, fail_str):
5037     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5038     if ev is None:
5039         raise Exception("WPS-FAIL not indicated")
5040     if fail_str not in ev:
5041         raise Exception("Unexpected WPS-FAIL value: " + ev)
5042     dev.request("WPS_CANCEL")
5043     dev.wait_disconnected()
5044
5045 def wps_auth_corrupt_from_ap(dev, hapd, bssid, fail_str):
5046     wps_auth_corrupt(dev, hapd, bssid)
5047     wps_fail_finish(hapd, dev, fail_str)
5048
5049 def wps_auth_corrupt_to_ap(dev, hapd, addr, fail_str):
5050     wps_auth_corrupt(hapd, dev, addr)
5051     wps_fail_finish(hapd, dev, fail_str)
5052
5053 def test_ap_wps_authenticator_mismatch_m2(dev, apdev):
5054     """WPS and Authenticator attribute mismatch in M2"""
5055     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5056     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5057     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5058     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5059     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5060     logger.debug("M2")
5061     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=5")
5062
5063 def test_ap_wps_authenticator_mismatch_m3(dev, apdev):
5064     """WPS and Authenticator attribute mismatch in M3"""
5065     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5066     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5067     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5068     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5069     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5070     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5071     logger.debug("M3")
5072     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=7")
5073
5074 def test_ap_wps_authenticator_mismatch_m4(dev, apdev):
5075     """WPS and Authenticator attribute mismatch in M4"""
5076     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5077     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5078     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5079     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5080     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5081     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5082     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5083     logger.debug("M4")
5084     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=8")
5085
5086 def test_ap_wps_authenticator_mismatch_m5(dev, apdev):
5087     """WPS and Authenticator attribute mismatch in M5"""
5088     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5089     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5090     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5091     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5092     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5093     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5094     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5095     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5096     logger.debug("M5")
5097     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=9")
5098
5099 def test_ap_wps_authenticator_mismatch_m6(dev, apdev):
5100     """WPS and Authenticator attribute mismatch in M6"""
5101     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5102     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5103     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5104     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5105     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5106     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5107     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5108     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5109     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5110     logger.debug("M6")
5111     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=10")
5112
5113 def test_ap_wps_authenticator_mismatch_m7(dev, apdev):
5114     """WPS and Authenticator attribute mismatch in M7"""
5115     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5116     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5117     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5118     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5119     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5120     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5121     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5122     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5123     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5124     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5125     logger.debug("M7")
5126     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=11")
5127
5128 def test_ap_wps_authenticator_mismatch_m8(dev, apdev):
5129     """WPS and Authenticator attribute mismatch in M8"""
5130     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5131     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5132     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5133     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5134     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5135     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5136     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5137     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5138     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5139     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5140     wps_ext_eap_wsc(hapd, dev[0], addr, "M7")
5141     logger.debug("M8")
5142     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=12")
5143
5144 def test_ap_wps_authenticator_missing_m2(dev, apdev):
5145     """WPS and Authenticator attribute missing from M2"""
5146     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5147     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5148     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5149     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5150     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5151     logger.debug("M2")
5152     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5153     if ev is None:
5154         raise Exception("Timeout on EAPOL-TX")
5155     hapd.request("SET ext_eapol_frame_io 0")
5156     dev[0].request("SET ext_eapol_frame_io 0")
5157     msg = ev.split(' ')[2]
5158     if msg[-24:-16] != '10050008':
5159         raise Exception("Could not find Authenticator attribute")
5160     # Remove Authenticator value
5161     msg = msg[:-24]
5162     mlen = "%04x" % (int(msg[4:8], 16) - 12)
5163     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:]
5164     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5165     if "OK" not in res:
5166         raise Exception("EAPOL_RX failed")
5167     wps_fail_finish(hapd, dev[0], "msg=5")
5168
5169 def test_ap_wps_m2_dev_passwd_id_p2p(dev, apdev):
5170     """WPS and M2 with different Device Password ID (P2P)"""
5171     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5172     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5173     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5174     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5175     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5176     logger.debug("M2")
5177     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5178     if ev is None:
5179         raise Exception("Timeout on EAPOL-TX")
5180     hapd.request("SET ext_eapol_frame_io 0")
5181     dev[0].request("SET ext_eapol_frame_io 0")
5182     msg = ev.split(' ')[2]
5183     if msg[722:730] != '10120002':
5184         raise Exception("Could not find Device Password ID attribute")
5185     # Replace Device Password ID value. This will fail Authenticator check, but
5186     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5187     # log.
5188     msg = msg[0:730] + "0005" + msg[734:]
5189     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5190     if "OK" not in res:
5191         raise Exception("EAPOL_RX failed")
5192     wps_fail_finish(hapd, dev[0], "msg=5")
5193
5194 def test_ap_wps_m2_dev_passwd_id_change_pin_to_pbc(dev, apdev):
5195     """WPS and M2 with different Device Password ID (PIN to PBC)"""
5196     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5197     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5198     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5199     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5200     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5201     logger.debug("M2")
5202     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5203     if ev is None:
5204         raise Exception("Timeout on EAPOL-TX")
5205     hapd.request("SET ext_eapol_frame_io 0")
5206     dev[0].request("SET ext_eapol_frame_io 0")
5207     msg = ev.split(' ')[2]
5208     if msg[722:730] != '10120002':
5209         raise Exception("Could not find Device Password ID attribute")
5210     # Replace Device Password ID value (PIN --> PBC). This will be rejected.
5211     msg = msg[0:730] + "0004" + msg[734:]
5212     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5213     if "OK" not in res:
5214         raise Exception("EAPOL_RX failed")
5215     wps_fail_finish(hapd, dev[0], "msg=5")
5216
5217 def test_ap_wps_m2_dev_passwd_id_change_pbc_to_pin(dev, apdev):
5218     """WPS and M2 with different Device Password ID (PBC to PIN)"""
5219     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5220     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5221     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5222     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5223     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5224     logger.debug("M2")
5225     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5226     if ev is None:
5227         raise Exception("Timeout on EAPOL-TX")
5228     hapd.request("SET ext_eapol_frame_io 0")
5229     dev[0].request("SET ext_eapol_frame_io 0")
5230     msg = ev.split(' ')[2]
5231     if msg[722:730] != '10120002':
5232         raise Exception("Could not find Device Password ID attribute")
5233     # Replace Device Password ID value. This will fail Authenticator check, but
5234     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5235     # log.
5236     msg = msg[0:730] + "0000" + msg[734:]
5237     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5238     if "OK" not in res:
5239         raise Exception("EAPOL_RX failed")
5240     wps_fail_finish(hapd, dev[0], "msg=5")
5241     dev[0].flush_scan_cache()
5242
5243 def test_ap_wps_m2_missing_dev_passwd_id(dev, apdev):
5244     """WPS and M2 without Device Password ID"""
5245     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5246     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5247     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5248     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5249     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5250     logger.debug("M2")
5251     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5252     if ev is None:
5253         raise Exception("Timeout on EAPOL-TX")
5254     hapd.request("SET ext_eapol_frame_io 0")
5255     dev[0].request("SET ext_eapol_frame_io 0")
5256     msg = ev.split(' ')[2]
5257     if msg[722:730] != '10120002':
5258         raise Exception("Could not find Device Password ID attribute")
5259     # Remove Device Password ID value. This will fail Authenticator check, but
5260     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5261     # log.
5262     mlen = "%04x" % (int(msg[4:8], 16) - 6)
5263     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:722] + msg[734:]
5264     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5265     if "OK" not in res:
5266         raise Exception("EAPOL_RX failed")
5267     wps_fail_finish(hapd, dev[0], "msg=5")
5268
5269 def test_ap_wps_m2_missing_registrar_nonce(dev, apdev):
5270     """WPS and M2 without Registrar Nonce"""
5271     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5272     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5273     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5274     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5275     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5276     logger.debug("M2")
5277     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5278     if ev is None:
5279         raise Exception("Timeout on EAPOL-TX")
5280     hapd.request("SET ext_eapol_frame_io 0")
5281     dev[0].request("SET ext_eapol_frame_io 0")
5282     msg = ev.split(' ')[2]
5283     if msg[96:104] != '10390010':
5284         raise Exception("Could not find Registrar Nonce attribute")
5285     # Remove Registrar Nonce. This will fail Authenticator check, but
5286     # allows the code path in wps_process_registrar_nonce() to be checked from
5287     # the debug log.
5288     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5289     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:96] + msg[136:]
5290     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5291     if "OK" not in res:
5292         raise Exception("EAPOL_RX failed")
5293     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5294     if ev is None:
5295         raise Exception("Disconnect event not seen")
5296     dev[0].request("WPS_CANCEL")
5297     dev[0].flush_scan_cache()
5298
5299 def test_ap_wps_m2_missing_enrollee_nonce(dev, apdev):
5300     """WPS and M2 without Enrollee Nonce"""
5301     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5302     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5303     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5304     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5305     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5306     logger.debug("M2")
5307     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5308     if ev is None:
5309         raise Exception("Timeout on EAPOL-TX")
5310     hapd.request("SET ext_eapol_frame_io 0")
5311     dev[0].request("SET ext_eapol_frame_io 0")
5312     msg = ev.split(' ')[2]
5313     if msg[56:64] != '101a0010':
5314         raise Exception("Could not find enrollee Nonce attribute")
5315     # Remove Enrollee Nonce. This will fail Authenticator check, but
5316     # allows the code path in wps_process_enrollee_nonce() to be checked from
5317     # the debug log.
5318     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5319     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:56] + msg[96:]
5320     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5321     if "OK" not in res:
5322         raise Exception("EAPOL_RX failed")
5323     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5324     if ev is None:
5325         raise Exception("Disconnect event not seen")
5326     dev[0].request("WPS_CANCEL")
5327     dev[0].flush_scan_cache()
5328
5329 def test_ap_wps_m2_missing_uuid_r(dev, apdev):
5330     """WPS and M2 without UUID-R"""
5331     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5332     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5333     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5334     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5335     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5336     logger.debug("M2")
5337     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5338     if ev is None:
5339         raise Exception("Timeout on EAPOL-TX")
5340     hapd.request("SET ext_eapol_frame_io 0")
5341     dev[0].request("SET ext_eapol_frame_io 0")
5342     msg = ev.split(' ')[2]
5343     if msg[136:144] != '10480010':
5344         raise Exception("Could not find enrollee Nonce attribute")
5345     # Remove UUID-R. This will fail Authenticator check, but allows the code
5346     # path in wps_process_uuid_r() to be checked from the debug log.
5347     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5348     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:136] + msg[176:]
5349     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5350     if "OK" not in res:
5351         raise Exception("EAPOL_RX failed")
5352     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5353     if ev is None:
5354         raise Exception("Disconnect event not seen")
5355     dev[0].request("WPS_CANCEL")
5356     dev[0].flush_scan_cache()
5357
5358 def test_ap_wps_m2_invalid(dev, apdev):
5359     """WPS and M2 parsing failure"""
5360     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5361     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5362     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5363     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5364     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5365     logger.debug("M2")
5366     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5367     if ev is None:
5368         raise Exception("Timeout on EAPOL-TX")
5369     hapd.request("SET ext_eapol_frame_io 0")
5370     dev[0].request("SET ext_eapol_frame_io 0")
5371     msg = ev.split(' ')[2]
5372     if msg[136:144] != '10480010':
5373         raise Exception("Could not find enrollee Nonce attribute")
5374     # Remove UUID-R. This will fail Authenticator check, but allows the code
5375     # path in wps_process_uuid_r() to be checked from the debug log.
5376     mlen = "%04x" % (int(msg[4:8], 16) - 1)
5377     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:-2]
5378     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5379     if "OK" not in res:
5380         raise Exception("EAPOL_RX failed")
5381     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5382     if ev is None:
5383         raise Exception("Disconnect event not seen")
5384     dev[0].request("WPS_CANCEL")
5385     dev[0].flush_scan_cache()
5386
5387 def test_ap_wps_m2_missing_msg_type(dev, apdev):
5388     """WPS and M2 without Message Type"""
5389     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5390     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5391     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5392     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5393     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5394     logger.debug("M2")
5395     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5396     if ev is None:
5397         raise Exception("Timeout on EAPOL-TX")
5398     hapd.request("SET ext_eapol_frame_io 0")
5399     dev[0].request("SET ext_eapol_frame_io 0")
5400     msg = ev.split(' ')[2]
5401     if msg[46:54] != '10220001':
5402         raise Exception("Could not find Message Type attribute")
5403     # Remove Message Type. This will fail Authenticator check, but allows the
5404     # code path in wps_process_wsc_msg() to be checked from the debug log.
5405     mlen = "%04x" % (int(msg[4:8], 16) - 5)
5406     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:46] + msg[56:]
5407     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5408     if "OK" not in res:
5409         raise Exception("EAPOL_RX failed")
5410     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5411     if ev is None:
5412         raise Exception("Disconnect event not seen")
5413     dev[0].request("WPS_CANCEL")
5414     dev[0].flush_scan_cache()
5415
5416 def test_ap_wps_m2_unknown_msg_type(dev, apdev):
5417     """WPS and M2 but unknown Message Type"""
5418     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5419     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5420     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5421     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5422     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5423     logger.debug("M2")
5424     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5425     if ev is None:
5426         raise Exception("Timeout on EAPOL-TX")
5427     hapd.request("SET ext_eapol_frame_io 0")
5428     dev[0].request("SET ext_eapol_frame_io 0")
5429     msg = ev.split(' ')[2]
5430     if msg[46:54] != '10220001':
5431         raise Exception("Could not find Message Type attribute")
5432     # Replace Message Type value. This will be rejected.
5433     msg = msg[0:54] + "00" + msg[56:]
5434     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5435     if "OK" not in res:
5436         raise Exception("EAPOL_RX failed")
5437     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5438     if ev is None:
5439         raise Exception("Disconnect event not seen")
5440     dev[0].request("WPS_CANCEL")
5441     dev[0].flush_scan_cache()
5442
5443 def test_ap_wps_m2_unknown_opcode(dev, apdev):
5444     """WPS and M2 but unknown opcode"""
5445     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5446     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5447     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5448     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5449     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5450     logger.debug("M2")
5451     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5452     if ev is None:
5453         raise Exception("Timeout on EAPOL-TX")
5454     hapd.request("SET ext_eapol_frame_io 0")
5455     dev[0].request("SET ext_eapol_frame_io 0")
5456     msg = ev.split(' ')[2]
5457     # Replace opcode. This will be discarded in EAP-WSC processing.
5458     msg = msg[0:32] + "00" + msg[34:]
5459     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5460     if "OK" not in res:
5461         raise Exception("EAPOL_RX failed")
5462     dev[0].request("WPS_CANCEL")
5463     dev[0].wait_disconnected()
5464     dev[0].flush_scan_cache()
5465
5466 def test_ap_wps_m2_unknown_opcode2(dev, apdev):
5467     """WPS and M2 but unknown opcode (WSC_Start)"""
5468     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5469     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5470     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5471     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5472     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5473     logger.debug("M2")
5474     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5475     if ev is None:
5476         raise Exception("Timeout on EAPOL-TX")
5477     hapd.request("SET ext_eapol_frame_io 0")
5478     dev[0].request("SET ext_eapol_frame_io 0")
5479     msg = ev.split(' ')[2]
5480     # Replace opcode. This will be discarded in EAP-WSC processing.
5481     msg = msg[0:32] + "01" + msg[34:]
5482     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5483     if "OK" not in res:
5484         raise Exception("EAPOL_RX failed")
5485     dev[0].request("WPS_CANCEL")
5486     dev[0].wait_disconnected()
5487     dev[0].flush_scan_cache()
5488
5489 def test_ap_wps_m2_unknown_opcode3(dev, apdev):
5490     """WPS and M2 but unknown opcode (WSC_Done)"""
5491     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5492     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5493     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5494     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5495     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5496     logger.debug("M2")
5497     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5498     if ev is None:
5499         raise Exception("Timeout on EAPOL-TX")
5500     hapd.request("SET ext_eapol_frame_io 0")
5501     dev[0].request("SET ext_eapol_frame_io 0")
5502     msg = ev.split(' ')[2]
5503     # Replace opcode. This will be discarded in WPS Enrollee processing.
5504     msg = msg[0:32] + "05" + msg[34:]
5505     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5506     if "OK" not in res:
5507         raise Exception("EAPOL_RX failed")
5508     dev[0].request("WPS_CANCEL")
5509     dev[0].wait_disconnected()
5510     dev[0].flush_scan_cache()
5511
5512 def wps_m2_but_other(dev, apdev, title, msgtype):
5513     addr,bssid,hapd = wps_start_ext(apdev, dev)
5514     wps_ext_eap_identity_req(dev, hapd, bssid)
5515     wps_ext_eap_identity_resp(hapd, dev, addr)
5516     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5517     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5518     logger.debug(title)
5519     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5520     if ev is None:
5521         raise Exception("Timeout on EAPOL-TX")
5522     hapd.request("SET ext_eapol_frame_io 0")
5523     dev.request("SET ext_eapol_frame_io 0")
5524     msg = ev.split(' ')[2]
5525     if msg[46:54] != '10220001':
5526         raise Exception("Could not find Message Type attribute")
5527     # Replace Message Type value. This will be rejected.
5528     msg = msg[0:54] + msgtype + msg[56:]
5529     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5530     if "OK" not in res:
5531         raise Exception("EAPOL_RX failed")
5532     ev = dev.wait_event(["WPS-FAIL"], timeout=5)
5533     if ev is None:
5534         raise Exception("WPS-FAIL event not seen")
5535     dev.request("WPS_CANCEL")
5536     dev.wait_disconnected()
5537
5538 def wps_m4_but_other(dev, apdev, title, msgtype):
5539     addr,bssid,hapd = wps_start_ext(apdev, dev)
5540     wps_ext_eap_identity_req(dev, hapd, bssid)
5541     wps_ext_eap_identity_resp(hapd, dev, addr)
5542     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5543     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5544     wps_ext_eap_wsc(dev, hapd, bssid, "M2")
5545     wps_ext_eap_wsc(hapd, dev, addr, "M3")
5546     logger.debug(title)
5547     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5548     if ev is None:
5549         raise Exception("Timeout on EAPOL-TX")
5550     hapd.request("SET ext_eapol_frame_io 0")
5551     dev.request("SET ext_eapol_frame_io 0")
5552     msg = ev.split(' ')[2]
5553     if msg[46:54] != '10220001':
5554         raise Exception("Could not find Message Type attribute")
5555     # Replace Message Type value. This will be rejected.
5556     msg = msg[0:54] + msgtype + msg[56:]
5557     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5558     if "OK" not in res:
5559         raise Exception("EAPOL_RX failed")
5560     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5561     if ev is None:
5562         raise Exception("WPS-FAIL event not seen")
5563     dev.request("WPS_CANCEL")
5564     dev.wait_disconnected()
5565
5566 def test_ap_wps_m2_msg_type_m4(dev, apdev):
5567     """WPS and M2 but Message Type M4"""
5568     wps_m2_but_other(dev[0], apdev[0], "M2/M4", "08")
5569
5570 def test_ap_wps_m2_msg_type_m6(dev, apdev):
5571     """WPS and M2 but Message Type M6"""
5572     wps_m2_but_other(dev[0], apdev[0], "M2/M6", "0a")
5573
5574 def test_ap_wps_m2_msg_type_m8(dev, apdev):
5575     """WPS and M2 but Message Type M8"""
5576     wps_m2_but_other(dev[0], apdev[0], "M2/M8", "0c")
5577
5578 def test_ap_wps_m4_msg_type_m2(dev, apdev):
5579     """WPS and M4 but Message Type M2"""
5580     wps_m4_but_other(dev[0], apdev[0], "M4/M2", "05")
5581
5582 def test_ap_wps_m4_msg_type_m2d(dev, apdev):
5583     """WPS and M4 but Message Type M2D"""
5584     wps_m4_but_other(dev[0], apdev[0], "M4/M2D", "06")
5585
5586 def test_ap_wps_config_methods(dev, apdev):
5587     """WPS configuration method parsing"""
5588     ssid = "test-wps-conf"
5589     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5590                "wpa_passphrase": "12345678", "wpa": "2",
5591                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5592                "config_methods": "ethernet display ext_nfc_token int_nfc_token physical_display physical_push_button" }
5593     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
5594     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5595                "wpa_passphrase": "12345678", "wpa": "2",
5596                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5597                "config_methods": "display push_button" }
5598     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
5599
5600 def test_ap_wps_set_selected_registrar_proto(dev, apdev):
5601     """WPS UPnP SetSelectedRegistrar protocol testing"""
5602     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5603     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5604
5605     location = ssdp_get_location(ap_uuid)
5606     urls = upnp_get_urls(location)
5607     eventurl = urlparse.urlparse(urls['event_sub_url'])
5608     ctrlurl = urlparse.urlparse(urls['control_url'])
5609     url = urlparse.urlparse(location)
5610     conn = httplib.HTTPConnection(url.netloc)
5611
5612     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
5613         def handle(self):
5614             data = self.rfile.readline().strip()
5615             logger.debug(data)
5616             self.wfile.write(gen_wps_event())
5617
5618     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
5619     server.timeout = 1
5620
5621     headers = { "callback": '<http://127.0.0.1:12345/event>',
5622                 "NT": "upnp:event",
5623                 "timeout": "Second-1234" }
5624     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
5625     resp = conn.getresponse()
5626     if resp.status != 200:
5627         raise Exception("Unexpected HTTP response: %d" % resp.status)
5628     sid = resp.getheader("sid")
5629     logger.debug("Subscription SID " + sid)
5630     server.handle_request()
5631
5632     tests = [ (500, "10"),
5633               (200, "104a000110" + "1041000101" + "101200020000" +
5634                "105300023148" +
5635                "1049002c00372a0001200124111111111111222222222222333333333333444444444444555555555555666666666666" +
5636                "10480010362db47ba53a519188fb5458b986b2e4"),
5637               (200, "104a000110" + "1041000100" + "101200020000" +
5638                "105300020000"),
5639               (200, "104a000110" + "1041000100"),
5640               (200, "104a000110") ]
5641     for status,test in tests:
5642         tlvs = binascii.unhexlify(test)
5643         newmsg = base64.b64encode(tlvs)
5644         msg = '<?xml version="1.0"?>\n'
5645         msg += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
5646         msg += '<s:Body>'
5647         msg += '<u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">'
5648         msg += '<NewMessage>'
5649         msg += newmsg
5650         msg += "</NewMessage></u:SetSelectedRegistrar></s:Body></s:Envelope>"
5651         headers = { "Content-type": 'text/xml; charset="utf-8"' }
5652         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
5653         conn.request("POST", ctrlurl.path, msg, headers)
5654         resp = conn.getresponse()
5655         if resp.status != status:
5656             raise Exception("Unexpected HTTP response: %d (expected %d)" % (resp.status, status))
5657
5658 def test_ap_wps_adv_oom(dev, apdev):
5659     """WPS AP and advertisement OOM"""
5660     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5661     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5662
5663     with alloc_fail(hapd, 1, "=msearchreply_state_machine_start"):
5664         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5665                           no_recv=True)
5666         time.sleep(0.2)
5667
5668     with alloc_fail(hapd, 1, "eloop_register_timeout;msearchreply_state_machine_start"):
5669         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5670                           no_recv=True)
5671         time.sleep(0.2)
5672
5673     with alloc_fail(hapd, 1,
5674                     "next_advertisement;advertisement_state_machine_stop"):
5675         hapd.disable()
5676
5677     with alloc_fail(hapd, 1, "ssdp_listener_start"):
5678         if "FAIL" not in hapd.request("ENABLE"):
5679             raise Exception("ENABLE succeeded during OOM")
5680
5681 def test_wps_config_methods(dev):
5682     """WPS config method update"""
5683     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
5684     wpas.interface_add("wlan5")
5685     if "OK" not in wpas.request("SET config_methods display label"):
5686         raise Exception("Failed to set config_methods")
5687     if wpas.request("GET config_methods").strip() != "display label":
5688         raise Exception("config_methods were not updated")
5689     if "OK" not in wpas.request("SET config_methods "):
5690         raise Exception("Failed to clear config_methods")
5691     if wpas.request("GET config_methods").strip() != "":
5692         raise Exception("config_methods were not cleared")
5693
5694 WPS_VENDOR_ID_WFA = 14122
5695 WPS_VENDOR_TYPE = 1
5696
5697 # EAP-WSC Op-Code values
5698 WSC_Start = 0x01
5699 WSC_ACK = 0x02
5700 WSC_NACK = 0x03
5701 WSC_MSG = 0x04
5702 WSC_Done = 0x05
5703 WSC_FRAG_ACK = 0x06
5704
5705 ATTR_AP_CHANNEL = 0x1001
5706 ATTR_ASSOC_STATE = 0x1002
5707 ATTR_AUTH_TYPE = 0x1003
5708 ATTR_AUTH_TYPE_FLAGS = 0x1004
5709 ATTR_AUTHENTICATOR = 0x1005
5710 ATTR_CONFIG_METHODS = 0x1008
5711 ATTR_CONFIG_ERROR = 0x1009
5712 ATTR_CONFIRM_URL4 = 0x100a
5713 ATTR_CONFIRM_URL6 = 0x100b
5714 ATTR_CONN_TYPE = 0x100c
5715 ATTR_CONN_TYPE_FLAGS = 0x100d
5716 ATTR_CRED = 0x100e
5717 ATTR_ENCR_TYPE = 0x100f
5718 ATTR_ENCR_TYPE_FLAGS = 0x1010
5719 ATTR_DEV_NAME = 0x1011
5720 ATTR_DEV_PASSWORD_ID = 0x1012
5721 ATTR_E_HASH1 = 0x1014
5722 ATTR_E_HASH2 = 0x1015
5723 ATTR_E_SNONCE1 = 0x1016
5724 ATTR_E_SNONCE2 = 0x1017
5725 ATTR_ENCR_SETTINGS = 0x1018
5726 ATTR_ENROLLEE_NONCE = 0x101a
5727 ATTR_FEATURE_ID = 0x101b
5728 ATTR_IDENTITY = 0x101c
5729 ATTR_IDENTITY_PROOF = 0x101d
5730 ATTR_KEY_WRAP_AUTH = 0x101e
5731 ATTR_KEY_ID = 0x101f
5732 ATTR_MAC_ADDR = 0x1020
5733 ATTR_MANUFACTURER = 0x1021
5734 ATTR_MSG_TYPE = 0x1022
5735 ATTR_MODEL_NAME = 0x1023
5736 ATTR_MODEL_NUMBER = 0x1024
5737 ATTR_NETWORK_INDEX = 0x1026
5738 ATTR_NETWORK_KEY = 0x1027
5739 ATTR_NETWORK_KEY_INDEX = 0x1028
5740 ATTR_NEW_DEVICE_NAME = 0x1029
5741 ATTR_NEW_PASSWORD = 0x102a
5742 ATTR_OOB_DEVICE_PASSWORD = 0x102c
5743 ATTR_OS_VERSION = 0x102d
5744 ATTR_POWER_LEVEL = 0x102f
5745 ATTR_PSK_CURRENT = 0x1030
5746 ATTR_PSK_MAX = 0x1031
5747 ATTR_PUBLIC_KEY = 0x1032
5748 ATTR_RADIO_ENABLE = 0x1033
5749 ATTR_REBOOT = 0x1034
5750 ATTR_REGISTRAR_CURRENT = 0x1035
5751 ATTR_REGISTRAR_ESTABLISHED = 0x1036
5752 ATTR_REGISTRAR_LIST = 0x1037
5753 ATTR_REGISTRAR_MAX = 0x1038
5754 ATTR_REGISTRAR_NONCE = 0x1039
5755 ATTR_REQUEST_TYPE = 0x103a
5756 ATTR_RESPONSE_TYPE = 0x103b
5757 ATTR_RF_BANDS = 0x103c
5758 ATTR_R_HASH1 = 0x103d
5759 ATTR_R_HASH2 = 0x103e
5760 ATTR_R_SNONCE1 = 0x103f
5761 ATTR_R_SNONCE2 = 0x1040
5762 ATTR_SELECTED_REGISTRAR = 0x1041
5763 ATTR_SERIAL_NUMBER = 0x1042
5764 ATTR_WPS_STATE = 0x1044
5765 ATTR_SSID = 0x1045
5766 ATTR_TOTAL_NETWORKS = 0x1046
5767 ATTR_UUID_E = 0x1047
5768 ATTR_UUID_R = 0x1048
5769 ATTR_VENDOR_EXT = 0x1049
5770 ATTR_VERSION = 0x104a
5771 ATTR_X509_CERT_REQ = 0x104b
5772 ATTR_X509_CERT = 0x104c
5773 ATTR_EAP_IDENTITY = 0x104d
5774 ATTR_MSG_COUNTER = 0x104e
5775 ATTR_PUBKEY_HASH = 0x104f
5776 ATTR_REKEY_KEY = 0x1050
5777 ATTR_KEY_LIFETIME = 0x1051
5778 ATTR_PERMITTED_CFG_METHODS = 0x1052
5779 ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053
5780 ATTR_PRIMARY_DEV_TYPE = 0x1054
5781 ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055
5782 ATTR_PORTABLE_DEV = 0x1056
5783 ATTR_AP_SETUP_LOCKED = 0x1057
5784 ATTR_APPLICATION_EXT = 0x1058
5785 ATTR_EAP_TYPE = 0x1059
5786 ATTR_IV = 0x1060
5787 ATTR_KEY_PROVIDED_AUTO = 0x1061
5788 ATTR_802_1X_ENABLED = 0x1062
5789 ATTR_APPSESSIONKEY = 0x1063
5790 ATTR_WEPTRANSMITKEY = 0x1064
5791 ATTR_REQUESTED_DEV_TYPE = 0x106a
5792
5793 # Message Type
5794 WPS_Beacon = 0x01
5795 WPS_ProbeRequest = 0x02
5796 WPS_ProbeResponse = 0x03
5797 WPS_M1 = 0x04
5798 WPS_M2 = 0x05
5799 WPS_M2D = 0x06
5800 WPS_M3 = 0x07
5801 WPS_M4 = 0x08
5802 WPS_M5 = 0x09
5803 WPS_M6 = 0x0a
5804 WPS_M7 = 0x0b
5805 WPS_M8 = 0x0c
5806 WPS_WSC_ACK = 0x0d
5807 WPS_WSC_NACK = 0x0e
5808 WPS_WSC_DONE = 0x0f
5809
5810 def get_wsc_msg(dev):
5811     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
5812     if ev is None:
5813         raise Exception("Timeout on EAPOL-TX")
5814     data = binascii.unhexlify(ev.split(' ')[2])
5815     msg = {}
5816
5817     # Parse EAPOL header
5818     if len(data) < 4:
5819         raise Exception("No room for EAPOL header")
5820     version,type,length = struct.unpack('>BBH', data[0:4])
5821     msg['eapol_version'] = version
5822     msg['eapol_type'] = type
5823     msg['eapol_length'] = length
5824     data = data[4:]
5825     if length != len(data):
5826         raise Exception("EAPOL header length mismatch (%d != %d)" % (length, len(data)))
5827     if type != 0:
5828         raise Exception("Unexpected EAPOL header type: %d" % type)
5829
5830     # Parse EAP header
5831     if len(data) < 4:
5832         raise Exception("No room for EAP header")
5833     code,identifier,length = struct.unpack('>BBH', data[0:4])
5834     msg['eap_code'] = code
5835     msg['eap_identifier'] = identifier
5836     msg['eap_length'] = length
5837     data = data[4:]
5838     if msg['eapol_length'] != msg['eap_length']:
5839         raise Exception("EAP header length mismatch (%d != %d)" % (msg['eapol_length'], length))
5840
5841     # Parse EAP expanded header
5842     if len(data) < 1:
5843         raise Exception("No EAP type included")
5844     msg['eap_type'], = struct.unpack('B', data[0])
5845     data = data[1:]
5846
5847     if msg['eap_type'] == 254:
5848         if len(data) < 3 + 4:
5849             raise Exception("Truncated EAP expanded header")
5850         msg['eap_vendor_id'], msg['eap_vendor_type'] = struct.unpack('>LL', '\0' + data[0:7])
5851         data = data[7:]
5852     else:
5853         raise Exception("Unexpected EAP type")
5854
5855     if msg['eap_vendor_id'] != WPS_VENDOR_ID_WFA:
5856         raise Exception("Unexpected Vendor-Id")
5857     if msg['eap_vendor_type'] != WPS_VENDOR_TYPE:
5858         raise Exception("Unexpected Vendor-Type")
5859
5860     # Parse EAP-WSC header
5861     if len(data) < 2:
5862         raise Exception("Truncated EAP-WSC header")
5863     msg['wsc_opcode'], msg['wsc_flags'] = struct.unpack('BB', data[0:2])
5864     data = data[2:]
5865
5866     # Parse WSC attributes
5867     msg['raw_attrs'] = data
5868     attrs = {}
5869     while len(data) > 0:
5870         if len(data) < 4:
5871             raise Exception("Truncated attribute header")
5872         attr,length = struct.unpack('>HH', data[0:4])
5873         data = data[4:]
5874         if length > len(data):
5875             raise Exception("Truncated attribute 0x%04x" % attr)
5876         attrs[attr] = data[0:length]
5877         data = data[length:]
5878     msg['wsc_attrs'] = attrs
5879
5880     if ATTR_MSG_TYPE in attrs:
5881         msg['wsc_msg_type'], = struct.unpack('B', attrs[ATTR_MSG_TYPE])
5882
5883     return msg
5884
5885 def recv_wsc_msg(dev, opcode, msg_type):
5886     msg = get_wsc_msg(dev)
5887     if msg['wsc_opcode'] != opcode or msg['wsc_msg_type'] != msg_type:
5888         raise Exception("Unexpected Op-Code/MsgType")
5889     return msg, msg['wsc_attrs'], msg['raw_attrs']
5890
5891 def build_wsc_attr(attr, payload):
5892     return struct.pack('>HH', attr, len(payload)) + payload
5893
5894 def build_attr_msg_type(msg_type):
5895     return build_wsc_attr(ATTR_MSG_TYPE, struct.pack('B', msg_type))
5896
5897 def build_eap_wsc(eap_code, eap_id, payload, opcode=WSC_MSG):
5898     length = 4 + 8 + 2 + len(payload)
5899     # EAPOL header
5900     msg = struct.pack('>BBH', 2, 0, length)
5901     # EAP header
5902     msg += struct.pack('>BBH', eap_code, eap_id, length)
5903     # EAP expanded header for EAP-WSC
5904     msg += struct.pack('B', 254)
5905     msg += struct.pack('>L', WPS_VENDOR_ID_WFA)[1:4]
5906     msg += struct.pack('>L', WPS_VENDOR_TYPE)
5907     # EAP-WSC header
5908     msg += struct.pack('BB', opcode, 0)
5909     # WSC attributes
5910     msg += payload
5911     return msg
5912
5913 def build_eap_success(eap_id):
5914     length = 4
5915     # EAPOL header
5916     msg = struct.pack('>BBH', 2, 0, length)
5917     # EAP header
5918     msg += struct.pack('>BBH', 3, eap_id, length)
5919     return msg
5920
5921 def build_eap_failure(eap_id):
5922     length = 4
5923     # EAPOL header
5924     msg = struct.pack('>BBH', 2, 0, length)
5925     # EAP header
5926     msg += struct.pack('>BBH', 4, eap_id, length)
5927     return msg
5928
5929 def send_wsc_msg(dev, src, msg):
5930     res = dev.request("EAPOL_RX " + src + " " + binascii.hexlify(msg))
5931     if "OK" not in res:
5932         raise Exception("EAPOL_RX failed")
5933
5934 group_5_prime = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF
5935 group_5_generator = 2
5936
5937 def wsc_kdf(key, label, bits):
5938     result = ''
5939     i = 1
5940     while len(result) * 8 < bits:
5941         data = struct.pack('>L', i) + label + struct.pack('>L', bits)
5942         m = hmac.new(key, data, hashlib.sha256)
5943         result += m.digest()
5944         i += 1
5945     return result[0:bits / 8]
5946
5947 def wsc_keys(kdk):
5948     keys = wsc_kdf(kdk, "Wi-Fi Easy and Secure Key Derivation", 640)
5949     authkey = keys[0:32]
5950     keywrapkey = keys[32:48]
5951     emsk = keys[48:80]
5952     return authkey,keywrapkey,emsk
5953
5954 def wsc_dev_pw_half_psk(authkey, dev_pw):
5955     m = hmac.new(authkey, dev_pw, hashlib.sha256)
5956     return m.digest()[0:16]
5957
5958 def wsc_dev_pw_psk(authkey, dev_pw):
5959     dev_pw_1 = dev_pw[0:len(dev_pw) / 2]
5960     dev_pw_2 = dev_pw[len(dev_pw) / 2:]
5961     psk1 = wsc_dev_pw_half_psk(authkey, dev_pw_1)
5962     psk2 = wsc_dev_pw_half_psk(authkey, dev_pw_2)
5963     return psk1,psk2
5964
5965 def build_attr_authenticator(authkey, prev_msg, curr_msg):
5966     m = hmac.new(authkey, prev_msg + curr_msg, hashlib.sha256)
5967     auth = m.digest()[0:8]
5968     return build_wsc_attr(ATTR_AUTHENTICATOR, auth)
5969
5970 def build_attr_encr_settings(authkey, keywrapkey, data):
5971     m = hmac.new(authkey, data, hashlib.sha256)
5972     kwa = m.digest()[0:8]
5973     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
5974     iv = 16*'\x99'
5975     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
5976     pad_len = 16 - len(data) % 16
5977     ps = pad_len * struct.pack('B', pad_len)
5978     data += ps
5979     wrapped = aes.encrypt(data)
5980     return build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
5981
5982 def decrypt_attr_encr_settings(authkey, keywrapkey, data):
5983     if len(data) < 32 or len(data) % 16 != 0:
5984         raise Exception("Unexpected Encrypted Settings length: %d" % len(data))
5985     iv = data[0:16]
5986     encr = data[16:]
5987     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
5988     decrypted = aes.decrypt(encr)
5989     pad_len, = struct.unpack('B', decrypted[-1])
5990     if pad_len > len(decrypted):
5991         raise Exception("Invalid padding in Encrypted Settings")
5992     for i in range(-pad_len, -1):
5993         if decrypted[i] != decrypted[-1]:
5994             raise Exception("Invalid PS value in Encrypted Settings")
5995     
5996     decrypted = decrypted[0:len(decrypted) - pad_len]
5997     if len(decrypted) < 12:
5998         raise Exception("Truncated Encrypted Settings plaintext")
5999     kwa = decrypted[-12:]
6000     attr,length = struct.unpack(">HH", kwa[0:4])
6001     if attr != ATTR_KEY_WRAP_AUTH or length != 8:
6002         raise Exception("Invalid KWA header")
6003     kwa = kwa[4:]
6004     decrypted = decrypted[0:len(decrypted) - 12]
6005
6006     m = hmac.new(authkey, decrypted, hashlib.sha256)
6007     calc_kwa = m.digest()[0:8]
6008     if kwa != calc_kwa:
6009         raise Exception("KWA mismatch")
6010
6011     return decrypted
6012
6013 def zeropad_str(val, pad_len):
6014     while len(val) < pad_len * 2:
6015         val = '0' + val
6016     return val
6017
6018 def wsc_dh_init():
6019     # For now, use a hardcoded private key. In theory, this is supposed to be
6020     # randomly selected.
6021     own_private = 0x123456789
6022     own_public = pow(group_5_generator, own_private, group_5_prime)
6023     pk = binascii.unhexlify(zeropad_str(format(own_public, '02x'), 192))
6024     return own_private, pk
6025
6026 def wsc_dh_kdf(peer_pk, own_private, mac_addr, e_nonce, r_nonce):
6027     peer_public = long(binascii.hexlify(peer_pk), 16)
6028     if peer_public < 2 or peer_public >= group_5_prime:
6029         raise Exception("Invalid peer public key")
6030     if pow(peer_public, (group_5_prime - 1) / 2, group_5_prime) != 1:
6031         raise Exception("Unexpected Legendre symbol for peer public key")
6032
6033     shared_secret = pow(peer_public, own_private, group_5_prime)
6034     ss = zeropad_str(format(shared_secret, "02x"), 192)
6035     logger.debug("DH shared secret: " + ss)
6036
6037     dhkey = hashlib.sha256(binascii.unhexlify(ss)).digest()
6038     logger.debug("DHKey: " + binascii.hexlify(dhkey))
6039
6040     m = hmac.new(dhkey, e_nonce + mac_addr + r_nonce, hashlib.sha256)
6041     kdk = m.digest()
6042     logger.debug("KDK: " + binascii.hexlify(kdk))
6043     authkey,keywrapkey,emsk = wsc_keys(kdk)
6044     logger.debug("AuthKey: " + binascii.hexlify(authkey))
6045     logger.debug("KeyWrapKey: " + binascii.hexlify(keywrapkey))
6046     logger.debug("EMSK: " + binascii.hexlify(emsk))
6047     return authkey,keywrapkey
6048
6049 def wsc_dev_pw_hash(authkey, dev_pw, e_pk, r_pk):
6050     psk1,psk2 = wsc_dev_pw_psk(authkey, dev_pw)
6051     logger.debug("PSK1: " + binascii.hexlify(psk1))
6052     logger.debug("PSK2: " + binascii.hexlify(psk2))
6053
6054     # Note: Secret values are supposed to be random, but hardcoded values are
6055     # fine for testing.
6056     s1 = 16*'\x77'
6057     m = hmac.new(authkey, s1 + psk1 + e_pk + r_pk, hashlib.sha256)
6058     hash1 = m.digest()
6059     logger.debug("Hash1: " + binascii.hexlify(hash1))
6060
6061     s2 = 16*'\x88'
6062     m = hmac.new(authkey, s2 + psk2 + e_pk + r_pk, hashlib.sha256)
6063     hash2 = m.digest()
6064     logger.debug("Hash2: " + binascii.hexlify(hash2))
6065     return s1,s2,hash1,hash2
6066
6067 def build_m1(eap_id, uuid_e, mac_addr, e_nonce, e_pk,
6068              manufacturer='', model_name='', config_methods='\x00\x00'):
6069     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6070     attrs += build_attr_msg_type(WPS_M1)
6071     attrs += build_wsc_attr(ATTR_UUID_E, uuid_e)
6072     attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6073     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6074     attrs += build_wsc_attr(ATTR_PUBLIC_KEY, e_pk)
6075     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6076     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6077     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6078     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, config_methods)
6079     attrs += build_wsc_attr(ATTR_WPS_STATE, '\x00')
6080     attrs += build_wsc_attr(ATTR_MANUFACTURER, manufacturer)
6081     attrs += build_wsc_attr(ATTR_MODEL_NAME, model_name)
6082     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6083     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6084     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6085     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6086     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6087     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6088     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, '\x00\x00')
6089     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6090     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6091     m1 = build_eap_wsc(2, eap_id, attrs)
6092     return m1, attrs
6093
6094 def build_m2(authkey, m1, eap_id, e_nonce, r_nonce, uuid_r, r_pk,
6095              dev_pw_id='\x00\x00', eap_code=1):
6096     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6097     attrs += build_attr_msg_type(WPS_M2)
6098     if e_nonce:
6099         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6100     if r_nonce:
6101         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6102     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6103     if r_pk:
6104         attrs += build_wsc_attr(ATTR_PUBLIC_KEY, r_pk)
6105     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6106     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6107     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6108     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6109     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6110     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6111     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6112     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6113     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6114     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6115     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6116     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6117     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6118     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6119     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6120     attrs += build_attr_authenticator(authkey, m1, attrs)
6121     m2 = build_eap_wsc(eap_code, eap_id, attrs)
6122     return m2, attrs
6123
6124 def build_m2d(m1, eap_id, e_nonce, r_nonce, uuid_r, dev_pw_id=None, eap_code=1):
6125     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6126     attrs += build_attr_msg_type(WPS_M2D)
6127     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6128     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6129     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6130     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6131     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6132     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6133     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6134     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6135     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6136     #attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6137     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6138     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6139     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6140     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6141     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6142     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6143     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6144     if dev_pw_id:
6145         attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6146     m2d = build_eap_wsc(eap_code, eap_id, attrs)
6147     return m2d, attrs
6148
6149 def build_ack(eap_id, e_nonce, r_nonce, msg_type=WPS_WSC_ACK, eap_code=1):
6150     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6151     if msg_type is not None:
6152         attrs += build_attr_msg_type(msg_type)
6153     if e_nonce:
6154         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6155     if r_nonce:
6156         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6157     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_ACK)
6158     return msg, attrs
6159
6160 def build_nack(eap_id, e_nonce, r_nonce, config_error='\x00\x00',
6161                msg_type=WPS_WSC_NACK, eap_code=1):
6162     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6163     if msg_type is not None:
6164         attrs += build_attr_msg_type(msg_type)
6165     if e_nonce:
6166         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6167     if r_nonce:
6168         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6169     if config_error:
6170         attrs += build_wsc_attr(ATTR_CONFIG_ERROR, config_error)
6171     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_NACK)
6172     return msg, attrs
6173
6174 def test_wps_ext(dev, apdev):
6175     """WPS against external implementation"""
6176     pin = "12345670"
6177     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6178     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6179     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6180
6181     logger.debug("Receive WSC/Start from AP")
6182     msg = get_wsc_msg(hapd)
6183     if msg['wsc_opcode'] != WSC_Start:
6184         raise Exception("Unexpected Op-Code for WSC/Start")
6185     wsc_start_id = msg['eap_identifier']
6186
6187     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6188     uuid_e = 16*'\x11'
6189     e_nonce = 16*'\x22'
6190     own_private, e_pk = wsc_dh_init()
6191
6192     logger.debug("Send M1 to AP")
6193     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
6194                                 e_nonce, e_pk)
6195     send_wsc_msg(hapd, addr, m1)
6196
6197     logger.debug("Receive M2 from AP")
6198     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
6199
6200     authkey,keywrapkey = wsc_dh_kdf(m2_attrs[ATTR_PUBLIC_KEY], own_private,
6201                                     mac_addr, e_nonce,
6202                                     m2_attrs[ATTR_REGISTRAR_NONCE])
6203     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk,
6204                                                 m2_attrs[ATTR_PUBLIC_KEY])
6205
6206     logger.debug("Send M3 to AP")
6207     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6208     attrs += build_attr_msg_type(WPS_M3)
6209     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6210                             m2_attrs[ATTR_REGISTRAR_NONCE])
6211     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
6212     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
6213     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
6214     raw_m3_attrs = attrs
6215     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6216     send_wsc_msg(hapd, addr, m3)
6217
6218     logger.debug("Receive M4 from AP")
6219     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
6220
6221     logger.debug("Send M5 to AP")
6222     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6223     attrs += build_attr_msg_type(WPS_M5)
6224     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6225                             m2_attrs[ATTR_REGISTRAR_NONCE])
6226     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
6227     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6228     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
6229     raw_m5_attrs = attrs
6230     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6231     send_wsc_msg(hapd, addr, m5)
6232
6233     logger.debug("Receive M6 from AP")
6234     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
6235
6236     logger.debug("Send M7 to AP")
6237     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6238     attrs += build_attr_msg_type(WPS_M7)
6239     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6240                             m2_attrs[ATTR_REGISTRAR_NONCE])
6241     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
6242     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6243     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
6244     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6245     raw_m7_attrs = attrs
6246     send_wsc_msg(hapd, addr, m7)
6247
6248     logger.debug("Receive M8 from AP")
6249     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
6250     m8_cred = decrypt_attr_encr_settings(authkey, keywrapkey,
6251                                          m8_attrs[ATTR_ENCR_SETTINGS])
6252     logger.debug("M8 Credential: " + binascii.hexlify(m8_cred))
6253
6254     logger.debug("Prepare WSC_Done")
6255     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6256     attrs += build_attr_msg_type(WPS_WSC_DONE)
6257     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6258     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6259                             m2_attrs[ATTR_REGISTRAR_NONCE])
6260     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
6261     # Do not send WSC_Done yet to allow exchangw with STA complete before the
6262     # AP disconnects.
6263
6264     uuid_r = 16*'\x33'
6265     r_nonce = 16*'\x44'
6266
6267     eap_id = wsc_start_id
6268     logger.debug("Send WSC/Start to STA")
6269     wsc_start = build_eap_wsc(1, eap_id, "", opcode=WSC_Start)
6270     send_wsc_msg(dev[0], bssid, wsc_start)
6271     eap_id = (eap_id + 1) % 256
6272
6273     logger.debug("Receive M1 from STA")
6274     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6275
6276     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6277                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6278                                     r_nonce)
6279     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6280                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6281
6282     logger.debug("Send M2 to STA")
6283     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6284                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6285                                 r_nonce, uuid_r, e_pk)
6286     send_wsc_msg(dev[0], bssid, m2)
6287     eap_id = (eap_id + 1) % 256
6288
6289     logger.debug("Receive M3 from STA")
6290     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6291
6292     logger.debug("Send M4 to STA")
6293     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6294     attrs += build_attr_msg_type(WPS_M4)
6295     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6296     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6297     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6298     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6299     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6300     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6301     raw_m4_attrs = attrs
6302     m4 = build_eap_wsc(1, eap_id, attrs)
6303     send_wsc_msg(dev[0], bssid, m4)
6304     eap_id = (eap_id + 1) % 256
6305
6306     logger.debug("Receive M5 from STA")
6307     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6308
6309     logger.debug("Send M6 to STA")
6310     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6311     attrs += build_attr_msg_type(WPS_M6)
6312     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6313                             m1_attrs[ATTR_ENROLLEE_NONCE])
6314     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6315     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6316     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6317     raw_m6_attrs = attrs
6318     m6 = build_eap_wsc(1, eap_id, attrs)
6319     send_wsc_msg(dev[0], bssid, m6)
6320     eap_id = (eap_id + 1) % 256
6321
6322     logger.debug("Receive M7 from STA")
6323     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6324
6325     logger.debug("Send M8 to STA")
6326     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6327     attrs += build_attr_msg_type(WPS_M8)
6328     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6329                             m1_attrs[ATTR_ENROLLEE_NONCE])
6330     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6331     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6332     raw_m8_attrs = attrs
6333     m8 = build_eap_wsc(1, eap_id, attrs)
6334     send_wsc_msg(dev[0], bssid, m8)
6335     eap_id = (eap_id + 1) % 256
6336
6337     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=5)
6338     if ev is None:
6339         raise Exception("wpa_supplicant did not report credential")
6340
6341     logger.debug("Receive WSC_Done from STA")
6342     msg = get_wsc_msg(dev[0])
6343     if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6344         raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6345
6346     logger.debug("Send WSC_Done to AP")
6347     hapd.request("SET ext_eapol_frame_io 0")
6348     dev[0].request("SET ext_eapol_frame_io 0")
6349     send_wsc_msg(hapd, addr, wsc_done)
6350
6351     ev = hapd.wait_event(["WPS-REG-SUCCESS"], timeout=5)
6352     if ev is None:
6353         raise Exception("hostapd did not report WPS success")
6354
6355     dev[0].wait_connected()
6356
6357 def wps_start_kwa(dev, apdev):
6358     pin = "12345670"
6359     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6360     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6361     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6362     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6363
6364     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6365     uuid_r = 16*'\x33'
6366     r_nonce = 16*'\x44'
6367     own_private, e_pk = wsc_dh_init()
6368
6369     logger.debug("Receive M1 from STA")
6370     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6371     eap_id = (msg['eap_identifier'] + 1) % 256
6372
6373     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6374                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6375                                     r_nonce)
6376     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6377                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6378
6379     logger.debug("Send M2 to STA")
6380     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6381                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6382                                 r_nonce, uuid_r, e_pk)
6383     send_wsc_msg(dev[0], bssid, m2)
6384     eap_id = (eap_id + 1) % 256
6385
6386     logger.debug("Receive M3 from STA")
6387     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6388
6389     logger.debug("Send M4 to STA")
6390     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6391     attrs += build_attr_msg_type(WPS_M4)
6392     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6393     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6394     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6395
6396     return r_s1, keywrapkey, authkey, raw_m3_attrs, eap_id, bssid, attrs
6397
6398 def wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id):
6399     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6400     m4 = build_eap_wsc(1, eap_id, attrs)
6401     send_wsc_msg(dev[0], bssid, m4)
6402     eap_id = (eap_id + 1) % 256
6403
6404     logger.debug("Receive M5 from STA")
6405     msg = get_wsc_msg(dev[0])
6406     if msg['wsc_opcode'] != WSC_NACK:
6407         raise Exception("Unexpected message - expected WSC_Nack")
6408
6409     dev[0].request("WPS_CANCEL")
6410     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6411     dev[0].wait_disconnected()
6412
6413 def test_wps_ext_kwa_proto_no_kwa(dev, apdev):
6414     """WPS and KWA error: No KWA attribute"""
6415     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6416     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6417     # Encrypted Settings without KWA
6418     iv = 16*'\x99'
6419     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6420     pad_len = 16 - len(data) % 16
6421     ps = pad_len * struct.pack('B', pad_len)
6422     data += ps
6423     wrapped = aes.encrypt(data)
6424     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6425     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6426
6427 def test_wps_ext_kwa_proto_data_after_kwa(dev, apdev):
6428     """WPS and KWA error: Data after KWA"""
6429     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6430     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6431     # Encrypted Settings and data after KWA
6432     m = hmac.new(authkey, data, hashlib.sha256)
6433     kwa = m.digest()[0:8]
6434     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6435     data += build_wsc_attr(ATTR_VENDOR_EXT, "1234567890")
6436     iv = 16*'\x99'
6437     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6438     pad_len = 16 - len(data) % 16
6439     ps = pad_len * struct.pack('B', pad_len)
6440     data += ps
6441     wrapped = aes.encrypt(data)
6442     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6443     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6444
6445 def test_wps_ext_kwa_proto_kwa_mismatch(dev, apdev):
6446     """WPS and KWA error: KWA mismatch"""
6447     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6448     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6449     # Encrypted Settings and KWA with incorrect value
6450     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, 8*'\x00')
6451     iv = 16*'\x99'
6452     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6453     pad_len = 16 - len(data) % 16
6454     ps = pad_len * struct.pack('B', pad_len)
6455     data += ps
6456     wrapped = aes.encrypt(data)
6457     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6458     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6459
6460 def wps_run_cred_proto(dev, apdev, m8_cred, connect=False, no_connect=False):
6461     pin = "12345670"
6462     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6463     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6464     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6465     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6466
6467     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6468     uuid_r = 16*'\x33'
6469     r_nonce = 16*'\x44'
6470     own_private, e_pk = wsc_dh_init()
6471
6472     logger.debug("Receive M1 from STA")
6473     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6474     eap_id = (msg['eap_identifier'] + 1) % 256
6475
6476     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6477                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6478                                     r_nonce)
6479     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6480                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6481
6482     logger.debug("Send M2 to STA")
6483     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6484                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6485                                 r_nonce, uuid_r, e_pk)
6486     send_wsc_msg(dev[0], bssid, m2)
6487     eap_id = (eap_id + 1) % 256
6488
6489     logger.debug("Receive M3 from STA")
6490     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6491
6492     logger.debug("Send M4 to STA")
6493     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6494     attrs += build_attr_msg_type(WPS_M4)
6495     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6496     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6497     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6498     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6499     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6500     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6501     raw_m4_attrs = attrs
6502     m4 = build_eap_wsc(1, eap_id, attrs)
6503     send_wsc_msg(dev[0], bssid, m4)
6504     eap_id = (eap_id + 1) % 256
6505
6506     logger.debug("Receive M5 from STA")
6507     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6508
6509     logger.debug("Send M6 to STA")
6510     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6511     attrs += build_attr_msg_type(WPS_M6)
6512     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6513                             m1_attrs[ATTR_ENROLLEE_NONCE])
6514     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6515     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6516     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6517     raw_m6_attrs = attrs
6518     m6 = build_eap_wsc(1, eap_id, attrs)
6519     send_wsc_msg(dev[0], bssid, m6)
6520     eap_id = (eap_id + 1) % 256
6521
6522     logger.debug("Receive M7 from STA")
6523     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6524
6525     logger.debug("Send M8 to STA")
6526     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6527     attrs += build_attr_msg_type(WPS_M8)
6528     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6529                             m1_attrs[ATTR_ENROLLEE_NONCE])
6530     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6531     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6532     raw_m8_attrs = attrs
6533     m8 = build_eap_wsc(1, eap_id, attrs)
6534     send_wsc_msg(dev[0], bssid, m8)
6535     eap_id = (eap_id + 1) % 256
6536
6537     if no_connect:
6538         logger.debug("Receive WSC_Done from STA")
6539         msg = get_wsc_msg(dev[0])
6540         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6541             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6542
6543         hapd.request("SET ext_eapol_frame_io 0")
6544         dev[0].request("SET ext_eapol_frame_io 0")
6545
6546         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6547
6548         dev[0].wait_disconnected()
6549         dev[0].request("REMOVE_NETWORK all")
6550     elif connect:
6551         logger.debug("Receive WSC_Done from STA")
6552         msg = get_wsc_msg(dev[0])
6553         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6554             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6555
6556         hapd.request("SET ext_eapol_frame_io 0")
6557         dev[0].request("SET ext_eapol_frame_io 0")
6558
6559         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6560
6561         dev[0].wait_connected()
6562     else:
6563         # Verify STA NACK's the credential
6564         msg = get_wsc_msg(dev[0])
6565         if msg['wsc_opcode'] != WSC_NACK:
6566             raise Exception("Unexpected message - expected WSC_Nack")
6567         dev[0].request("WPS_CANCEL")
6568         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6569         dev[0].wait_disconnected()
6570
6571 def build_cred(nw_idx='\x01', ssid='test-wps-conf', auth_type='\x00\x20',
6572                encr_type='\x00\x08', nw_key="12345678",
6573                mac_addr='\x00\x00\x00\x00\x00\x00'):
6574     attrs = ''
6575     if nw_idx is not None:
6576         attrs += build_wsc_attr(ATTR_NETWORK_INDEX, nw_idx)
6577     if ssid is not None:
6578         attrs += build_wsc_attr(ATTR_SSID, ssid)
6579     if auth_type is not None:
6580         attrs += build_wsc_attr(ATTR_AUTH_TYPE, auth_type)
6581     if encr_type is not None:
6582         attrs += build_wsc_attr(ATTR_ENCR_TYPE, encr_type)
6583     if nw_key is not None:
6584         attrs += build_wsc_attr(ATTR_NETWORK_KEY, nw_key)
6585     if mac_addr is not None:
6586         attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6587     return build_wsc_attr(ATTR_CRED, attrs)
6588
6589 def test_wps_ext_cred_proto_success(dev, apdev):
6590     """WPS and Credential: success"""
6591     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6592     m8_cred = build_cred(mac_addr=mac_addr)
6593     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6594
6595 def test_wps_ext_cred_proto_mac_addr_mismatch(dev, apdev):
6596     """WPS and Credential: MAC Address mismatch"""
6597     m8_cred = build_cred()
6598     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6599
6600 def test_wps_ext_cred_proto_zero_padding(dev, apdev):
6601     """WPS and Credential: zeropadded attributes"""
6602     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6603     m8_cred = build_cred(mac_addr=mac_addr, ssid='test-wps-conf\x00',
6604                          nw_key="12345678\x00")
6605     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6606
6607 def test_wps_ext_cred_proto_ssid_missing(dev, apdev):
6608     """WPS and Credential: SSID missing"""
6609     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6610     m8_cred = build_cred(mac_addr=mac_addr, ssid=None)
6611     wps_run_cred_proto(dev, apdev, m8_cred)
6612
6613 def test_wps_ext_cred_proto_ssid_zero_len(dev, apdev):
6614     """WPS and Credential: Zero-length SSID"""
6615     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6616     m8_cred = build_cred(mac_addr=mac_addr, ssid="")
6617     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6618
6619 def test_wps_ext_cred_proto_auth_type_missing(dev, apdev):
6620     """WPS and Credential: Auth Type missing"""
6621     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6622     m8_cred = build_cred(mac_addr=mac_addr, auth_type=None)
6623     wps_run_cred_proto(dev, apdev, m8_cred)
6624
6625 def test_wps_ext_cred_proto_encr_type_missing(dev, apdev):
6626     """WPS and Credential: Encr Type missing"""
6627     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6628     m8_cred = build_cred(mac_addr=mac_addr, encr_type=None)
6629     wps_run_cred_proto(dev, apdev, m8_cred)
6630
6631 def test_wps_ext_cred_proto_network_key_missing(dev, apdev):
6632     """WPS and Credential: Network Key missing"""
6633     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6634     m8_cred = build_cred(mac_addr=mac_addr, nw_key=None)
6635     wps_run_cred_proto(dev, apdev, m8_cred)
6636
6637 def test_wps_ext_cred_proto_network_key_missing_open(dev, apdev):
6638     """WPS and Credential: Network Key missing (open)"""
6639     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6640     m8_cred = build_cred(mac_addr=mac_addr, auth_type='\x00\x01',
6641                          encr_type='\x00\x01', nw_key=None, ssid="foo")
6642     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6643
6644 def test_wps_ext_cred_proto_mac_addr_missing(dev, apdev):
6645     """WPS and Credential: MAC Address missing"""
6646     m8_cred = build_cred(mac_addr=None)
6647     wps_run_cred_proto(dev, apdev, m8_cred)
6648
6649 def test_wps_ext_cred_proto_invalid_encr_type(dev, apdev):
6650     """WPS and Credential: Invalid Encr Type"""
6651     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6652     m8_cred = build_cred(mac_addr=mac_addr, encr_type='\x00\x00')
6653     wps_run_cred_proto(dev, apdev, m8_cred)
6654
6655 def test_wps_ext_cred_proto_missing_cred(dev, apdev):
6656     """WPS and Credential: Missing Credential"""
6657     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6658     m8_cred = ''
6659     wps_run_cred_proto(dev, apdev, m8_cred)
6660
6661 def test_wps_ext_proto_m2_no_public_key(dev, apdev):
6662     """WPS and no Public Key in M2"""
6663     pin = "12345670"
6664     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6665     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6666     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6667     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6668
6669     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6670     uuid_r = 16*'\x33'
6671     r_nonce = 16*'\x44'
6672     own_private, e_pk = wsc_dh_init()
6673
6674     logger.debug("Receive M1 from STA")
6675     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6676     eap_id = (msg['eap_identifier'] + 1) % 256
6677
6678     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6679                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6680                                     r_nonce)
6681     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6682                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6683
6684     logger.debug("Send M2 to STA")
6685     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6686                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6687                                 r_nonce, uuid_r, None)
6688     send_wsc_msg(dev[0], bssid, m2)
6689     eap_id = (eap_id + 1) % 256
6690
6691     # Verify STA NACK's the credential
6692     msg = get_wsc_msg(dev[0])
6693     if msg['wsc_opcode'] != WSC_NACK:
6694         raise Exception("Unexpected message - expected WSC_Nack")
6695     dev[0].request("WPS_CANCEL")
6696     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6697     dev[0].wait_disconnected()
6698
6699 def test_wps_ext_proto_m2_invalid_public_key(dev, apdev):
6700     """WPS and invalid Public Key in M2"""
6701     pin = "12345670"
6702     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6703     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6704     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6705     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6706
6707     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6708     uuid_r = 16*'\x33'
6709     r_nonce = 16*'\x44'
6710     own_private, e_pk = wsc_dh_init()
6711
6712     logger.debug("Receive M1 from STA")
6713     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6714     eap_id = (msg['eap_identifier'] + 1) % 256
6715
6716     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6717                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6718                                     r_nonce)
6719     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6720                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6721
6722     logger.debug("Send M2 to STA")
6723     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6724                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6725                                 r_nonce, uuid_r, 192*'\xff')
6726     send_wsc_msg(dev[0], bssid, m2)
6727     eap_id = (eap_id + 1) % 256
6728
6729     # Verify STA NACK's the credential
6730     msg = get_wsc_msg(dev[0])
6731     if msg['wsc_opcode'] != WSC_NACK:
6732         raise Exception("Unexpected message - expected WSC_Nack")
6733     dev[0].request("WPS_CANCEL")
6734     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6735     dev[0].wait_disconnected()
6736
6737 def test_wps_ext_proto_m2_public_key_oom(dev, apdev):
6738     """WPS and Public Key OOM in M2"""
6739     pin = "12345670"
6740     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6741     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6742     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6743     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6744
6745     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6746     uuid_r = 16*'\x33'
6747     r_nonce = 16*'\x44'
6748     own_private, e_pk = wsc_dh_init()
6749
6750     logger.debug("Receive M1 from STA")
6751     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6752     eap_id = (msg['eap_identifier'] + 1) % 256
6753
6754     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6755                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6756                                     r_nonce)
6757     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6758                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6759
6760     logger.debug("Send M2 to STA")
6761     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6762                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6763                                 r_nonce, uuid_r, e_pk)
6764     with alloc_fail(dev[0], 1, "wpabuf_alloc_copy;wps_process_pubkey"):
6765         send_wsc_msg(dev[0], bssid, m2)
6766         eap_id = (eap_id + 1) % 256
6767
6768         # Verify STA NACK's the credential
6769         msg = get_wsc_msg(dev[0])
6770         if msg['wsc_opcode'] != WSC_NACK:
6771             raise Exception("Unexpected message - expected WSC_Nack")
6772         dev[0].request("WPS_CANCEL")
6773         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6774         dev[0].wait_disconnected()
6775
6776 def test_wps_ext_proto_nack_m3(dev, apdev):
6777     """WPS and NACK M3"""
6778     pin = "12345670"
6779     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6780     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6781     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6782     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6783
6784     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6785     uuid_r = 16*'\x33'
6786     r_nonce = 16*'\x44'
6787     own_private, e_pk = wsc_dh_init()
6788
6789     logger.debug("Receive M1 from STA")
6790     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6791     eap_id = (msg['eap_identifier'] + 1) % 256
6792
6793     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6794                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6795                                     r_nonce)
6796     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6797                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6798
6799     logger.debug("Send M2 to STA")
6800     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6801                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6802                                 r_nonce, uuid_r, e_pk)
6803     send_wsc_msg(dev[0], bssid, m2)
6804     eap_id = (eap_id + 1) % 256
6805
6806     logger.debug("Receive M3 from STA")
6807     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6808
6809     logger.debug("Send NACK to STA")
6810     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
6811                             r_nonce, config_error='\x01\x23')
6812     send_wsc_msg(dev[0], bssid, msg)
6813     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
6814     if ev is None:
6815         raise Exception("Failure not reported")
6816     if "msg=7 config_error=291" not in ev:
6817         raise Exception("Unexpected failure reason: " + ev)
6818
6819 def test_wps_ext_proto_nack_m5(dev, apdev):
6820     """WPS and NACK M5"""
6821     pin = "12345670"
6822     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6823     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6824     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6825     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6826
6827     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6828     uuid_r = 16*'\x33'
6829     r_nonce = 16*'\x44'
6830     own_private, e_pk = wsc_dh_init()
6831
6832     logger.debug("Receive M1 from STA")
6833     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6834     eap_id = (msg['eap_identifier'] + 1) % 256
6835
6836     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6837                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6838                                     r_nonce)
6839     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6840                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6841
6842     logger.debug("Send M2 to STA")
6843     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6844                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6845                                 r_nonce, uuid_r, e_pk)
6846     send_wsc_msg(dev[0], bssid, m2)
6847     eap_id = (eap_id + 1) % 256
6848
6849     logger.debug("Receive M3 from STA")
6850     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6851
6852     logger.debug("Send M4 to STA")
6853     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6854     attrs += build_attr_msg_type(WPS_M4)
6855     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6856     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6857     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6858     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6859     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6860     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6861     raw_m4_attrs = attrs
6862     m4 = build_eap_wsc(1, eap_id, attrs)
6863     send_wsc_msg(dev[0], bssid, m4)
6864     eap_id = (eap_id + 1) % 256
6865
6866     logger.debug("Receive M5 from STA")
6867     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6868
6869     logger.debug("Send NACK to STA")
6870     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
6871                             r_nonce, config_error='\x01\x24')
6872     send_wsc_msg(dev[0], bssid, msg)
6873     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
6874     if ev is None:
6875         raise Exception("Failure not reported")
6876     if "msg=9 config_error=292" not in ev:
6877         raise Exception("Unexpected failure reason: " + ev)
6878
6879 def wps_nack_m3(dev, apdev):
6880     pin = "00000000"
6881     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
6882     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6883     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6884     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6885
6886     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6887     uuid_r = 16*'\x33'
6888     r_nonce = 16*'\x44'
6889     own_private, e_pk = wsc_dh_init()
6890
6891     logger.debug("Receive M1 from STA")
6892     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6893     eap_id = (msg['eap_identifier'] + 1) % 256
6894
6895     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6896                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6897                                     r_nonce)
6898     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6899                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6900
6901     logger.debug("Send M2 to STA")
6902     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6903                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6904                                 r_nonce, uuid_r, e_pk, dev_pw_id='\x00\x04')
6905     send_wsc_msg(dev[0], bssid, m2)
6906     eap_id = (eap_id + 1) % 256
6907
6908     logger.debug("Receive M3 from STA")
6909     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6910     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid
6911
6912 def test_wps_ext_proto_nack_m3_no_config_error(dev, apdev):
6913     """WPS and NACK M3 missing Config Error"""
6914     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6915     logger.debug("Send NACK to STA")
6916     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, config_error=None)
6917     send_wsc_msg(dev[0], bssid, msg)
6918     dev[0].request("WPS_CANCEL")
6919     dev[0].wait_disconnected()
6920     dev[0].flush_scan_cache()
6921
6922 def test_wps_ext_proto_nack_m3_no_e_nonce(dev, apdev):
6923     """WPS and NACK M3 missing E-Nonce"""
6924     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6925     logger.debug("Send NACK to STA")
6926     msg, attrs = build_nack(eap_id, None, r_nonce)
6927     send_wsc_msg(dev[0], bssid, msg)
6928     dev[0].request("WPS_CANCEL")
6929     dev[0].wait_disconnected()
6930     dev[0].flush_scan_cache()
6931
6932 def test_wps_ext_proto_nack_m3_e_nonce_mismatch(dev, apdev):
6933     """WPS and NACK M3 E-Nonce mismatch"""
6934     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6935     logger.debug("Send NACK to STA")
6936     msg, attrs = build_nack(eap_id, 16*'\x00', r_nonce)
6937     send_wsc_msg(dev[0], bssid, msg)
6938     dev[0].request("WPS_CANCEL")
6939     dev[0].wait_disconnected()
6940     dev[0].flush_scan_cache()
6941
6942 def test_wps_ext_proto_nack_m3_no_r_nonce(dev, apdev):
6943     """WPS and NACK M3 missing R-Nonce"""
6944     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6945     logger.debug("Send NACK to STA")
6946     msg, attrs = build_nack(eap_id, e_nonce, None)
6947     send_wsc_msg(dev[0], bssid, msg)
6948     dev[0].request("WPS_CANCEL")
6949     dev[0].wait_disconnected()
6950     dev[0].flush_scan_cache()
6951
6952 def test_wps_ext_proto_nack_m3_r_nonce_mismatch(dev, apdev):
6953     """WPS and NACK M3 R-Nonce mismatch"""
6954     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6955     logger.debug("Send NACK to STA")
6956     msg, attrs = build_nack(eap_id, e_nonce, 16*'\x00')
6957     send_wsc_msg(dev[0], bssid, msg)
6958     dev[0].request("WPS_CANCEL")
6959     dev[0].wait_disconnected()
6960     dev[0].flush_scan_cache()
6961
6962 def test_wps_ext_proto_nack_m3_no_msg_type(dev, apdev):
6963     """WPS and NACK M3 no Message Type"""
6964     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6965     logger.debug("Send NACK to STA")
6966     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=None)
6967     send_wsc_msg(dev[0], bssid, msg)
6968     dev[0].request("WPS_CANCEL")
6969     dev[0].wait_disconnected()
6970     dev[0].flush_scan_cache()
6971
6972 def test_wps_ext_proto_nack_m3_invalid_msg_type(dev, apdev):
6973     """WPS and NACK M3 invalid Message Type"""
6974     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6975     logger.debug("Send NACK to STA")
6976     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=123)
6977     send_wsc_msg(dev[0], bssid, msg)
6978     dev[0].request("WPS_CANCEL")
6979     dev[0].wait_disconnected()
6980     dev[0].flush_scan_cache()
6981
6982 def test_wps_ext_proto_nack_m3_invalid_attr(dev, apdev):
6983     """WPS and NACK M3 invalid attribute"""
6984     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6985     logger.debug("Send NACK to STA")
6986     attrs = '\x10\x10\x00'
6987     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_NACK)
6988     send_wsc_msg(dev[0], bssid, msg)
6989     dev[0].request("WPS_CANCEL")
6990     dev[0].wait_disconnected()
6991     dev[0].flush_scan_cache()
6992
6993 def test_wps_ext_proto_ack_m3_no_e_nonce(dev, apdev):
6994     """WPS and ACK M3 missing E-Nonce"""
6995     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6996     logger.debug("Send NACK to STA")
6997     msg, attrs = build_ack(eap_id, None, r_nonce)
6998     send_wsc_msg(dev[0], bssid, msg)
6999     dev[0].request("WPS_CANCEL")
7000     dev[0].wait_disconnected()
7001     dev[0].flush_scan_cache()
7002
7003 def test_wps_ext_proto_ack_m3_e_nonce_mismatch(dev, apdev):
7004     """WPS and ACK M3 E-Nonce mismatch"""
7005     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7006     logger.debug("Send NACK to STA")
7007     msg, attrs = build_ack(eap_id, 16*'\x00', r_nonce)
7008     send_wsc_msg(dev[0], bssid, msg)
7009     dev[0].request("WPS_CANCEL")
7010     dev[0].wait_disconnected()
7011     dev[0].flush_scan_cache()
7012
7013 def test_wps_ext_proto_ack_m3_no_r_nonce(dev, apdev):
7014     """WPS and ACK M3 missing R-Nonce"""
7015     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7016     logger.debug("Send NACK to STA")
7017     msg, attrs = build_ack(eap_id, e_nonce, None)
7018     send_wsc_msg(dev[0], bssid, msg)
7019     dev[0].request("WPS_CANCEL")
7020     dev[0].wait_disconnected()
7021     dev[0].flush_scan_cache()
7022
7023 def test_wps_ext_proto_ack_m3_r_nonce_mismatch(dev, apdev):
7024     """WPS and ACK M3 R-Nonce mismatch"""
7025     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7026     logger.debug("Send NACK to STA")
7027     msg, attrs = build_ack(eap_id, e_nonce, 16*'\x00')
7028     send_wsc_msg(dev[0], bssid, msg)
7029     dev[0].request("WPS_CANCEL")
7030     dev[0].wait_disconnected()
7031     dev[0].flush_scan_cache()
7032
7033 def test_wps_ext_proto_ack_m3_no_msg_type(dev, apdev):
7034     """WPS and ACK M3 no Message Type"""
7035     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7036     logger.debug("Send NACK to STA")
7037     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=None)
7038     send_wsc_msg(dev[0], bssid, msg)
7039     dev[0].request("WPS_CANCEL")
7040     dev[0].wait_disconnected()
7041     dev[0].flush_scan_cache()
7042
7043 def test_wps_ext_proto_ack_m3_invalid_msg_type(dev, apdev):
7044     """WPS and ACK M3 invalid Message Type"""
7045     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7046     logger.debug("Send NACK to STA")
7047     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=123)
7048     send_wsc_msg(dev[0], bssid, msg)
7049     dev[0].request("WPS_CANCEL")
7050     dev[0].wait_disconnected()
7051     dev[0].flush_scan_cache()
7052
7053 def test_wps_ext_proto_ack_m3_invalid_attr(dev, apdev):
7054     """WPS and ACK M3 invalid attribute"""
7055     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7056     logger.debug("Send ACK to STA")
7057     attrs = '\x10\x10\x00'
7058     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_ACK)
7059     send_wsc_msg(dev[0], bssid, msg)
7060     dev[0].request("WPS_CANCEL")
7061     dev[0].wait_disconnected()
7062     dev[0].flush_scan_cache()
7063
7064 def test_wps_ext_proto_ack_m3(dev, apdev):
7065     """WPS and ACK M3"""
7066     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7067     logger.debug("Send ACK to STA")
7068     msg, attrs = build_ack(eap_id, e_nonce, r_nonce)
7069     send_wsc_msg(dev[0], bssid, msg)
7070     dev[0].request("WPS_CANCEL")
7071     dev[0].wait_disconnected()
7072     dev[0].flush_scan_cache()
7073
7074 def wps_to_m3_helper(dev, apdev):
7075     pin = "12345670"
7076     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7077     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7078     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7079     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7080
7081     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7082     uuid_r = 16*'\x33'
7083     r_nonce = 16*'\x44'
7084     own_private, e_pk = wsc_dh_init()
7085
7086     logger.debug("Receive M1 from STA")
7087     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7088     eap_id = (msg['eap_identifier'] + 1) % 256
7089
7090     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7091                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7092                                     r_nonce)
7093     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7094                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7095
7096     logger.debug("Send M2 to STA")
7097     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7098                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7099                                 r_nonce, uuid_r, e_pk)
7100     send_wsc_msg(dev[0], bssid, m2)
7101     eap_id = (eap_id + 1) % 256
7102
7103     logger.debug("Receive M3 from STA")
7104     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7105     return eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey
7106
7107 def wps_to_m3(dev, apdev):
7108     eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey = wps_to_m3_helper(dev, apdev)
7109     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s1, raw_m3_attrs, authkey, keywrapkey
7110
7111 def wps_to_m5(dev, apdev):
7112     eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey = wps_to_m3_helper(dev, apdev)
7113
7114     logger.debug("Send M4 to STA")
7115     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7116     attrs += build_attr_msg_type(WPS_M4)
7117     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
7118     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7119     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7120     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7121     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7122     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7123     raw_m4_attrs = attrs
7124     m4 = build_eap_wsc(1, eap_id, attrs)
7125     send_wsc_msg(dev[0], bssid, m4)
7126     eap_id = (eap_id + 1) % 256
7127
7128     logger.debug("Receive M5 from STA")
7129     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
7130
7131     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s2, raw_m5_attrs, authkey, keywrapkey
7132
7133 def test_wps_ext_proto_m4_missing_r_hash1(dev, apdev):
7134     """WPS and no R-Hash1 in M4"""
7135     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7136
7137     logger.debug("Send M4 to STA")
7138     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7139     attrs += build_attr_msg_type(WPS_M4)
7140     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7141     #attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7142     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7143     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7144     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7145     attrs += build_attr_authenticator(authkey, m3, attrs)
7146     m4 = build_eap_wsc(1, eap_id, attrs)
7147     send_wsc_msg(dev[0], bssid, m4)
7148     eap_id = (eap_id + 1) % 256
7149
7150     logger.debug("Receive M5 (NACK) from STA")
7151     msg = get_wsc_msg(dev[0])
7152     if msg['wsc_opcode'] != WSC_NACK:
7153         raise Exception("Unexpected message - expected WSC_Nack")
7154
7155     dev[0].request("WPS_CANCEL")
7156     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7157     dev[0].wait_disconnected()
7158
7159 def test_wps_ext_proto_m4_missing_r_hash2(dev, apdev):
7160     """WPS and no R-Hash2 in M4"""
7161     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7162
7163     logger.debug("Send M4 to STA")
7164     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7165     attrs += build_attr_msg_type(WPS_M4)
7166     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7167     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7168     #attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7169     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7170     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7171     attrs += build_attr_authenticator(authkey, m3, attrs)
7172     m4 = build_eap_wsc(1, eap_id, attrs)
7173     send_wsc_msg(dev[0], bssid, m4)
7174     eap_id = (eap_id + 1) % 256
7175
7176     logger.debug("Receive M5 (NACK) from STA")
7177     msg = get_wsc_msg(dev[0])
7178     if msg['wsc_opcode'] != WSC_NACK:
7179         raise Exception("Unexpected message - expected WSC_Nack")
7180
7181     dev[0].request("WPS_CANCEL")
7182     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7183     dev[0].wait_disconnected()
7184
7185 def test_wps_ext_proto_m4_missing_r_snonce1(dev, apdev):
7186     """WPS and no R-SNonce1 in M4"""
7187     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7188
7189     logger.debug("Send M4 to STA")
7190     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7191     attrs += build_attr_msg_type(WPS_M4)
7192     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7193     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7194     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7195     #data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7196     data = ''
7197     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7198     attrs += build_attr_authenticator(authkey, m3, attrs)
7199     m4 = build_eap_wsc(1, eap_id, attrs)
7200     send_wsc_msg(dev[0], bssid, m4)
7201     eap_id = (eap_id + 1) % 256
7202
7203     logger.debug("Receive M5 (NACK) from STA")
7204     msg = get_wsc_msg(dev[0])
7205     if msg['wsc_opcode'] != WSC_NACK:
7206         raise Exception("Unexpected message - expected WSC_Nack")
7207
7208     dev[0].request("WPS_CANCEL")
7209     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7210     dev[0].wait_disconnected()
7211
7212 def test_wps_ext_proto_m4_invalid_pad_string(dev, apdev):
7213     """WPS and invalid pad string in M4"""
7214     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7215
7216     logger.debug("Send M4 to STA")
7217     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7218     attrs += build_attr_msg_type(WPS_M4)
7219     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7220     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7221     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7222     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7223
7224     m = hmac.new(authkey, data, hashlib.sha256)
7225     kwa = m.digest()[0:8]
7226     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7227     iv = 16*'\x99'
7228     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7229     pad_len = 16 - len(data) % 16
7230     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', pad_len - 1)
7231     data += ps
7232     wrapped = aes.encrypt(data)
7233     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7234
7235     attrs += build_attr_authenticator(authkey, m3, attrs)
7236     m4 = build_eap_wsc(1, eap_id, attrs)
7237     send_wsc_msg(dev[0], bssid, m4)
7238     eap_id = (eap_id + 1) % 256
7239
7240     logger.debug("Receive M5 (NACK) from STA")
7241     msg = get_wsc_msg(dev[0])
7242     if msg['wsc_opcode'] != WSC_NACK:
7243         raise Exception("Unexpected message - expected WSC_Nack")
7244
7245     dev[0].request("WPS_CANCEL")
7246     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7247     dev[0].wait_disconnected()
7248
7249 def test_wps_ext_proto_m4_invalid_pad_value(dev, apdev):
7250     """WPS and invalid pad value in M4"""
7251     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7252
7253     logger.debug("Send M4 to STA")
7254     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7255     attrs += build_attr_msg_type(WPS_M4)
7256     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7257     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7258     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7259     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7260
7261     m = hmac.new(authkey, data, hashlib.sha256)
7262     kwa = m.digest()[0:8]
7263     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7264     iv = 16*'\x99'
7265     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7266     pad_len = 16 - len(data) % 16
7267     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', 255)
7268     data += ps
7269     wrapped = aes.encrypt(data)
7270     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7271
7272     attrs += build_attr_authenticator(authkey, m3, attrs)
7273     m4 = build_eap_wsc(1, eap_id, attrs)
7274     send_wsc_msg(dev[0], bssid, m4)
7275     eap_id = (eap_id + 1) % 256
7276
7277     logger.debug("Receive M5 (NACK) from STA")
7278     msg = get_wsc_msg(dev[0])
7279     if msg['wsc_opcode'] != WSC_NACK:
7280         raise Exception("Unexpected message - expected WSC_Nack")
7281
7282     dev[0].request("WPS_CANCEL")
7283     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7284     dev[0].wait_disconnected()
7285
7286 def test_wps_ext_proto_m4_no_encr_settings(dev, apdev):
7287     """WPS and no Encr Settings in M4"""
7288     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7289
7290     logger.debug("Send M4 to STA")
7291     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7292     attrs += build_attr_msg_type(WPS_M4)
7293     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7294     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7295     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7296     attrs += build_attr_authenticator(authkey, m3, attrs)
7297     m4 = build_eap_wsc(1, eap_id, attrs)
7298     send_wsc_msg(dev[0], bssid, m4)
7299     eap_id = (eap_id + 1) % 256
7300
7301     logger.debug("Receive M5 (NACK) from STA")
7302     msg = get_wsc_msg(dev[0])
7303     if msg['wsc_opcode'] != WSC_NACK:
7304         raise Exception("Unexpected message - expected WSC_Nack")
7305
7306     dev[0].request("WPS_CANCEL")
7307     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7308     dev[0].wait_disconnected()
7309
7310 def test_wps_ext_proto_m6_missing_r_snonce2(dev, apdev):
7311     """WPS and no R-SNonce2 in M6"""
7312     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7313
7314     logger.debug("Send M6 to STA")
7315     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7316     attrs += build_attr_msg_type(WPS_M6)
7317     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7318     #data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7319     data = ''
7320     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7321     attrs += build_attr_authenticator(authkey, m5, attrs)
7322     m6 = build_eap_wsc(1, eap_id, attrs)
7323     send_wsc_msg(dev[0], bssid, m6)
7324     eap_id = (eap_id + 1) % 256
7325
7326     logger.debug("Receive M7 (NACK) from STA")
7327     msg = get_wsc_msg(dev[0])
7328     if msg['wsc_opcode'] != WSC_NACK:
7329         raise Exception("Unexpected message - expected WSC_Nack")
7330
7331     dev[0].request("WPS_CANCEL")
7332     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7333     dev[0].wait_disconnected()
7334
7335 def test_wps_ext_proto_m6_no_encr_settings(dev, apdev):
7336     """WPS and no Encr Settings in M6"""
7337     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7338
7339     logger.debug("Send M6 to STA")
7340     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7341     attrs += build_attr_msg_type(WPS_M6)
7342     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7343     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7344     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7345     attrs += build_attr_authenticator(authkey, m5, attrs)
7346     m6 = build_eap_wsc(1, eap_id, attrs)
7347     send_wsc_msg(dev[0], bssid, m6)
7348     eap_id = (eap_id + 1) % 256
7349
7350     logger.debug("Receive M7 (NACK) from STA")
7351     msg = get_wsc_msg(dev[0])
7352     if msg['wsc_opcode'] != WSC_NACK:
7353         raise Exception("Unexpected message - expected WSC_Nack")
7354
7355     dev[0].request("WPS_CANCEL")
7356     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7357     dev[0].wait_disconnected()
7358
7359 def test_wps_ext_proto_m8_no_encr_settings(dev, apdev):
7360     """WPS and no Encr Settings in M6"""
7361     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7362
7363     logger.debug("Send M6 to STA")
7364     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7365     attrs += build_attr_msg_type(WPS_M6)
7366     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7367     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7368     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7369     attrs += build_attr_authenticator(authkey, m5, attrs)
7370     raw_m6_attrs = attrs
7371     m6 = build_eap_wsc(1, eap_id, attrs)
7372     send_wsc_msg(dev[0], bssid, m6)
7373     eap_id = (eap_id + 1) % 256
7374
7375     logger.debug("Receive M7 from STA")
7376     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
7377
7378     logger.debug("Send M8 to STA")
7379     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7380     attrs += build_attr_msg_type(WPS_M8)
7381     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7382     #attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
7383     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7384     raw_m8_attrs = attrs
7385     m8 = build_eap_wsc(1, eap_id, attrs)
7386     send_wsc_msg(dev[0], bssid, m8)
7387
7388     logger.debug("Receive WSC_Done (NACK) from STA")
7389     msg = get_wsc_msg(dev[0])
7390     if msg['wsc_opcode'] != WSC_NACK:
7391         raise Exception("Unexpected message - expected WSC_Nack")
7392
7393     dev[0].request("WPS_CANCEL")
7394     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7395     dev[0].wait_disconnected()
7396
7397 def wps_start_ext_reg(apdev, dev):
7398     addr = dev.own_addr()
7399     bssid = apdev['bssid']
7400     ssid = "test-wps-conf"
7401     appin = "12345670"
7402     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
7403                "wpa_passphrase": "12345678", "wpa": "2",
7404                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
7405                "ap_pin": appin }
7406     hapd = hostapd.add_ap(apdev['ifname'], params)
7407
7408     dev.scan_for_bss(bssid, freq="2412")
7409     hapd.request("SET ext_eapol_frame_io 1")
7410     dev.request("SET ext_eapol_frame_io 1")
7411
7412     dev.request("WPS_REG " + bssid + " " + appin)
7413
7414     return addr,bssid,hapd
7415
7416 def wps_run_ap_settings_proto(dev, apdev, ap_settings, success):
7417     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7418     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7419     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7420
7421     logger.debug("Receive M1 from AP")
7422     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7423     mac_addr = m1_attrs[ATTR_MAC_ADDR]
7424     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7425     e_pk = m1_attrs[ATTR_PUBLIC_KEY]
7426
7427     appin = '12345670'
7428     uuid_r = 16*'\x33'
7429     r_nonce = 16*'\x44'
7430     own_private, r_pk = wsc_dh_init()
7431     authkey,keywrapkey = wsc_dh_kdf(e_pk, own_private, mac_addr, e_nonce,
7432                                     r_nonce)
7433     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, appin, e_pk, r_pk)
7434
7435     logger.debug("Send M2 to AP")
7436     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, msg['eap_identifier'],
7437                                 e_nonce, r_nonce, uuid_r, r_pk, eap_code=2)
7438     send_wsc_msg(hapd, addr, m2)
7439
7440     logger.debug("Receive M3 from AP")
7441     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M3)
7442
7443     logger.debug("Send M4 to AP")
7444     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7445     attrs += build_attr_msg_type(WPS_M4)
7446     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7447     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7448     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7449     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7450     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7451     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7452     raw_m4_attrs = attrs
7453     m4 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7454     send_wsc_msg(hapd, addr, m4)
7455
7456     logger.debug("Receive M5 from AP")
7457     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M5)
7458
7459     logger.debug("Send M6 to STA")
7460     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7461     attrs += build_attr_msg_type(WPS_M6)
7462     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7463     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7464     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7465     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
7466     raw_m6_attrs = attrs
7467     m6 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7468     send_wsc_msg(hapd, addr, m6)
7469
7470     logger.debug("Receive M7 from AP")
7471     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M7)
7472
7473     logger.debug("Send M8 to STA")
7474     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7475     attrs += build_attr_msg_type(WPS_M8)
7476     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7477     if ap_settings:
7478         attrs += build_attr_encr_settings(authkey, keywrapkey, ap_settings)
7479     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7480     raw_m8_attrs = attrs
7481     m8 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7482     send_wsc_msg(hapd, addr, m8)
7483
7484     if success:
7485         ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
7486         if ev is None:
7487             raise Exception("New AP settings not reported")
7488         logger.debug("Receive WSC_Done from AP")
7489         msg = get_wsc_msg(hapd)
7490         if msg['wsc_opcode'] != WSC_Done:
7491             raise Exception("Unexpected message - expected WSC_Done")
7492
7493         logger.debug("Send WSC_ACK to AP")
7494         ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
7495                               eap_code=2)
7496         send_wsc_msg(hapd, addr, ack)
7497         dev[0].wait_disconnected()
7498     else:
7499         ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
7500         if ev is None:
7501             raise Exception("WPS failure not reported")
7502         logger.debug("Receive WSC_NACK from AP")
7503         msg = get_wsc_msg(hapd)
7504         if msg['wsc_opcode'] != WSC_NACK:
7505             raise Exception("Unexpected message - expected WSC_NACK")
7506
7507         logger.debug("Send WSC_NACK to AP")
7508         nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7509                                 eap_code=2)
7510         send_wsc_msg(hapd, addr, nack)
7511         dev[0].wait_disconnected()
7512
7513 def test_wps_ext_ap_settings_success(dev, apdev):
7514     """WPS and AP Settings: success"""
7515     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7516     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7517     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7518     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7519     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7520     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7521     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7522
7523 def test_wps_ext_ap_settings_missing(dev, apdev):
7524     """WPS and AP Settings: missing"""
7525     wps_run_ap_settings_proto(dev, apdev, None, False)
7526
7527 def test_wps_ext_ap_settings_mac_addr_mismatch(dev, apdev):
7528     """WPS and AP Settings: MAC Address mismatch"""
7529     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7530     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7531     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7532     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7533     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7534     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, '\x00\x00\x00\x00\x00\x00')
7535     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7536
7537 def test_wps_ext_ap_settings_mac_addr_missing(dev, apdev):
7538     """WPS and AP Settings: missing MAC Address"""
7539     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7540     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7541     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7542     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7543     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7544     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7545
7546 def test_wps_ext_ap_settings_reject_encr_type(dev, apdev):
7547     """WPS and AP Settings: reject Encr Type"""
7548     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7549     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7550     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7551     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x00')
7552     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7553     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7554     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7555
7556 def test_wps_ext_ap_settings_m2d(dev, apdev):
7557     """WPS and AP Settings: M2D"""
7558     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7559     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7560     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7561
7562     logger.debug("Receive M1 from AP")
7563     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7564     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7565
7566     r_nonce = 16*'\x44'
7567     uuid_r = 16*'\x33'
7568
7569     logger.debug("Send M2D to AP")
7570     m2d, raw_m2d_attrs = build_m2d(raw_m1_attrs, msg['eap_identifier'],
7571                                    e_nonce, r_nonce, uuid_r,
7572                                    dev_pw_id='\x00\x00', eap_code=2)
7573     send_wsc_msg(hapd, addr, m2d)
7574
7575     ev = hapd.wait_event(["WPS-M2D"], timeout=5)
7576     if ev is None:
7577         raise Exception("M2D not reported")
7578
7579     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7580
7581 def wps_wait_ap_nack(hapd, dev, e_nonce, r_nonce):
7582     logger.debug("Receive WSC_NACK from AP")
7583     msg = get_wsc_msg(hapd)
7584     if msg['wsc_opcode'] != WSC_NACK:
7585         raise Exception("Unexpected message - expected WSC_NACK")
7586
7587     logger.debug("Send WSC_NACK to AP")
7588     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7589                             eap_code=2)
7590     send_wsc_msg(hapd, dev.own_addr(), nack)
7591     dev.wait_disconnected()
7592
7593 def test_wps_ext_m3_missing_e_hash1(dev, apdev):
7594     """WPS proto: M3 missing E-Hash1"""
7595     pin = "12345670"
7596     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7597     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7598     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7599
7600     logger.debug("Receive WSC/Start from AP")
7601     msg = get_wsc_msg(hapd)
7602     if msg['wsc_opcode'] != WSC_Start:
7603         raise Exception("Unexpected Op-Code for WSC/Start")
7604
7605     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7606     uuid_e = 16*'\x11'
7607     e_nonce = 16*'\x22'
7608     own_private, e_pk = wsc_dh_init()
7609
7610     logger.debug("Send M1 to AP")
7611     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7612                                 e_nonce, e_pk)
7613     send_wsc_msg(hapd, addr, m1)
7614
7615     logger.debug("Receive M2 from AP")
7616     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7617     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7618     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7619
7620     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7621                                     r_nonce)
7622     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7623
7624     logger.debug("Send M3 to AP")
7625     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7626     attrs += build_attr_msg_type(WPS_M3)
7627     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7628     #attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7629     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7630     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7631     raw_m3_attrs = attrs
7632     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7633     send_wsc_msg(hapd, addr, m3)
7634
7635     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7636
7637 def test_wps_ext_m3_missing_e_hash2(dev, apdev):
7638     """WPS proto: M3 missing E-Hash2"""
7639     pin = "12345670"
7640     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7641     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7642     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7643
7644     logger.debug("Receive WSC/Start from AP")
7645     msg = get_wsc_msg(hapd)
7646     if msg['wsc_opcode'] != WSC_Start:
7647         raise Exception("Unexpected Op-Code for WSC/Start")
7648
7649     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7650     uuid_e = 16*'\x11'
7651     e_nonce = 16*'\x22'
7652     own_private, e_pk = wsc_dh_init()
7653
7654     logger.debug("Send M1 to AP")
7655     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7656                                 e_nonce, e_pk)
7657     send_wsc_msg(hapd, addr, m1)
7658
7659     logger.debug("Receive M2 from AP")
7660     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7661     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7662     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7663
7664     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7665                                     r_nonce)
7666     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7667
7668     logger.debug("Send M3 to AP")
7669     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7670     attrs += build_attr_msg_type(WPS_M3)
7671     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7672     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7673     #attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7674     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7675     raw_m3_attrs = attrs
7676     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7677     send_wsc_msg(hapd, addr, m3)
7678
7679     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7680
7681 def test_wps_ext_m5_missing_e_snonce1(dev, apdev):
7682     """WPS proto: M5 missing E-SNonce1"""
7683     pin = "12345670"
7684     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7685     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7686     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7687
7688     logger.debug("Receive WSC/Start from AP")
7689     msg = get_wsc_msg(hapd)
7690     if msg['wsc_opcode'] != WSC_Start:
7691         raise Exception("Unexpected Op-Code for WSC/Start")
7692
7693     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7694     uuid_e = 16*'\x11'
7695     e_nonce = 16*'\x22'
7696     own_private, e_pk = wsc_dh_init()
7697
7698     logger.debug("Send M1 to AP")
7699     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7700                                 e_nonce, e_pk)
7701     send_wsc_msg(hapd, addr, m1)
7702
7703     logger.debug("Receive M2 from AP")
7704     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7705     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7706     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7707
7708     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7709                                     r_nonce)
7710     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7711
7712     logger.debug("Send M3 to AP")
7713     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7714     attrs += build_attr_msg_type(WPS_M3)
7715     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7716     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7717     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7718     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7719     raw_m3_attrs = attrs
7720     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7721     send_wsc_msg(hapd, addr, m3)
7722
7723     logger.debug("Receive M4 from AP")
7724     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7725
7726     logger.debug("Send M5 to AP")
7727     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7728     attrs += build_attr_msg_type(WPS_M5)
7729     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7730     #data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7731     data = ''
7732     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7733     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7734     raw_m5_attrs = attrs
7735     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7736     send_wsc_msg(hapd, addr, m5)
7737
7738     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7739
7740 def test_wps_ext_m5_e_snonce1_mismatch(dev, apdev):
7741     """WPS proto: M5 E-SNonce1 mismatch"""
7742     pin = "12345670"
7743     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7744     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7745     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7746
7747     logger.debug("Receive WSC/Start from AP")
7748     msg = get_wsc_msg(hapd)
7749     if msg['wsc_opcode'] != WSC_Start:
7750         raise Exception("Unexpected Op-Code for WSC/Start")
7751
7752     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7753     uuid_e = 16*'\x11'
7754     e_nonce = 16*'\x22'
7755     own_private, e_pk = wsc_dh_init()
7756
7757     logger.debug("Send M1 to AP")
7758     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7759                                 e_nonce, e_pk)
7760     send_wsc_msg(hapd, addr, m1)
7761
7762     logger.debug("Receive M2 from AP")
7763     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7764     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7765     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7766
7767     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7768                                     r_nonce)
7769     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7770
7771     logger.debug("Send M3 to AP")
7772     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7773     attrs += build_attr_msg_type(WPS_M3)
7774     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7775     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7776     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7777     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7778     raw_m3_attrs = attrs
7779     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7780     send_wsc_msg(hapd, addr, m3)
7781
7782     logger.debug("Receive M4 from AP")
7783     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7784
7785     logger.debug("Send M5 to AP")
7786     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7787     attrs += build_attr_msg_type(WPS_M5)
7788     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7789     data = build_wsc_attr(ATTR_E_SNONCE1, 16*'\x00')
7790     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7791     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7792     raw_m5_attrs = attrs
7793     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7794     send_wsc_msg(hapd, addr, m5)
7795
7796     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7797
7798 def test_wps_ext_m7_missing_e_snonce2(dev, apdev):
7799     """WPS proto: M7 missing E-SNonce2"""
7800     pin = "12345670"
7801     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7802     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7803     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7804
7805     logger.debug("Receive WSC/Start from AP")
7806     msg = get_wsc_msg(hapd)
7807     if msg['wsc_opcode'] != WSC_Start:
7808         raise Exception("Unexpected Op-Code for WSC/Start")
7809
7810     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7811     uuid_e = 16*'\x11'
7812     e_nonce = 16*'\x22'
7813     own_private, e_pk = wsc_dh_init()
7814
7815     logger.debug("Send M1 to AP")
7816     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7817                                 e_nonce, e_pk)
7818     send_wsc_msg(hapd, addr, m1)
7819
7820     logger.debug("Receive M2 from AP")
7821     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7822     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7823     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7824
7825     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7826                                     r_nonce)
7827     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7828
7829     logger.debug("Send M3 to AP")
7830     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7831     attrs += build_attr_msg_type(WPS_M3)
7832     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7833     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7834     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7835     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7836     raw_m3_attrs = attrs
7837     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7838     send_wsc_msg(hapd, addr, m3)
7839
7840     logger.debug("Receive M4 from AP")
7841     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7842
7843     logger.debug("Send M5 to AP")
7844     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7845     attrs += build_attr_msg_type(WPS_M5)
7846     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7847     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7848     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7849     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7850     raw_m5_attrs = attrs
7851     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7852     send_wsc_msg(hapd, addr, m5)
7853
7854     logger.debug("Receive M6 from AP")
7855     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
7856
7857     logger.debug("Send M7 to AP")
7858     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7859     attrs += build_attr_msg_type(WPS_M7)
7860     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7861     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
7862     data = ''
7863     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7864     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
7865     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7866     raw_m7_attrs = attrs
7867     send_wsc_msg(hapd, addr, m7)
7868
7869     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7870
7871 def test_wps_ext_m7_e_snonce2_mismatch(dev, apdev):
7872     """WPS proto: M7 E-SNonce2 mismatch"""
7873     pin = "12345670"
7874     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7875     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7876     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7877
7878     logger.debug("Receive WSC/Start from AP")
7879     msg = get_wsc_msg(hapd)
7880     if msg['wsc_opcode'] != WSC_Start:
7881         raise Exception("Unexpected Op-Code for WSC/Start")
7882
7883     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7884     uuid_e = 16*'\x11'
7885     e_nonce = 16*'\x22'
7886     own_private, e_pk = wsc_dh_init()
7887
7888     logger.debug("Send M1 to AP")
7889     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7890                                 e_nonce, e_pk)
7891     send_wsc_msg(hapd, addr, m1)
7892
7893     logger.debug("Receive M2 from AP")
7894     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7895     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7896     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7897
7898     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7899                                     r_nonce)
7900     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7901
7902     logger.debug("Send M3 to AP")
7903     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7904     attrs += build_attr_msg_type(WPS_M3)
7905     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7906     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7907     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7908     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7909     raw_m3_attrs = attrs
7910     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7911     send_wsc_msg(hapd, addr, m3)
7912
7913     logger.debug("Receive M4 from AP")
7914     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7915
7916     logger.debug("Send M5 to AP")
7917     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7918     attrs += build_attr_msg_type(WPS_M5)
7919     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7920     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7921     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7922     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7923     raw_m5_attrs = attrs
7924     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7925     send_wsc_msg(hapd, addr, m5)
7926
7927     logger.debug("Receive M6 from AP")
7928     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
7929
7930     logger.debug("Send M7 to AP")
7931     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7932     attrs += build_attr_msg_type(WPS_M7)
7933     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7934     data = build_wsc_attr(ATTR_E_SNONCE2, 16*'\x00')
7935     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7936     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
7937     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7938     raw_m7_attrs = attrs
7939     send_wsc_msg(hapd, addr, m7)
7940
7941     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7942
7943 def test_wps_ext_m1_pubkey_oom(dev, apdev):
7944     """WPS proto: M1 PubKey OOM"""
7945     pin = "12345670"
7946     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7947     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7948     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7949
7950     logger.debug("Receive WSC/Start from AP")
7951     msg = get_wsc_msg(hapd)
7952     if msg['wsc_opcode'] != WSC_Start:
7953         raise Exception("Unexpected Op-Code for WSC/Start")
7954
7955     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7956     uuid_e = 16*'\x11'
7957     e_nonce = 16*'\x22'
7958     own_private, e_pk = wsc_dh_init()
7959
7960     logger.debug("Send M1 to AP")
7961     with alloc_fail(hapd, 1, "wpabuf_alloc_copy;wps_process_pubkey"):
7962         m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7963                                     e_nonce, e_pk)
7964         send_wsc_msg(hapd, addr, m1)
7965         wps_wait_eap_failure(hapd, dev[0])
7966
7967 def wps_wait_eap_failure(hapd, dev):
7968     ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7969     if ev is None:
7970         raise Exception("EAP-Failure not reported")
7971     dev.wait_disconnected()
7972
7973 def test_wps_ext_m3_m1(dev, apdev):
7974     """WPS proto: M3 replaced with M1"""
7975     pin = "12345670"
7976     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7977     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7978     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7979
7980     logger.debug("Receive WSC/Start from AP")
7981     msg = get_wsc_msg(hapd)
7982     if msg['wsc_opcode'] != WSC_Start:
7983         raise Exception("Unexpected Op-Code for WSC/Start")
7984
7985     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7986     uuid_e = 16*'\x11'
7987     e_nonce = 16*'\x22'
7988     own_private, e_pk = wsc_dh_init()
7989
7990     logger.debug("Send M1 to AP")
7991     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7992                                 e_nonce, e_pk)
7993     send_wsc_msg(hapd, addr, m1)
7994
7995     logger.debug("Receive M2 from AP")
7996     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7997     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7998     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7999
8000     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8001                                     r_nonce)
8002     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8003
8004     logger.debug("Send M3(M1) to AP")
8005     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8006     attrs += build_attr_msg_type(WPS_M1)
8007     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8008     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8009     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8010     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8011     raw_m3_attrs = attrs
8012     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8013     send_wsc_msg(hapd, addr, m3)
8014
8015     wps_wait_eap_failure(hapd, dev[0])
8016
8017 def test_wps_ext_m5_m3(dev, apdev):
8018     """WPS proto: M5 replaced with M3"""
8019     pin = "12345670"
8020     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8021     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8022     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8023
8024     logger.debug("Receive WSC/Start from AP")
8025     msg = get_wsc_msg(hapd)
8026     if msg['wsc_opcode'] != WSC_Start:
8027         raise Exception("Unexpected Op-Code for WSC/Start")
8028
8029     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8030     uuid_e = 16*'\x11'
8031     e_nonce = 16*'\x22'
8032     own_private, e_pk = wsc_dh_init()
8033
8034     logger.debug("Send M1 to AP")
8035     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8036                                 e_nonce, e_pk)
8037     send_wsc_msg(hapd, addr, m1)
8038
8039     logger.debug("Receive M2 from AP")
8040     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8041     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8042     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8043
8044     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8045                                     r_nonce)
8046     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8047
8048     logger.debug("Send M3 to AP")
8049     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8050     attrs += build_attr_msg_type(WPS_M3)
8051     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8052     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8053     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8054     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8055     raw_m3_attrs = attrs
8056     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8057     send_wsc_msg(hapd, addr, m3)
8058
8059     logger.debug("Receive M4 from AP")
8060     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8061
8062     logger.debug("Send M5(M3) to AP")
8063     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8064     attrs += build_attr_msg_type(WPS_M3)
8065     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8066     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8067     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8068     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8069     raw_m5_attrs = attrs
8070     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8071     send_wsc_msg(hapd, addr, m5)
8072
8073     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8074
8075 def test_wps_ext_m3_m2(dev, apdev):
8076     """WPS proto: M3 replaced with M2"""
8077     pin = "12345670"
8078     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8079     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8080     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8081
8082     logger.debug("Receive WSC/Start from AP")
8083     msg = get_wsc_msg(hapd)
8084     if msg['wsc_opcode'] != WSC_Start:
8085         raise Exception("Unexpected Op-Code for WSC/Start")
8086
8087     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8088     uuid_e = 16*'\x11'
8089     e_nonce = 16*'\x22'
8090     own_private, e_pk = wsc_dh_init()
8091
8092     logger.debug("Send M1 to AP")
8093     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8094                                 e_nonce, e_pk)
8095     send_wsc_msg(hapd, addr, m1)
8096
8097     logger.debug("Receive M2 from AP")
8098     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8099     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8100     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8101
8102     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8103                                     r_nonce)
8104     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8105
8106     logger.debug("Send M3(M2) to AP")
8107     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8108     attrs += build_attr_msg_type(WPS_M2)
8109     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8110     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8111     raw_m3_attrs = attrs
8112     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8113     send_wsc_msg(hapd, addr, m3)
8114
8115     wps_wait_eap_failure(hapd, dev[0])
8116
8117 def test_wps_ext_m3_m5(dev, apdev):
8118     """WPS proto: M3 replaced with M5"""
8119     pin = "12345670"
8120     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8121     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8122     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8123
8124     logger.debug("Receive WSC/Start from AP")
8125     msg = get_wsc_msg(hapd)
8126     if msg['wsc_opcode'] != WSC_Start:
8127         raise Exception("Unexpected Op-Code for WSC/Start")
8128
8129     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8130     uuid_e = 16*'\x11'
8131     e_nonce = 16*'\x22'
8132     own_private, e_pk = wsc_dh_init()
8133
8134     logger.debug("Send M1 to AP")
8135     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8136                                 e_nonce, e_pk)
8137     send_wsc_msg(hapd, addr, m1)
8138
8139     logger.debug("Receive M2 from AP")
8140     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8141     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8142     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8143
8144     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8145                                     r_nonce)
8146     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8147
8148     logger.debug("Send M3(M5) to AP")
8149     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8150     attrs += build_attr_msg_type(WPS_M5)
8151     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8152     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8153     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8154     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8155     raw_m3_attrs = attrs
8156     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8157     send_wsc_msg(hapd, addr, m3)
8158
8159     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8160
8161 def test_wps_ext_m3_m7(dev, apdev):
8162     """WPS proto: M3 replaced with M7"""
8163     pin = "12345670"
8164     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8165     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8166     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8167
8168     logger.debug("Receive WSC/Start from AP")
8169     msg = get_wsc_msg(hapd)
8170     if msg['wsc_opcode'] != WSC_Start:
8171         raise Exception("Unexpected Op-Code for WSC/Start")
8172
8173     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8174     uuid_e = 16*'\x11'
8175     e_nonce = 16*'\x22'
8176     own_private, e_pk = wsc_dh_init()
8177
8178     logger.debug("Send M1 to AP")
8179     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8180                                 e_nonce, e_pk)
8181     send_wsc_msg(hapd, addr, m1)
8182
8183     logger.debug("Receive M2 from AP")
8184     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8185     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8186     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8187
8188     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8189                                     r_nonce)
8190     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8191
8192     logger.debug("Send M3(M7) to AP")
8193     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8194     attrs += build_attr_msg_type(WPS_M7)
8195     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8196     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8197     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8198     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8199     raw_m3_attrs = attrs
8200     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8201     send_wsc_msg(hapd, addr, m3)
8202
8203     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8204
8205 def test_wps_ext_m3_done(dev, apdev):
8206     """WPS proto: M3 replaced with WSC_Done"""
8207     pin = "12345670"
8208     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8209     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8210     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8211
8212     logger.debug("Receive WSC/Start from AP")
8213     msg = get_wsc_msg(hapd)
8214     if msg['wsc_opcode'] != WSC_Start:
8215         raise Exception("Unexpected Op-Code for WSC/Start")
8216
8217     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8218     uuid_e = 16*'\x11'
8219     e_nonce = 16*'\x22'
8220     own_private, e_pk = wsc_dh_init()
8221
8222     logger.debug("Send M1 to AP")
8223     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8224                                 e_nonce, e_pk)
8225     send_wsc_msg(hapd, addr, m1)
8226
8227     logger.debug("Receive M2 from AP")
8228     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8229     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8230     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8231
8232     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8233                                     r_nonce)
8234     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8235
8236     logger.debug("Send M3(WSC_Done) to AP")
8237     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8238     attrs += build_attr_msg_type(WPS_WSC_DONE)
8239     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8240     raw_m3_attrs = attrs
8241     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8242     send_wsc_msg(hapd, addr, m3)
8243
8244     wps_wait_eap_failure(hapd, dev[0])
8245
8246 def test_wps_ext_m2_nack_invalid(dev, apdev):
8247     """WPS proto: M2 followed by invalid NACK"""
8248     pin = "12345670"
8249     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8250     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8251     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8252
8253     logger.debug("Receive WSC/Start from AP")
8254     msg = get_wsc_msg(hapd)
8255     if msg['wsc_opcode'] != WSC_Start:
8256         raise Exception("Unexpected Op-Code for WSC/Start")
8257
8258     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8259     uuid_e = 16*'\x11'
8260     e_nonce = 16*'\x22'
8261     own_private, e_pk = wsc_dh_init()
8262
8263     logger.debug("Send M1 to AP")
8264     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8265                                 e_nonce, e_pk)
8266     send_wsc_msg(hapd, addr, m1)
8267
8268     logger.debug("Receive M2 from AP")
8269     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8270     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8271     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8272
8273     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8274                                     r_nonce)
8275     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8276
8277     logger.debug("Send WSC_NACK to AP")
8278     attrs = '\x10\x00\x00'
8279     nack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_NACK)
8280     send_wsc_msg(hapd, addr, nack)
8281
8282     wps_wait_eap_failure(hapd, dev[0])
8283
8284 def test_wps_ext_m2_nack_no_msg_type(dev, apdev):
8285     """WPS proto: M2 followed by NACK without Msg Type"""
8286     pin = "12345670"
8287     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8288     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8289     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8290
8291     logger.debug("Receive WSC/Start from AP")
8292     msg = get_wsc_msg(hapd)
8293     if msg['wsc_opcode'] != WSC_Start:
8294         raise Exception("Unexpected Op-Code for WSC/Start")
8295
8296     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8297     uuid_e = 16*'\x11'
8298     e_nonce = 16*'\x22'
8299     own_private, e_pk = wsc_dh_init()
8300
8301     logger.debug("Send M1 to AP")
8302     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8303                                 e_nonce, e_pk)
8304     send_wsc_msg(hapd, addr, m1)
8305
8306     logger.debug("Receive M2 from AP")
8307     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8308     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8309     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8310
8311     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8312                                     r_nonce)
8313     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8314
8315     logger.debug("Send WSC_NACK to AP")
8316     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8317                             msg_type=None, eap_code=2)
8318     send_wsc_msg(hapd, addr, nack)
8319
8320     wps_wait_eap_failure(hapd, dev[0])
8321
8322 def test_wps_ext_m2_nack_invalid_msg_type(dev, apdev):
8323     """WPS proto: M2 followed by NACK with invalid Msg Type"""
8324     pin = "12345670"
8325     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8326     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8327     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8328
8329     logger.debug("Receive WSC/Start from AP")
8330     msg = get_wsc_msg(hapd)
8331     if msg['wsc_opcode'] != WSC_Start:
8332         raise Exception("Unexpected Op-Code for WSC/Start")
8333
8334     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8335     uuid_e = 16*'\x11'
8336     e_nonce = 16*'\x22'
8337     own_private, e_pk = wsc_dh_init()
8338
8339     logger.debug("Send M1 to AP")
8340     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8341                                 e_nonce, e_pk)
8342     send_wsc_msg(hapd, addr, m1)
8343
8344     logger.debug("Receive M2 from AP")
8345     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8346     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8347     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8348
8349     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8350                                     r_nonce)
8351     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8352
8353     logger.debug("Send WSC_NACK to AP")
8354     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8355                             msg_type=WPS_WSC_ACK, eap_code=2)
8356     send_wsc_msg(hapd, addr, nack)
8357
8358     wps_wait_eap_failure(hapd, dev[0])
8359
8360 def test_wps_ext_m2_nack_e_nonce_mismatch(dev, apdev):
8361     """WPS proto: M2 followed by NACK with e-nonce mismatch"""
8362     pin = "12345670"
8363     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8364     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8365     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8366
8367     logger.debug("Receive WSC/Start from AP")
8368     msg = get_wsc_msg(hapd)
8369     if msg['wsc_opcode'] != WSC_Start:
8370         raise Exception("Unexpected Op-Code for WSC/Start")
8371
8372     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8373     uuid_e = 16*'\x11'
8374     e_nonce = 16*'\x22'
8375     own_private, e_pk = wsc_dh_init()
8376
8377     logger.debug("Send M1 to AP")
8378     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8379                                 e_nonce, e_pk)
8380     send_wsc_msg(hapd, addr, m1)
8381
8382     logger.debug("Receive M2 from AP")
8383     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8384     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8385     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8386
8387     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8388                                     r_nonce)
8389     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8390
8391     logger.debug("Send WSC_NACK to AP")
8392     nack,attrs = build_nack(msg['eap_identifier'], 16*'\x00', r_nonce,
8393                             eap_code=2)
8394     send_wsc_msg(hapd, addr, nack)
8395
8396     wps_wait_eap_failure(hapd, dev[0])
8397
8398 def test_wps_ext_m2_nack_no_config_error(dev, apdev):
8399     """WPS proto: M2 followed by NACK without Config Error"""
8400     pin = "12345670"
8401     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8402     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8403     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8404
8405     logger.debug("Receive WSC/Start from AP")
8406     msg = get_wsc_msg(hapd)
8407     if msg['wsc_opcode'] != WSC_Start:
8408         raise Exception("Unexpected Op-Code for WSC/Start")
8409
8410     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8411     uuid_e = 16*'\x11'
8412     e_nonce = 16*'\x22'
8413     own_private, e_pk = wsc_dh_init()
8414
8415     logger.debug("Send M1 to AP")
8416     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8417                                 e_nonce, e_pk)
8418     send_wsc_msg(hapd, addr, m1)
8419
8420     logger.debug("Receive M2 from AP")
8421     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8422     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8423     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8424
8425     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8426                                     r_nonce)
8427     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8428
8429     logger.debug("Send WSC_NACK to AP")
8430     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8431                             config_error=None, eap_code=2)
8432     send_wsc_msg(hapd, addr, nack)
8433
8434     wps_wait_eap_failure(hapd, dev[0])
8435
8436 def test_wps_ext_m2_ack_invalid(dev, apdev):
8437     """WPS proto: M2 followed by invalid ACK"""
8438     pin = "12345670"
8439     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8440     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8441     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8442
8443     logger.debug("Receive WSC/Start from AP")
8444     msg = get_wsc_msg(hapd)
8445     if msg['wsc_opcode'] != WSC_Start:
8446         raise Exception("Unexpected Op-Code for WSC/Start")
8447
8448     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8449     uuid_e = 16*'\x11'
8450     e_nonce = 16*'\x22'
8451     own_private, e_pk = wsc_dh_init()
8452
8453     logger.debug("Send M1 to AP")
8454     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8455                                 e_nonce, e_pk)
8456     send_wsc_msg(hapd, addr, m1)
8457
8458     logger.debug("Receive M2 from AP")
8459     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8460     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8461     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8462
8463     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8464                                     r_nonce)
8465     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8466
8467     logger.debug("Send WSC_ACK to AP")
8468     attrs = '\x10\x00\x00'
8469     ack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_ACK)
8470     send_wsc_msg(hapd, addr, ack)
8471
8472     wps_wait_eap_failure(hapd, dev[0])
8473
8474 def test_wps_ext_m2_ack(dev, apdev):
8475     """WPS proto: M2 followed by ACK"""
8476     pin = "12345670"
8477     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8478     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8479     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8480
8481     logger.debug("Receive WSC/Start from AP")
8482     msg = get_wsc_msg(hapd)
8483     if msg['wsc_opcode'] != WSC_Start:
8484         raise Exception("Unexpected Op-Code for WSC/Start")
8485
8486     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8487     uuid_e = 16*'\x11'
8488     e_nonce = 16*'\x22'
8489     own_private, e_pk = wsc_dh_init()
8490
8491     logger.debug("Send M1 to AP")
8492     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8493                                 e_nonce, e_pk)
8494     send_wsc_msg(hapd, addr, m1)
8495
8496     logger.debug("Receive M2 from AP")
8497     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8498     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8499     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8500
8501     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8502                                     r_nonce)
8503     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8504
8505     logger.debug("Send WSC_ACK to AP")
8506     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce, eap_code=2)
8507     send_wsc_msg(hapd, addr, ack)
8508
8509     wps_wait_eap_failure(hapd, dev[0])
8510
8511 def test_wps_ext_m2_ack_no_msg_type(dev, apdev):
8512     """WPS proto: M2 followed by ACK missing Msg Type"""
8513     pin = "12345670"
8514     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8515     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8516     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8517
8518     logger.debug("Receive WSC/Start from AP")
8519     msg = get_wsc_msg(hapd)
8520     if msg['wsc_opcode'] != WSC_Start:
8521         raise Exception("Unexpected Op-Code for WSC/Start")
8522
8523     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8524     uuid_e = 16*'\x11'
8525     e_nonce = 16*'\x22'
8526     own_private, e_pk = wsc_dh_init()
8527
8528     logger.debug("Send M1 to AP")
8529     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8530                                 e_nonce, e_pk)
8531     send_wsc_msg(hapd, addr, m1)
8532
8533     logger.debug("Receive M2 from AP")
8534     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8535     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8536     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8537
8538     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8539                                     r_nonce)
8540     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8541
8542     logger.debug("Send WSC_ACK to AP")
8543     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8544                           msg_type=None, eap_code=2)
8545     send_wsc_msg(hapd, addr, ack)
8546
8547     wps_wait_eap_failure(hapd, dev[0])
8548
8549 def test_wps_ext_m2_ack_invalid_msg_type(dev, apdev):
8550     """WPS proto: M2 followed by ACK with invalid Msg Type"""
8551     pin = "12345670"
8552     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8553     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8554     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8555
8556     logger.debug("Receive WSC/Start from AP")
8557     msg = get_wsc_msg(hapd)
8558     if msg['wsc_opcode'] != WSC_Start:
8559         raise Exception("Unexpected Op-Code for WSC/Start")
8560
8561     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8562     uuid_e = 16*'\x11'
8563     e_nonce = 16*'\x22'
8564     own_private, e_pk = wsc_dh_init()
8565
8566     logger.debug("Send M1 to AP")
8567     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8568                                 e_nonce, e_pk)
8569     send_wsc_msg(hapd, addr, m1)
8570
8571     logger.debug("Receive M2 from AP")
8572     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8573     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8574     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8575
8576     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8577                                     r_nonce)
8578     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8579
8580     logger.debug("Send WSC_ACK to AP")
8581     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8582                           msg_type=WPS_WSC_NACK, eap_code=2)
8583     send_wsc_msg(hapd, addr, ack)
8584
8585     wps_wait_eap_failure(hapd, dev[0])
8586
8587 def test_wps_ext_m2_ack_e_nonce_mismatch(dev, apdev):
8588     """WPS proto: M2 followed by ACK with e-nonce mismatch"""
8589     pin = "12345670"
8590     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8591     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8592     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8593
8594     logger.debug("Receive WSC/Start from AP")
8595     msg = get_wsc_msg(hapd)
8596     if msg['wsc_opcode'] != WSC_Start:
8597         raise Exception("Unexpected Op-Code for WSC/Start")
8598
8599     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8600     uuid_e = 16*'\x11'
8601     e_nonce = 16*'\x22'
8602     own_private, e_pk = wsc_dh_init()
8603
8604     logger.debug("Send M1 to AP")
8605     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8606                                 e_nonce, e_pk)
8607     send_wsc_msg(hapd, addr, m1)
8608
8609     logger.debug("Receive M2 from AP")
8610     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8611     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8612     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8613
8614     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8615                                     r_nonce)
8616     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8617
8618     logger.debug("Send WSC_ACK to AP")
8619     ack,attrs = build_ack(msg['eap_identifier'], 16*'\x00', r_nonce,
8620                           eap_code=2)
8621     send_wsc_msg(hapd, addr, ack)
8622
8623     wps_wait_eap_failure(hapd, dev[0])
8624
8625 def test_wps_ext_m1_invalid(dev, apdev):
8626     """WPS proto: M1 failing parsing"""
8627     pin = "12345670"
8628     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8629     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8630     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8631
8632     logger.debug("Receive WSC/Start from AP")
8633     msg = get_wsc_msg(hapd)
8634     if msg['wsc_opcode'] != WSC_Start:
8635         raise Exception("Unexpected Op-Code for WSC/Start")
8636
8637     logger.debug("Send M1 to AP")
8638     attrs = '\x10\x00\x00'
8639     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8640     send_wsc_msg(hapd, addr, m1)
8641
8642     wps_wait_eap_failure(hapd, dev[0])
8643
8644 def test_wps_ext_m1_missing_msg_type(dev, apdev):
8645     """WPS proto: M1 missing Msg Type"""
8646     pin = "12345670"
8647     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8648     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8649     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8650
8651     logger.debug("Receive WSC/Start from AP")
8652     msg = get_wsc_msg(hapd)
8653     if msg['wsc_opcode'] != WSC_Start:
8654         raise Exception("Unexpected Op-Code for WSC/Start")
8655
8656     logger.debug("Send M1 to AP")
8657     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8658     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8659     send_wsc_msg(hapd, addr, m1)
8660
8661     wps_wait_ap_nack(hapd, dev[0], 16*'\x00', 16*'\x00')
8662
8663 def wps_ext_wsc_done(dev, apdev):
8664     pin = "12345670"
8665     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8666     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8667     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8668
8669     logger.debug("Receive WSC/Start from AP")
8670     msg = get_wsc_msg(hapd)
8671     if msg['wsc_opcode'] != WSC_Start:
8672         raise Exception("Unexpected Op-Code for WSC/Start")
8673
8674     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8675     uuid_e = 16*'\x11'
8676     e_nonce = 16*'\x22'
8677     own_private, e_pk = wsc_dh_init()
8678
8679     logger.debug("Send M1 to AP")
8680     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8681                                 e_nonce, e_pk)
8682     send_wsc_msg(hapd, addr, m1)
8683
8684     logger.debug("Receive M2 from AP")
8685     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8686     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8687     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8688
8689     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8690                                     r_nonce)
8691     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8692
8693     logger.debug("Send M3 to AP")
8694     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8695     attrs += build_attr_msg_type(WPS_M3)
8696     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8697     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8698     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8699     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8700     raw_m3_attrs = attrs
8701     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8702     send_wsc_msg(hapd, addr, m3)
8703
8704     logger.debug("Receive M4 from AP")
8705     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8706
8707     logger.debug("Send M5 to AP")
8708     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8709     attrs += build_attr_msg_type(WPS_M5)
8710     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8711     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8712     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8713     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8714     raw_m5_attrs = attrs
8715     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8716     send_wsc_msg(hapd, addr, m5)
8717
8718     logger.debug("Receive M6 from AP")
8719     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8720
8721     logger.debug("Send M7 to AP")
8722     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8723     attrs += build_attr_msg_type(WPS_M7)
8724     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8725     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8726     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8727     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8728     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8729     raw_m7_attrs = attrs
8730     send_wsc_msg(hapd, addr, m7)
8731
8732     logger.debug("Receive M8 from AP")
8733     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
8734     return hapd, msg, e_nonce, r_nonce
8735
8736 def test_wps_ext_wsc_done_invalid(dev, apdev):
8737     """WPS proto: invalid WSC_Done"""
8738     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8739
8740     logger.debug("Send WSC_Done to AP")
8741     attrs = '\x10\x00\x00'
8742     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8743     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8744
8745     wps_wait_eap_failure(hapd, dev[0])
8746
8747 def test_wps_ext_wsc_done_no_msg_type(dev, apdev):
8748     """WPS proto: invalid WSC_Done"""
8749     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8750
8751     logger.debug("Send WSC_Done to AP")
8752     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8753     #attrs += build_attr_msg_type(WPS_WSC_DONE)
8754     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8755     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8756     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8757     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8758
8759     wps_wait_eap_failure(hapd, dev[0])
8760
8761 def test_wps_ext_wsc_done_wrong_msg_type(dev, apdev):
8762     """WPS proto: WSC_Done with wrong Msg Type"""
8763     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8764
8765     logger.debug("Send WSC_Done to AP")
8766     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8767     attrs += build_attr_msg_type(WPS_WSC_ACK)
8768     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8769     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8770     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8771     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8772
8773     wps_wait_eap_failure(hapd, dev[0])
8774
8775 def test_wps_ext_wsc_done_no_e_nonce(dev, apdev):
8776     """WPS proto: WSC_Done without e_nonce"""
8777     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8778
8779     logger.debug("Send WSC_Done to AP")
8780     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8781     attrs += build_attr_msg_type(WPS_WSC_DONE)
8782     #attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8783     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8784     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8785     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8786
8787     wps_wait_eap_failure(hapd, dev[0])
8788
8789 def test_wps_ext_wsc_done_no_r_nonce(dev, apdev):
8790     """WPS proto: WSC_Done without r_nonce"""
8791     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8792
8793     logger.debug("Send WSC_Done to AP")
8794     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8795     attrs += build_attr_msg_type(WPS_WSC_DONE)
8796     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8797     #attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8798     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8799     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8800
8801     wps_wait_eap_failure(hapd, dev[0])
8802
8803 def test_wps_ext_m7_no_encr_settings(dev, apdev):
8804     """WPS proto: M7 without Encr Settings"""
8805     pin = "12345670"
8806     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8807     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8808     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8809
8810     logger.debug("Receive WSC/Start from AP")
8811     msg = get_wsc_msg(hapd)
8812     if msg['wsc_opcode'] != WSC_Start:
8813         raise Exception("Unexpected Op-Code for WSC/Start")
8814
8815     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8816     uuid_e = 16*'\x11'
8817     e_nonce = 16*'\x22'
8818     own_private, e_pk = wsc_dh_init()
8819
8820     logger.debug("Send M1 to AP")
8821     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8822                                 e_nonce, e_pk)
8823     send_wsc_msg(hapd, addr, m1)
8824
8825     logger.debug("Receive M2 from AP")
8826     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8827     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8828     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8829
8830     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8831                                     r_nonce)
8832     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8833
8834     logger.debug("Send M3 to AP")
8835     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8836     attrs += build_attr_msg_type(WPS_M3)
8837     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8838     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8839     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8840     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8841     raw_m3_attrs = attrs
8842     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8843     send_wsc_msg(hapd, addr, m3)
8844
8845     logger.debug("Receive M4 from AP")
8846     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8847
8848     logger.debug("Send M5 to AP")
8849     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8850     attrs += build_attr_msg_type(WPS_M5)
8851     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8852     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8853     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8854     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8855     raw_m5_attrs = attrs
8856     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8857     send_wsc_msg(hapd, addr, m5)
8858
8859     logger.debug("Receive M6 from AP")
8860     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8861
8862     logger.debug("Send M7 to AP")
8863     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8864     attrs += build_attr_msg_type(WPS_M7)
8865     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8866     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8867     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8868     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8869     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8870     raw_m7_attrs = attrs
8871     send_wsc_msg(hapd, addr, m7)
8872
8873     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8874
8875 def test_wps_ext_m1_workaround(dev, apdev):
8876     """WPS proto: M1 Manufacturer/Model workaround"""
8877     pin = "12345670"
8878     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8879     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8880     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8881
8882     logger.debug("Receive WSC/Start from AP")
8883     msg = get_wsc_msg(hapd)
8884     if msg['wsc_opcode'] != WSC_Start:
8885         raise Exception("Unexpected Op-Code for WSC/Start")
8886
8887     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8888     uuid_e = 16*'\x11'
8889     e_nonce = 16*'\x22'
8890     own_private, e_pk = wsc_dh_init()
8891
8892     logger.debug("Send M1 to AP")
8893     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8894                                 e_nonce, e_pk, manufacturer='Apple TEST',
8895                                 model_name='AirPort', config_methods='\xff\xff')
8896     send_wsc_msg(hapd, addr, m1)
8897
8898     logger.debug("Receive M2 from AP")
8899     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)