tests: WPS ER SetSelectedRegistrar OOM
[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_er_set_sel_reg_oom(dev, apdev):
1747     """WPS ER SetSelectedRegistrar OOM"""
1748     try:
1749         _test_ap_wps_er_set_sel_reg_oom(dev, apdev)
1750     finally:
1751         dev[0].request("WPS_ER_STOP")
1752
1753 def _test_ap_wps_er_set_sel_reg_oom(dev, apdev):
1754     ssid = "wps-er-add-enrollee"
1755     ap_pin = "12345670"
1756     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1757     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1758                "wpa_passphrase": "12345678", "wpa": "2",
1759                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1760                "device_name": "Wireless AP", "manufacturer": "Company",
1761                "model_name": "WAP", "model_number": "123",
1762                "serial_number": "12345", "device_type": "6-0050F204-1",
1763                "os_version": "01020300",
1764                "config_methods": "label push_button",
1765                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1766     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1767     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1768     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1769
1770     dev[0].request("WPS_ER_START ifname=lo")
1771     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
1772     if ev is None:
1773         raise Exception("AP not discovered")
1774
1775     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1776     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1777     if ev is None:
1778         raise Exception("AP learn timed out")
1779     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1780     if ev is None:
1781         raise Exception("WPS-FAIL timed out")
1782     time.sleep(0.1)
1783
1784     for func in [ "http_client_url_parse;wps_er_send_set_sel_reg",
1785                   "wps_er_soap_hdr;wps_er_send_set_sel_reg",
1786                   "http_client_addr;wps_er_send_set_sel_reg",
1787                   "wpabuf_alloc;wps_er_set_sel_reg" ]:
1788         with alloc_fail(dev[0], 1, func):
1789             if "OK" not in dev[0].request("WPS_ER_PBC " + ap_uuid):
1790                 raise Exception("WPS_ER_PBC failed")
1791             ev = dev[0].wait_event(["WPS-PBC-ACTIVE"], timeout=3)
1792             if ev is None:
1793                 raise Exception("WPS-PBC-ACTIVE not seen")
1794
1795     dev[0].request("WPS_ER_STOP")
1796
1797 def test_ap_wps_fragmentation(dev, apdev):
1798     """WPS with fragmentation in EAP-WSC and mixed mode WPA+WPA2"""
1799     ssid = "test-wps-fragmentation"
1800     appin = "12345670"
1801     hostapd.add_ap(apdev[0]['ifname'],
1802                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1803                      "wpa_passphrase": "12345678", "wpa": "3",
1804                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1805                      "wpa_pairwise": "TKIP", "ap_pin": appin,
1806                      "fragment_size": "50" })
1807     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1808     logger.info("WPS provisioning step (PBC)")
1809     hapd.request("WPS_PBC")
1810     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1811     dev[0].dump_monitor()
1812     dev[0].request("SET wps_fragment_size 50")
1813     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1814     dev[0].wait_connected(timeout=30)
1815     status = dev[0].get_status()
1816     if status['wpa_state'] != 'COMPLETED':
1817         raise Exception("Not fully connected")
1818     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1819         raise Exception("Unexpected encryption configuration")
1820     if status['key_mgmt'] != 'WPA2-PSK':
1821         raise Exception("Unexpected key_mgmt")
1822
1823     logger.info("WPS provisioning step (PIN)")
1824     pin = dev[1].wps_read_pin()
1825     hapd.request("WPS_PIN any " + pin)
1826     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1827     dev[1].request("SET wps_fragment_size 50")
1828     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1829     dev[1].wait_connected(timeout=30)
1830     status = dev[1].get_status()
1831     if status['wpa_state'] != 'COMPLETED':
1832         raise Exception("Not fully connected")
1833     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1834         raise Exception("Unexpected encryption configuration")
1835     if status['key_mgmt'] != 'WPA2-PSK':
1836         raise Exception("Unexpected key_mgmt")
1837
1838     logger.info("WPS connection as registrar")
1839     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1840     dev[2].request("SET wps_fragment_size 50")
1841     dev[2].wps_reg(apdev[0]['bssid'], appin)
1842     status = dev[2].get_status()
1843     if status['wpa_state'] != 'COMPLETED':
1844         raise Exception("Not fully connected")
1845     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1846         raise Exception("Unexpected encryption configuration")
1847     if status['key_mgmt'] != 'WPA2-PSK':
1848         raise Exception("Unexpected key_mgmt")
1849
1850 def test_ap_wps_new_version_sta(dev, apdev):
1851     """WPS compatibility with new version number on the station"""
1852     ssid = "test-wps-ver"
1853     hostapd.add_ap(apdev[0]['ifname'],
1854                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1855                      "wpa_passphrase": "12345678", "wpa": "2",
1856                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1857     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1858     logger.info("WPS provisioning step")
1859     hapd.request("WPS_PBC")
1860     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1861     dev[0].dump_monitor()
1862     dev[0].request("SET wps_version_number 0x43")
1863     dev[0].request("SET wps_vendor_ext_m1 000137100100020001")
1864     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1865     dev[0].wait_connected(timeout=30)
1866
1867 def test_ap_wps_new_version_ap(dev, apdev):
1868     """WPS compatibility with new version number on the AP"""
1869     ssid = "test-wps-ver"
1870     hostapd.add_ap(apdev[0]['ifname'],
1871                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1872                      "wpa_passphrase": "12345678", "wpa": "2",
1873                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1874     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1875     logger.info("WPS provisioning step")
1876     if "FAIL" in hapd.request("SET wps_version_number 0x43"):
1877         raise Exception("Failed to enable test functionality")
1878     hapd.request("WPS_PBC")
1879     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1880     dev[0].dump_monitor()
1881     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1882     dev[0].wait_connected(timeout=30)
1883     hapd.request("SET wps_version_number 0x20")
1884
1885 def test_ap_wps_check_pin(dev, apdev):
1886     """Verify PIN checking through control interface"""
1887     hostapd.add_ap(apdev[0]['ifname'],
1888                    { "ssid": "wps", "eap_server": "1", "wps_state": "2",
1889                      "wpa_passphrase": "12345678", "wpa": "2",
1890                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1891     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1892     for t in [ ("12345670", "12345670"),
1893                ("12345678", "FAIL-CHECKSUM"),
1894                ("12345", "FAIL"),
1895                ("123456789", "FAIL"),
1896                ("1234-5670", "12345670"),
1897                ("1234 5670", "12345670"),
1898                ("1-2.3:4 5670", "12345670") ]:
1899         res = hapd.request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1900         res2 = dev[0].request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1901         if res != res2:
1902             raise Exception("Unexpected difference in WPS_CHECK_PIN responses")
1903         if res != t[1]:
1904             raise Exception("Incorrect WPS_CHECK_PIN response {} (expected {})".format(res, t[1]))
1905
1906     if "FAIL" not in hapd.request("WPS_CHECK_PIN 12345"):
1907         raise Exception("Unexpected WPS_CHECK_PIN success")
1908     if "FAIL" not in hapd.request("WPS_CHECK_PIN 123456789"):
1909         raise Exception("Unexpected WPS_CHECK_PIN success")
1910
1911     for i in range(0, 10):
1912         pin = dev[0].request("WPS_PIN get")
1913         rpin = dev[0].request("WPS_CHECK_PIN " + pin).rstrip('\n')
1914         if pin != rpin:
1915             raise Exception("Random PIN validation failed for " + pin)
1916
1917 def test_ap_wps_wep_config(dev, apdev):
1918     """WPS 2.0 AP rejecting WEP configuration"""
1919     ssid = "test-wps-config"
1920     appin = "12345670"
1921     hostapd.add_ap(apdev[0]['ifname'],
1922                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1923                      "ap_pin": appin})
1924     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1925     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1926     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
1927                    "hello", no_wait=True)
1928     ev = hapd.wait_event(["WPS-FAIL"], timeout=15)
1929     if ev is None:
1930         raise Exception("WPS-FAIL timed out")
1931     if "reason=2" not in ev:
1932         raise Exception("Unexpected reason code in WPS-FAIL")
1933     status = hapd.request("WPS_GET_STATUS")
1934     if "Last WPS result: Failed" not in status:
1935         raise Exception("WPS failure result not shown correctly")
1936     if "Failure Reason: WEP Prohibited" not in status:
1937         raise Exception("Failure reason not reported correctly")
1938     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
1939         raise Exception("Peer address not shown correctly")
1940
1941 def test_ap_wps_wep_enroll(dev, apdev):
1942     """WPS 2.0 STA rejecting WEP configuration"""
1943     ssid = "test-wps-wep"
1944     hostapd.add_ap(apdev[0]['ifname'],
1945                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1946                      "skip_cred_build": "1", "extra_cred": "wps-wep-cred" })
1947     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1948     hapd.request("WPS_PBC")
1949     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1950     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1951     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1952     if ev is None:
1953         raise Exception("WPS-FAIL event timed out")
1954     if "msg=12" not in ev or "reason=2 (WEP Prohibited)" not in ev:
1955         raise Exception("Unexpected WPS-FAIL event: " + ev)
1956
1957 def test_ap_wps_ie_fragmentation(dev, apdev):
1958     """WPS AP using fragmented WPS IE"""
1959     ssid = "test-wps-ie-fragmentation"
1960     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1961                "wpa_passphrase": "12345678", "wpa": "2",
1962                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1963                "device_name": "1234567890abcdef1234567890abcdef",
1964                "manufacturer": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
1965                "model_name": "1234567890abcdef1234567890abcdef",
1966                "model_number": "1234567890abcdef1234567890abcdef",
1967                "serial_number": "1234567890abcdef1234567890abcdef" }
1968     hostapd.add_ap(apdev[0]['ifname'], params)
1969     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1970     hapd.request("WPS_PBC")
1971     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1972     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1973     dev[0].wait_connected(timeout=30)
1974     bss = dev[0].get_bss(apdev[0]['bssid'])
1975     if "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1976         logger.info("Device Name not received correctly")
1977         logger.info(bss)
1978         # This can fail if Probe Response frame is missed and Beacon frame was
1979         # used to fill in the BSS entry. This can happen, e.g., during heavy
1980         # load every now and then and is not really an error, so try to
1981         # workaround by runnign another scan.
1982         dev[0].scan(freq="2412", only_new=True)
1983         bss = dev[0].get_bss(apdev[0]['bssid'])
1984         if not bss or "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1985             logger.info(bss)
1986             raise Exception("Device Name not received correctly")
1987     if len(re.findall("dd..0050f204", bss['ie'])) != 2:
1988         raise Exception("Unexpected number of WPS IEs")
1989
1990 def get_psk(pskfile):
1991     psks = {}
1992     with open(pskfile, "r") as f:
1993         lines = f.read().splitlines()
1994         for l in lines:
1995             if l == "# WPA PSKs":
1996                 continue
1997             (addr,psk) = l.split(' ')
1998             psks[addr] = psk
1999     return psks
2000
2001 def test_ap_wps_per_station_psk(dev, apdev):
2002     """WPS PBC provisioning with per-station PSK"""
2003     addr0 = dev[0].own_addr()
2004     addr1 = dev[1].own_addr()
2005     addr2 = dev[2].own_addr()
2006     ssid = "wps"
2007     appin = "12345670"
2008     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
2009     try:
2010         os.remove(pskfile)
2011     except:
2012         pass
2013
2014     try:
2015         with open(pskfile, "w") as f:
2016             f.write("# WPA PSKs\n")
2017
2018         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2019                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
2020                    "rsn_pairwise": "CCMP", "ap_pin": appin,
2021                    "wpa_psk_file": pskfile }
2022         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2023
2024         logger.info("First enrollee")
2025         hapd.request("WPS_PBC")
2026         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2027         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2028         dev[0].wait_connected(timeout=30)
2029
2030         logger.info("Second enrollee")
2031         hapd.request("WPS_PBC")
2032         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2033         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2034         dev[1].wait_connected(timeout=30)
2035
2036         logger.info("External registrar")
2037         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2038         dev[2].wps_reg(apdev[0]['bssid'], appin)
2039
2040         logger.info("Verifying PSK results")
2041         psks = get_psk(pskfile)
2042         if addr0 not in psks:
2043             raise Exception("No PSK recorded for sta0")
2044         if addr1 not in psks:
2045             raise Exception("No PSK recorded for sta1")
2046         if addr2 not in psks:
2047             raise Exception("No PSK recorded for sta2")
2048         if psks[addr0] == psks[addr1]:
2049             raise Exception("Same PSK recorded for sta0 and sta1")
2050         if psks[addr0] == psks[addr2]:
2051             raise Exception("Same PSK recorded for sta0 and sta2")
2052         if psks[addr1] == psks[addr2]:
2053             raise Exception("Same PSK recorded for sta1 and sta2")
2054
2055         dev[0].request("REMOVE_NETWORK all")
2056         logger.info("Second external registrar")
2057         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2058         dev[0].wps_reg(apdev[0]['bssid'], appin)
2059         psks2 = get_psk(pskfile)
2060         if addr0 not in psks2:
2061             raise Exception("No PSK recorded for sta0(reg)")
2062         if psks[addr0] == psks2[addr0]:
2063             raise Exception("Same PSK recorded for sta0(enrollee) and sta0(reg)")
2064     finally:
2065         os.remove(pskfile)
2066
2067 def test_ap_wps_per_station_psk_failure(dev, apdev):
2068     """WPS PBC provisioning with per-station PSK (file not writable)"""
2069     addr0 = dev[0].p2p_dev_addr()
2070     addr1 = dev[1].p2p_dev_addr()
2071     addr2 = dev[2].p2p_dev_addr()
2072     ssid = "wps"
2073     appin = "12345670"
2074     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
2075     try:
2076         os.remove(pskfile)
2077     except:
2078         pass
2079
2080     try:
2081         with open(pskfile, "w") as f:
2082             f.write("# WPA PSKs\n")
2083
2084         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2085                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
2086                    "rsn_pairwise": "CCMP", "ap_pin": appin,
2087                    "wpa_psk_file": pskfile }
2088         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2089         if "FAIL" in hapd.request("SET wpa_psk_file /tmp/does/not/exists/ap_wps_per_enrollee_psk_failure.psk_file"):
2090             raise Exception("Failed to set wpa_psk_file")
2091
2092         logger.info("First enrollee")
2093         hapd.request("WPS_PBC")
2094         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2095         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2096         dev[0].wait_connected(timeout=30)
2097
2098         logger.info("Second enrollee")
2099         hapd.request("WPS_PBC")
2100         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2101         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2102         dev[1].wait_connected(timeout=30)
2103
2104         logger.info("External registrar")
2105         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2106         dev[2].wps_reg(apdev[0]['bssid'], appin)
2107
2108         logger.info("Verifying PSK results")
2109         psks = get_psk(pskfile)
2110         if len(psks) > 0:
2111             raise Exception("PSK recorded unexpectedly")
2112     finally:
2113         os.remove(pskfile)
2114
2115 def test_ap_wps_pin_request_file(dev, apdev):
2116     """WPS PIN provisioning with configured AP"""
2117     ssid = "wps"
2118     pinfile = "/tmp/ap_wps_pin_request_file.log"
2119     if os.path.exists(pinfile):
2120         os.remove(pinfile)
2121     hostapd.add_ap(apdev[0]['ifname'],
2122                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2123                      "wps_pin_requests": pinfile,
2124                      "wpa_passphrase": "12345678", "wpa": "2",
2125                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2126     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2127     uuid = dev[0].get_status_field("uuid")
2128     pin = dev[0].wps_read_pin()
2129     try:
2130         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2131         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
2132         ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=15)
2133         if ev is None:
2134             raise Exception("PIN needed event not shown")
2135         if uuid not in ev:
2136             raise Exception("UUID mismatch")
2137         dev[0].request("WPS_CANCEL")
2138         success = False
2139         with open(pinfile, "r") as f:
2140             lines = f.readlines()
2141             for l in lines:
2142                 if uuid in l:
2143                     success = True
2144                     break
2145         if not success:
2146             raise Exception("PIN request entry not in the log file")
2147     finally:
2148         try:
2149             os.remove(pinfile)
2150         except:
2151             pass
2152
2153 def test_ap_wps_auto_setup_with_config_file(dev, apdev):
2154     """WPS auto-setup with configuration file"""
2155     conffile = "/tmp/ap_wps_auto_setup_with_config_file.conf"
2156     ifname = apdev[0]['ifname']
2157     try:
2158         with open(conffile, "w") as f:
2159             f.write("driver=nl80211\n")
2160             f.write("hw_mode=g\n")
2161             f.write("channel=1\n")
2162             f.write("ieee80211n=1\n")
2163             f.write("interface=%s\n" % ifname)
2164             f.write("ctrl_interface=/var/run/hostapd\n")
2165             f.write("ssid=wps\n")
2166             f.write("eap_server=1\n")
2167             f.write("wps_state=1\n")
2168         hostapd.add_bss('phy3', ifname, conffile)
2169         hapd = hostapd.Hostapd(ifname)
2170         hapd.request("WPS_PBC")
2171         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2172         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2173         dev[0].wait_connected(timeout=30)
2174         with open(conffile, "r") as f:
2175             lines = f.read().splitlines()
2176             vals = dict()
2177             for l in lines:
2178                 try:
2179                     [name,value] = l.split('=', 1)
2180                     vals[name] = value
2181                 except ValueError, e:
2182                     if "# WPS configuration" in l:
2183                         pass
2184                     else:
2185                         raise Exception("Unexpected configuration line: " + l)
2186         if vals['ieee80211n'] != '1' or vals['wps_state'] != '2' or "WPA-PSK" not in vals['wpa_key_mgmt']:
2187             raise Exception("Incorrect configuration: " + str(vals))
2188     finally:
2189         try:
2190             os.remove(conffile)
2191         except:
2192             pass
2193
2194 def test_ap_wps_pbc_timeout(dev, apdev, params):
2195     """wpa_supplicant PBC walk time and WPS ER SelReg timeout [long]"""
2196     if not params['long']:
2197         raise HwsimSkip("Skip test case with long duration due to --long not specified")
2198     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2199     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2200
2201     location = ssdp_get_location(ap_uuid)
2202     urls = upnp_get_urls(location)
2203     eventurl = urlparse.urlparse(urls['event_sub_url'])
2204     ctrlurl = urlparse.urlparse(urls['control_url'])
2205
2206     url = urlparse.urlparse(location)
2207     conn = httplib.HTTPConnection(url.netloc)
2208
2209     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
2210         def handle(self):
2211             data = self.rfile.readline().strip()
2212             logger.debug(data)
2213             self.wfile.write(gen_wps_event())
2214
2215     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
2216     server.timeout = 1
2217
2218     headers = { "callback": '<http://127.0.0.1:12345/event>',
2219                 "NT": "upnp:event",
2220                 "timeout": "Second-1234" }
2221     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2222     resp = conn.getresponse()
2223     if resp.status != 200:
2224         raise Exception("Unexpected HTTP response: %d" % resp.status)
2225     sid = resp.getheader("sid")
2226     logger.debug("Subscription SID " + sid)
2227
2228     msg = '''<?xml version="1.0"?>
2229 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
2230 <s:Body>
2231 <u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
2232 <NewMessage>EEoAARAQQQABARASAAIAABBTAAIxSBBJAA4ANyoAASABBv///////xBIABA2LbR7pTpRkYj7
2233 VFi5hrLk
2234 </NewMessage>
2235 </u:SetSelectedRegistrar>
2236 </s:Body>
2237 </s:Envelope>'''
2238     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2239     headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
2240     conn.request("POST", ctrlurl.path, msg, headers)
2241     resp = conn.getresponse()
2242     if resp.status != 200:
2243         raise Exception("Unexpected HTTP response: %d" % resp.status)
2244
2245     server.handle_request()
2246
2247     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
2248     if "OK" not in dev[0].request("WPS_PBC"):
2249         raise Exception("WPS_PBC failed")
2250
2251     start = os.times()[4]
2252
2253     server.handle_request()
2254     dev[1].request("BSS_FLUSH 0")
2255     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2256                         only_new=True)
2257     bss = dev[1].get_bss(apdev[0]['bssid'])
2258     logger.debug("BSS: " + str(bss))
2259     if '[WPS-AUTH]' not in bss['flags']:
2260         raise Exception("WPS not indicated authorized")
2261
2262     server.handle_request()
2263
2264     wps_timeout_seen = False
2265
2266     while True:
2267         hapd.dump_monitor()
2268         dev[1].dump_monitor()
2269         if not wps_timeout_seen:
2270             ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=0)
2271             if ev is not None:
2272                 logger.info("PBC timeout seen")
2273                 wps_timeout_seen = True
2274         else:
2275             dev[0].dump_monitor()
2276         now = os.times()[4]
2277         if now - start > 130:
2278             raise Exception("Selected registration information not removed")
2279         dev[1].request("BSS_FLUSH 0")
2280         dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2281                             only_new=True)
2282         bss = dev[1].get_bss(apdev[0]['bssid'])
2283         logger.debug("BSS: " + str(bss))
2284         if '[WPS-AUTH]' not in bss['flags']:
2285             break
2286         server.handle_request()
2287
2288     server.server_close()
2289
2290     if wps_timeout_seen:
2291         return
2292
2293     now = os.times()[4]
2294     if now < start + 150:
2295         dur = start + 150 - now
2296     else:
2297         dur = 1
2298     logger.info("Continue waiting for PBC timeout (%d sec)" % dur)
2299     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=dur)
2300     if ev is None:
2301         raise Exception("WPS-TIMEOUT not reported")
2302
2303 def add_ssdp_ap(ifname, ap_uuid):
2304     ssid = "wps-ssdp"
2305     ap_pin = "12345670"
2306     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2307                "wpa_passphrase": "12345678", "wpa": "2",
2308                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2309                "device_name": "Wireless AP", "manufacturer": "Company",
2310                "model_name": "WAP", "model_number": "123",
2311                "serial_number": "12345", "device_type": "6-0050F204-1",
2312                "os_version": "01020300",
2313                "config_methods": "label push_button",
2314                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
2315                "friendly_name": "WPS Access Point",
2316                "manufacturer_url": "http://www.example.com/",
2317                "model_description": "Wireless Access Point",
2318                "model_url": "http://www.example.com/model/",
2319                "upc": "123456789012" }
2320     return hostapd.add_ap(ifname, params)
2321
2322 def ssdp_send(msg, no_recv=False):
2323     socket.setdefaulttimeout(1)
2324     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2325     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2326     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2327     sock.bind(("127.0.0.1", 0))
2328     sock.sendto(msg, ("239.255.255.250", 1900))
2329     if no_recv:
2330         return None
2331     return sock.recv(1000)
2332
2333 def ssdp_send_msearch(st, no_recv=False):
2334     msg = '\r\n'.join([
2335             'M-SEARCH * HTTP/1.1',
2336             'HOST: 239.255.255.250:1900',
2337             'MX: 1',
2338             'MAN: "ssdp:discover"',
2339             'ST: ' + st,
2340             '', ''])
2341     return ssdp_send(msg, no_recv=no_recv)
2342
2343 def test_ap_wps_ssdp_msearch(dev, apdev):
2344     """WPS AP and SSDP M-SEARCH messages"""
2345     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2346     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2347
2348     msg = '\r\n'.join([
2349             'M-SEARCH * HTTP/1.1',
2350             'Host: 239.255.255.250:1900',
2351             'Mx: 1',
2352             'Man: "ssdp:discover"',
2353             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
2354             '', ''])
2355     ssdp_send(msg)
2356
2357     msg = '\r\n'.join([
2358             'M-SEARCH * HTTP/1.1',
2359             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
2360             'mx: \t1\t\t   ',
2361             'man: \t \t "ssdp:discover"   ',
2362             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
2363             '', ''])
2364     ssdp_send(msg)
2365
2366     ssdp_send_msearch("ssdp:all")
2367     ssdp_send_msearch("upnp:rootdevice")
2368     ssdp_send_msearch("uuid:" + ap_uuid)
2369     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
2370     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1");
2371
2372     msg = '\r\n'.join([
2373             'M-SEARCH * HTTP/1.1',
2374             'HOST:\t239.255.255.250:1900',
2375             'MAN: "ssdp:discover"',
2376             'MX: 130',
2377             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2378             '', ''])
2379     ssdp_send(msg, no_recv=True)
2380
2381 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
2382     """WPS AP and invalid SSDP M-SEARCH messages"""
2383     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2384     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2385
2386     socket.setdefaulttimeout(1)
2387     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2388     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2389     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2390     sock.bind(("127.0.0.1", 0))
2391
2392     logger.debug("Missing MX")
2393     msg = '\r\n'.join([
2394             'M-SEARCH * HTTP/1.1',
2395             'HOST: 239.255.255.250:1900',
2396             'MAN: "ssdp:discover"',
2397             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2398             '', ''])
2399     sock.sendto(msg, ("239.255.255.250", 1900))
2400
2401     logger.debug("Negative MX")
2402     msg = '\r\n'.join([
2403             'M-SEARCH * HTTP/1.1',
2404             'HOST: 239.255.255.250:1900',
2405             'MX: -1',
2406             'MAN: "ssdp:discover"',
2407             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2408             '', ''])
2409     sock.sendto(msg, ("239.255.255.250", 1900))
2410
2411     logger.debug("Invalid MX")
2412     msg = '\r\n'.join([
2413             'M-SEARCH * HTTP/1.1',
2414             'HOST: 239.255.255.250:1900',
2415             'MX; 1',
2416             'MAN: "ssdp:discover"',
2417             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2418             '', ''])
2419     sock.sendto(msg, ("239.255.255.250", 1900))
2420
2421     logger.debug("Missing MAN")
2422     msg = '\r\n'.join([
2423             'M-SEARCH * HTTP/1.1',
2424             'HOST: 239.255.255.250:1900',
2425             'MX: 1',
2426             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2427             '', ''])
2428     sock.sendto(msg, ("239.255.255.250", 1900))
2429
2430     logger.debug("Invalid MAN")
2431     msg = '\r\n'.join([
2432             'M-SEARCH * HTTP/1.1',
2433             'HOST: 239.255.255.250:1900',
2434             'MX: 1',
2435             'MAN: foo',
2436             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2437             '', ''])
2438     sock.sendto(msg, ("239.255.255.250", 1900))
2439     msg = '\r\n'.join([
2440             'M-SEARCH * HTTP/1.1',
2441             'HOST: 239.255.255.250:1900',
2442             'MX: 1',
2443             'MAN; "ssdp:discover"',
2444             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2445             '', ''])
2446     sock.sendto(msg, ("239.255.255.250", 1900))
2447
2448     logger.debug("Missing HOST")
2449     msg = '\r\n'.join([
2450             'M-SEARCH * HTTP/1.1',
2451             'MAN: "ssdp:discover"',
2452             'MX: 1',
2453             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2454             '', ''])
2455     sock.sendto(msg, ("239.255.255.250", 1900))
2456
2457     logger.debug("Missing ST")
2458     msg = '\r\n'.join([
2459             'M-SEARCH * HTTP/1.1',
2460             'HOST: 239.255.255.250:1900',
2461             'MAN: "ssdp:discover"',
2462             'MX: 1',
2463             '', ''])
2464     sock.sendto(msg, ("239.255.255.250", 1900))
2465
2466     logger.debug("Mismatching ST")
2467     msg = '\r\n'.join([
2468             'M-SEARCH * HTTP/1.1',
2469             'HOST: 239.255.255.250:1900',
2470             'MAN: "ssdp:discover"',
2471             'MX: 1',
2472             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
2473             '', ''])
2474     sock.sendto(msg, ("239.255.255.250", 1900))
2475     msg = '\r\n'.join([
2476             'M-SEARCH * HTTP/1.1',
2477             'HOST: 239.255.255.250:1900',
2478             'MAN: "ssdp:discover"',
2479             'MX: 1',
2480             'ST: foo:bar',
2481             '', ''])
2482     sock.sendto(msg, ("239.255.255.250", 1900))
2483     msg = '\r\n'.join([
2484             'M-SEARCH * HTTP/1.1',
2485             'HOST: 239.255.255.250:1900',
2486             'MAN: "ssdp:discover"',
2487             'MX: 1',
2488             'ST: foobar',
2489             '', ''])
2490     sock.sendto(msg, ("239.255.255.250", 1900))
2491
2492     logger.debug("Invalid ST")
2493     msg = '\r\n'.join([
2494             'M-SEARCH * HTTP/1.1',
2495             'HOST: 239.255.255.250:1900',
2496             'MAN: "ssdp:discover"',
2497             'MX: 1',
2498             'ST; urn:schemas-wifialliance-org:device:WFADevice:1',
2499             '', ''])
2500     sock.sendto(msg, ("239.255.255.250", 1900))
2501
2502     logger.debug("Invalid M-SEARCH")
2503     msg = '\r\n'.join([
2504             'M+SEARCH * HTTP/1.1',
2505             'HOST: 239.255.255.250:1900',
2506             'MAN: "ssdp:discover"',
2507             'MX: 1',
2508             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2509             '', ''])
2510     sock.sendto(msg, ("239.255.255.250", 1900))
2511     msg = '\r\n'.join([
2512             'M-SEARCH-* HTTP/1.1',
2513             'HOST: 239.255.255.250:1900',
2514             'MAN: "ssdp:discover"',
2515             'MX: 1',
2516             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2517             '', ''])
2518     sock.sendto(msg, ("239.255.255.250", 1900))
2519
2520     logger.debug("Invalid message format")
2521     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
2522     msg = '\r'.join([
2523             'M-SEARCH * HTTP/1.1',
2524             'HOST: 239.255.255.250:1900',
2525             'MAN: "ssdp:discover"',
2526             'MX: 1',
2527             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2528             '', ''])
2529     sock.sendto(msg, ("239.255.255.250", 1900))
2530
2531     try:
2532         r = sock.recv(1000)
2533         raise Exception("Unexpected M-SEARCH response: " + r)
2534     except socket.timeout:
2535         pass
2536
2537     logger.debug("Valid M-SEARCH")
2538     msg = '\r\n'.join([
2539             'M-SEARCH * HTTP/1.1',
2540             'HOST: 239.255.255.250:1900',
2541             'MAN: "ssdp:discover"',
2542             'MX: 1',
2543             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2544             '', ''])
2545     sock.sendto(msg, ("239.255.255.250", 1900))
2546
2547     try:
2548         r = sock.recv(1000)
2549         pass
2550     except socket.timeout:
2551         raise Exception("No SSDP response")
2552
2553 def test_ap_wps_ssdp_burst(dev, apdev):
2554     """WPS AP and SSDP burst"""
2555     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2556     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2557
2558     msg = '\r\n'.join([
2559             'M-SEARCH * HTTP/1.1',
2560             'HOST: 239.255.255.250:1900',
2561             'MAN: "ssdp:discover"',
2562             'MX: 1',
2563             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2564             '', ''])
2565     socket.setdefaulttimeout(1)
2566     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2567     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2568     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2569     sock.bind(("127.0.0.1", 0))
2570     for i in range(0, 25):
2571         sock.sendto(msg, ("239.255.255.250", 1900))
2572     resp = 0
2573     while True:
2574         try:
2575             r = sock.recv(1000)
2576             if not r.startswith("HTTP/1.1 200 OK\r\n"):
2577                 raise Exception("Unexpected message: " + r)
2578             resp += 1
2579         except socket.timeout:
2580             break
2581     if resp < 20:
2582         raise Exception("Too few SSDP responses")
2583
2584     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2585     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2586     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2587     sock.bind(("127.0.0.1", 0))
2588     for i in range(0, 25):
2589         sock.sendto(msg, ("239.255.255.250", 1900))
2590     while True:
2591         try:
2592             r = sock.recv(1000)
2593             if ap_uuid in r:
2594                 break
2595         except socket.timeout:
2596             raise Exception("No SSDP response")
2597
2598 def ssdp_get_location(uuid):
2599     res = ssdp_send_msearch("uuid:" + uuid)
2600     location = None
2601     for l in res.splitlines():
2602         if l.lower().startswith("location:"):
2603             location = l.split(':', 1)[1].strip()
2604             break
2605     if location is None:
2606         raise Exception("No UPnP location found")
2607     return location
2608
2609 def upnp_get_urls(location):
2610     conn = urllib.urlopen(location)
2611     tree = ET.parse(conn)
2612     root = tree.getroot()
2613     urn = '{urn:schemas-upnp-org:device-1-0}'
2614     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
2615     res = {}
2616     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
2617     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
2618     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
2619     return res
2620
2621 def upnp_soap_action(conn, path, action, include_soap_action=True, soap_action_override=None):
2622     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
2623     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
2624     ET.register_namespace('soapenv', soapns)
2625     ET.register_namespace('wfa', wpsns)
2626     attrib = {}
2627     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
2628     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
2629     body = ET.SubElement(root, "{%s}Body" % soapns)
2630     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
2631     tree = ET.ElementTree(root)
2632     soap = StringIO.StringIO()
2633     tree.write(soap, xml_declaration=True, encoding='utf-8')
2634
2635     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2636     if include_soap_action:
2637         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
2638     elif soap_action_override:
2639         headers["SOAPAction"] = soap_action_override
2640     conn.request("POST", path, soap.getvalue(), headers)
2641     return conn.getresponse()
2642
2643 def test_ap_wps_upnp(dev, apdev):
2644     """WPS AP and UPnP operations"""
2645     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2646     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2647
2648     location = ssdp_get_location(ap_uuid)
2649     urls = upnp_get_urls(location)
2650
2651     conn = urllib.urlopen(urls['scpd_url'])
2652     scpd = conn.read()
2653
2654     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"))
2655     if conn.getcode() != 404:
2656         raise Exception("Unexpected HTTP response to GET unknown URL")
2657
2658     url = urlparse.urlparse(location)
2659     conn = httplib.HTTPConnection(url.netloc)
2660     #conn.set_debuglevel(1)
2661     headers = { "Content-type": 'text/xml; charset="utf-8"',
2662                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
2663     conn.request("POST", "hello", "\r\n\r\n", headers)
2664     resp = conn.getresponse()
2665     if resp.status != 404:
2666         raise Exception("Unexpected HTTP response: %d" % resp.status)
2667
2668     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
2669     resp = conn.getresponse()
2670     if resp.status != 501:
2671         raise Exception("Unexpected HTTP response: %d" % resp.status)
2672
2673     headers = { "Content-type": 'text/xml; charset="utf-8"',
2674                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
2675     ctrlurl = urlparse.urlparse(urls['control_url'])
2676     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
2677     resp = conn.getresponse()
2678     if resp.status != 401:
2679         raise Exception("Unexpected HTTP response: %d" % resp.status)
2680
2681     logger.debug("GetDeviceInfo without SOAPAction header")
2682     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2683                             include_soap_action=False)
2684     if resp.status != 401:
2685         raise Exception("Unexpected HTTP response: %d" % resp.status)
2686
2687     logger.debug("GetDeviceInfo with invalid SOAPAction header")
2688     for act in [ "foo",
2689                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
2690                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
2691                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
2692         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2693                                 include_soap_action=False,
2694                                 soap_action_override=act)
2695         if resp.status != 401:
2696             raise Exception("Unexpected HTTP response: %d" % resp.status)
2697
2698     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
2699     if resp.status != 200:
2700         raise Exception("Unexpected HTTP response: %d" % resp.status)
2701     dev = resp.read()
2702     if "NewDeviceInfo" not in dev:
2703         raise Exception("Unexpected GetDeviceInfo response")
2704
2705     logger.debug("PutMessage without required parameters")
2706     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
2707     if resp.status != 600:
2708         raise Exception("Unexpected HTTP response: %d" % resp.status)
2709
2710     logger.debug("PutWLANResponse without required parameters")
2711     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
2712     if resp.status != 600:
2713         raise Exception("Unexpected HTTP response: %d" % resp.status)
2714
2715     logger.debug("SetSelectedRegistrar from unregistered ER")
2716     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
2717     if resp.status != 501:
2718         raise Exception("Unexpected HTTP response: %d" % resp.status)
2719
2720     logger.debug("Unknown action")
2721     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
2722     if resp.status != 401:
2723         raise Exception("Unexpected HTTP response: %d" % resp.status)
2724
2725 def test_ap_wps_upnp_subscribe(dev, apdev):
2726     """WPS AP and UPnP event subscription"""
2727     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2728     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2729
2730     location = ssdp_get_location(ap_uuid)
2731     urls = upnp_get_urls(location)
2732     eventurl = urlparse.urlparse(urls['event_sub_url'])
2733
2734     url = urlparse.urlparse(location)
2735     conn = httplib.HTTPConnection(url.netloc)
2736     #conn.set_debuglevel(1)
2737     headers = { "callback": '<http://127.0.0.1:12345/event>',
2738                 "timeout": "Second-1234" }
2739     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
2740     resp = conn.getresponse()
2741     if resp.status != 412:
2742         raise Exception("Unexpected HTTP response: %d" % resp.status)
2743
2744     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2745     resp = conn.getresponse()
2746     if resp.status != 412:
2747         raise Exception("Unexpected HTTP response: %d" % resp.status)
2748
2749     headers = { "NT": "upnp:event",
2750                 "timeout": "Second-1234" }
2751     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2752     resp = conn.getresponse()
2753     if resp.status != 412:
2754         raise Exception("Unexpected HTTP response: %d" % resp.status)
2755
2756     headers = { "callback": '<http://127.0.0.1:12345/event>',
2757                 "NT": "upnp:foobar",
2758                 "timeout": "Second-1234" }
2759     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2760     resp = conn.getresponse()
2761     if resp.status != 400:
2762         raise Exception("Unexpected HTTP response: %d" % resp.status)
2763
2764     logger.debug("Valid subscription")
2765     headers = { "callback": '<http://127.0.0.1:12345/event>',
2766                 "NT": "upnp:event",
2767                 "timeout": "Second-1234" }
2768     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2769     resp = conn.getresponse()
2770     if resp.status != 200:
2771         raise Exception("Unexpected HTTP response: %d" % resp.status)
2772     sid = resp.getheader("sid")
2773     logger.debug("Subscription SID " + sid)
2774
2775     logger.debug("Invalid re-subscription")
2776     headers = { "NT": "upnp:event",
2777                 "sid": "123456734567854",
2778                 "timeout": "Second-1234" }
2779     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2780     resp = conn.getresponse()
2781     if resp.status != 400:
2782         raise Exception("Unexpected HTTP response: %d" % resp.status)
2783
2784     logger.debug("Invalid re-subscription")
2785     headers = { "NT": "upnp:event",
2786                 "sid": "uuid:123456734567854",
2787                 "timeout": "Second-1234" }
2788     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2789     resp = conn.getresponse()
2790     if resp.status != 400:
2791         raise Exception("Unexpected HTTP response: %d" % resp.status)
2792
2793     logger.debug("Invalid re-subscription")
2794     headers = { "callback": '<http://127.0.0.1:12345/event>',
2795                 "NT": "upnp:event",
2796                 "sid": sid,
2797                 "timeout": "Second-1234" }
2798     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2799     resp = conn.getresponse()
2800     if resp.status != 400:
2801         raise Exception("Unexpected HTTP response: %d" % resp.status)
2802
2803     logger.debug("SID mismatch in re-subscription")
2804     headers = { "NT": "upnp:event",
2805                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2806                 "timeout": "Second-1234" }
2807     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2808     resp = conn.getresponse()
2809     if resp.status != 412:
2810         raise Exception("Unexpected HTTP response: %d" % resp.status)
2811
2812     logger.debug("Valid re-subscription")
2813     headers = { "NT": "upnp:event",
2814                 "sid": sid,
2815                 "timeout": "Second-1234" }
2816     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2817     resp = conn.getresponse()
2818     if resp.status != 200:
2819         raise Exception("Unexpected HTTP response: %d" % resp.status)
2820     sid2 = resp.getheader("sid")
2821     logger.debug("Subscription SID " + sid2)
2822
2823     if sid != sid2:
2824         raise Exception("Unexpected SID change")
2825
2826     logger.debug("Valid re-subscription")
2827     headers = { "NT": "upnp:event",
2828                 "sid": "uuid: \t \t" + sid.split(':')[1],
2829                 "timeout": "Second-1234" }
2830     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2831     resp = conn.getresponse()
2832     if resp.status != 200:
2833         raise Exception("Unexpected HTTP response: %d" % resp.status)
2834
2835     logger.debug("Invalid unsubscription")
2836     headers = { "sid": sid }
2837     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2838     resp = conn.getresponse()
2839     if resp.status != 412:
2840         raise Exception("Unexpected HTTP response: %d" % resp.status)
2841     headers = { "foo": "bar" }
2842     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2843     resp = conn.getresponse()
2844     if resp.status != 412:
2845         raise Exception("Unexpected HTTP response: %d" % resp.status)
2846
2847     logger.debug("Valid unsubscription")
2848     headers = { "sid": sid }
2849     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2850     resp = conn.getresponse()
2851     if resp.status != 200:
2852         raise Exception("Unexpected HTTP response: %d" % resp.status)
2853
2854     logger.debug("Unsubscription for not existing SID")
2855     headers = { "sid": sid }
2856     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2857     resp = conn.getresponse()
2858     if resp.status != 412:
2859         raise Exception("Unexpected HTTP response: %d" % resp.status)
2860
2861     logger.debug("Invalid unsubscription")
2862     headers = { "sid": " \t \tfoo" }
2863     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2864     resp = conn.getresponse()
2865     if resp.status != 400:
2866         raise Exception("Unexpected HTTP response: %d" % resp.status)
2867
2868     logger.debug("Invalid unsubscription")
2869     headers = { "sid": "uuid:\t \tfoo" }
2870     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2871     resp = conn.getresponse()
2872     if resp.status != 400:
2873         raise Exception("Unexpected HTTP response: %d" % resp.status)
2874
2875     logger.debug("Invalid unsubscription")
2876     headers = { "NT": "upnp:event",
2877                 "sid": sid }
2878     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2879     resp = conn.getresponse()
2880     if resp.status != 400:
2881         raise Exception("Unexpected HTTP response: %d" % resp.status)
2882     headers = { "callback": '<http://127.0.0.1:12345/event>',
2883                 "sid": sid }
2884     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2885     resp = conn.getresponse()
2886     if resp.status != 400:
2887         raise Exception("Unexpected HTTP response: %d" % resp.status)
2888
2889     logger.debug("Valid subscription with multiple callbacks")
2890     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>',
2891                 "NT": "upnp:event",
2892                 "timeout": "Second-1234" }
2893     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2894     resp = conn.getresponse()
2895     if resp.status != 200:
2896         raise Exception("Unexpected HTTP response: %d" % resp.status)
2897     sid = resp.getheader("sid")
2898     logger.debug("Subscription SID " + sid)
2899
2900     # Force subscription to be deleted due to errors
2901     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2902     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2903     with alloc_fail(hapd, 1, "event_build_message"):
2904         for i in range(10):
2905             dev[1].dump_monitor()
2906             dev[2].dump_monitor()
2907             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2908             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2909             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2910             dev[1].request("WPS_CANCEL")
2911             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2912             dev[2].request("WPS_CANCEL")
2913             if i % 4 == 1:
2914                 time.sleep(1)
2915             else:
2916                 time.sleep(0.1)
2917     time.sleep(0.2)
2918
2919     headers = { "sid": sid }
2920     conn.request("UNSUBSCRIBE", eventurl.path, "", headers)
2921     resp = conn.getresponse()
2922     if resp.status != 200 and resp.status != 412:
2923         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2924
2925     headers = { "callback": '<http://127.0.0.1:12345/event>',
2926                 "NT": "upnp:event",
2927                 "timeout": "Second-1234" }
2928     with alloc_fail(hapd, 1, "http_client_addr;event_send_start"):
2929         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2930         resp = conn.getresponse()
2931         if resp.status != 200:
2932             raise Exception("Unexpected HTTP response for SUBSCRIBE: %d" % resp.status)
2933         sid = resp.getheader("sid")
2934         logger.debug("Subscription SID " + sid)
2935
2936     headers = { "sid": sid }
2937     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2938     resp = conn.getresponse()
2939     if resp.status != 200:
2940         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2941
2942     headers = { "callback": '<http://127.0.0.1:12345/event>',
2943                 "NT": "upnp:event",
2944                 "timeout": "Second-1234" }
2945     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2946     resp = conn.getresponse()
2947     if resp.status != 200:
2948         raise Exception("Unexpected HTTP response: %d" % resp.status)
2949     sid = resp.getheader("sid")
2950     logger.debug("Subscription SID " + sid)
2951
2952     with alloc_fail(hapd, 1, "=event_add"):
2953         for i in range(2):
2954             dev[1].dump_monitor()
2955             dev[2].dump_monitor()
2956             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2957             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2958             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2959             dev[1].request("WPS_CANCEL")
2960             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2961             dev[2].request("WPS_CANCEL")
2962             if i == 0:
2963                 time.sleep(1)
2964             else:
2965                 time.sleep(0.1)
2966
2967     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2968     resp = conn.getresponse()
2969     if resp.status != 200:
2970         raise Exception("Unexpected HTTP response: %d" % resp.status)
2971
2972     with alloc_fail(hapd, 1, "wpabuf_dup;event_add"):
2973         dev[1].dump_monitor()
2974         dev[2].dump_monitor()
2975         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2976         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2977         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2978         dev[1].request("WPS_CANCEL")
2979         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2980         dev[2].request("WPS_CANCEL")
2981         time.sleep(0.1)
2982
2983     with fail_test(hapd, 1, "os_get_random;uuid_make;subscription_start"):
2984         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2985         resp = conn.getresponse()
2986         if resp.status != 500:
2987             raise Exception("Unexpected HTTP response: %d" % resp.status)
2988
2989     with alloc_fail(hapd, 1, "=subscription_start"):
2990         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2991         resp = conn.getresponse()
2992         if resp.status != 500:
2993             raise Exception("Unexpected HTTP response: %d" % resp.status)
2994
2995     headers = { "callback": '',
2996                 "NT": "upnp:event",
2997                 "timeout": "Second-1234" }
2998     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2999     resp = conn.getresponse()
3000     if resp.status != 500:
3001         raise Exception("Unexpected HTTP response: %d" % resp.status)
3002
3003     headers = { "callback": ' <',
3004                 "NT": "upnp:event",
3005                 "timeout": "Second-1234" }
3006     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3007     resp = conn.getresponse()
3008     if resp.status != 500:
3009         raise Exception("Unexpected HTTP response: %d" % resp.status)
3010
3011     headers = { "callback": '<http://127.0.0.1:12345/event>',
3012                 "NT": "upnp:event",
3013                 "timeout": "Second-1234" }
3014     with alloc_fail(hapd, 1, "wpabuf_alloc;subscription_first_event"):
3015         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3016         resp = conn.getresponse()
3017         if resp.status != 500:
3018             raise Exception("Unexpected HTTP response: %d" % resp.status)
3019
3020     with alloc_fail(hapd, 1, "event_add;subscription_first_event"):
3021         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3022         resp = conn.getresponse()
3023         if resp.status != 500:
3024             raise Exception("Unexpected HTTP response: %d" % resp.status)
3025
3026     with alloc_fail(hapd, 1, "subscr_addr_add_url"):
3027         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3028         resp = conn.getresponse()
3029         if resp.status != 500:
3030             raise Exception("Unexpected HTTP response: %d" % resp.status)
3031
3032     with alloc_fail(hapd, 2, "subscr_addr_add_url"):
3033         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3034         resp = conn.getresponse()
3035         if resp.status != 500:
3036             raise Exception("Unexpected HTTP response: %d" % resp.status)
3037
3038     for i in range(6):
3039         headers = { "callback": '<http://127.0.0.1:%d/event>' % (12345 + i),
3040                     "NT": "upnp:event",
3041                     "timeout": "Second-1234" }
3042         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3043         resp = conn.getresponse()
3044         if resp.status != 200:
3045             raise Exception("Unexpected HTTP response: %d" % resp.status)
3046
3047     with alloc_fail(hapd, 1, "=upnp_wps_device_send_wlan_event"):
3048         dev[1].dump_monitor()
3049         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3050         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3051         dev[1].request("WPS_CANCEL")
3052         time.sleep(0.1)
3053
3054     with alloc_fail(hapd, 1, "wpabuf_alloc;upnp_wps_device_send_event"):
3055         dev[1].dump_monitor()
3056         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3057         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3058         dev[1].request("WPS_CANCEL")
3059         time.sleep(0.1)
3060
3061     with alloc_fail(hapd, 1, "base64_encode;upnp_wps_device_send_wlan_event"):
3062         dev[1].dump_monitor()
3063         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3064         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3065         dev[1].request("WPS_CANCEL")
3066         time.sleep(0.1)
3067
3068     hapd.disable()
3069     with alloc_fail(hapd, 1, "get_netif_info"):
3070         if "FAIL" not in hapd.request("ENABLE"):
3071             raise Exception("ENABLE succeeded during OOM")
3072
3073 def test_ap_wps_upnp_subscribe_events(dev, apdev):
3074     """WPS AP and UPnP event subscription and many events"""
3075     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3076     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3077
3078     location = ssdp_get_location(ap_uuid)
3079     urls = upnp_get_urls(location)
3080     eventurl = urlparse.urlparse(urls['event_sub_url'])
3081
3082     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
3083         def handle(self):
3084             data = self.rfile.readline().strip()
3085             logger.debug(data)
3086             self.wfile.write(gen_wps_event())
3087
3088     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
3089     server.timeout = 1
3090
3091     url = urlparse.urlparse(location)
3092     conn = httplib.HTTPConnection(url.netloc)
3093
3094     headers = { "callback": '<http://127.0.0.1:12345/event>',
3095                 "NT": "upnp:event",
3096                 "timeout": "Second-1234" }
3097     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3098     resp = conn.getresponse()
3099     if resp.status != 200:
3100         raise Exception("Unexpected HTTP response: %d" % resp.status)
3101     sid = resp.getheader("sid")
3102     logger.debug("Subscription SID " + sid)
3103
3104     # Fetch the first event message
3105     server.handle_request()
3106
3107     # Force subscription event queue to reach the maximum length by generating
3108     # new proxied events without the ER fetching any of the pending events.
3109     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3110     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
3111     for i in range(16):
3112         dev[1].dump_monitor()
3113         dev[2].dump_monitor()
3114         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3115         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3116         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3117         dev[1].request("WPS_CANCEL")
3118         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3119         dev[2].request("WPS_CANCEL")
3120         if i % 4 == 1:
3121             time.sleep(1)
3122         else:
3123             time.sleep(0.1)
3124
3125     hapd.request("WPS_PIN any 12345670")
3126     dev[1].dump_monitor()
3127     dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3128     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=10)
3129     if ev is None:
3130         raise Exception("WPS success not reported")
3131
3132     # Close the WPS ER HTTP server without fetching all the pending events.
3133     # This tests hostapd code path that clears subscription and the remaining
3134     # event queue when the interface is deinitialized.
3135     server.handle_request()
3136     server.server_close()
3137
3138     dev[1].wait_connected()
3139
3140 def test_ap_wps_upnp_http_proto(dev, apdev):
3141     """WPS AP and UPnP/HTTP protocol testing"""
3142     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3143     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3144
3145     location = ssdp_get_location(ap_uuid)
3146
3147     url = urlparse.urlparse(location)
3148     conn = httplib.HTTPConnection(url.netloc, timeout=0.2)
3149     #conn.set_debuglevel(1)
3150
3151     conn.request("HEAD", "hello")
3152     resp = conn.getresponse()
3153     if resp.status != 501:
3154         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3155     conn.close()
3156
3157     for cmd in [ "PUT", "DELETE", "TRACE", "CONNECT", "M-SEARCH", "M-POST" ]:
3158         try:
3159             conn.request(cmd, "hello")
3160             resp = conn.getresponse()
3161         except Exception, e:
3162             pass
3163         conn.close()
3164
3165     headers = { "Content-Length": 'abc' }
3166     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3167     try:
3168         resp = conn.getresponse()
3169     except Exception, e:
3170         pass
3171     conn.close()
3172
3173     headers = { "Content-Length": '-10' }
3174     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3175     try:
3176         resp = conn.getresponse()
3177     except Exception, e:
3178         pass
3179     conn.close()
3180
3181     headers = { "Content-Length": '10000000000000' }
3182     conn.request("HEAD", "hello", "\r\n\r\nhello", headers)
3183     try:
3184         resp = conn.getresponse()
3185     except Exception, e:
3186         pass
3187     conn.close()
3188
3189     headers = { "Transfer-Encoding": 'abc' }
3190     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3191     resp = conn.getresponse()
3192     if resp.status != 501:
3193         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3194     conn.close()
3195
3196     headers = { "Transfer-Encoding": 'chunked' }
3197     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3198     resp = conn.getresponse()
3199     if resp.status != 501:
3200         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3201     conn.close()
3202
3203     # Too long a header
3204     conn.request("HEAD", 5000 * 'A')
3205     try:
3206         resp = conn.getresponse()
3207     except Exception, e:
3208         pass
3209     conn.close()
3210
3211     # Long URL but within header length limits
3212     conn.request("HEAD", 3000 * 'A')
3213     resp = conn.getresponse()
3214     if resp.status != 501:
3215         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3216     conn.close()
3217
3218     headers = { "Content-Length": '20' }
3219     conn.request("POST", "hello", 10 * 'A' + "\r\n\r\n", headers)
3220     try:
3221         resp = conn.getresponse()
3222     except Exception, e:
3223         pass
3224     conn.close()
3225
3226     conn.request("POST", "hello", 5000 * 'A' + "\r\n\r\n")
3227     resp = conn.getresponse()
3228     if resp.status != 404:
3229         raise Exception("Unexpected HTTP response: %d" % resp.status)
3230     conn.close()
3231
3232     conn.request("POST", "hello", 60000 * 'A' + "\r\n\r\n")
3233     try:
3234         resp = conn.getresponse()
3235     except Exception, e:
3236         pass
3237     conn.close()
3238
3239 def test_ap_wps_upnp_http_proto_chunked(dev, apdev):
3240     """WPS AP and UPnP/HTTP protocol testing for chunked encoding"""
3241     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3242     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3243
3244     location = ssdp_get_location(ap_uuid)
3245
3246     url = urlparse.urlparse(location)
3247     conn = httplib.HTTPConnection(url.netloc)
3248     #conn.set_debuglevel(1)
3249
3250     headers = { "Transfer-Encoding": 'chunked' }
3251     conn.request("POST", "hello",
3252                  "a\r\nabcdefghij\r\n" + "2\r\nkl\r\n" + "0\r\n\r\n",
3253                  headers)
3254     resp = conn.getresponse()
3255     if resp.status != 404:
3256         raise Exception("Unexpected HTTP response: %d" % resp.status)
3257     conn.close()
3258
3259     conn.putrequest("POST", "hello")
3260     conn.putheader('Transfer-Encoding', 'chunked')
3261     conn.endheaders()
3262     conn.send("a\r\nabcdefghij\r\n")
3263     time.sleep(0.1)
3264     conn.send("2\r\nkl\r\n")
3265     conn.send("0\r\n\r\n")
3266     resp = conn.getresponse()
3267     if resp.status != 404:
3268         raise Exception("Unexpected HTTP response: %d" % resp.status)
3269     conn.close()
3270
3271     conn.putrequest("POST", "hello")
3272     conn.putheader('Transfer-Encoding', 'chunked')
3273     conn.endheaders()
3274     completed = False
3275     try:
3276         for i in range(20000):
3277             conn.send("1\r\nZ\r\n")
3278         conn.send("0\r\n\r\n")
3279         resp = conn.getresponse()
3280         completed = True
3281     except Exception, e:
3282         pass
3283     conn.close()
3284     if completed:
3285         raise Exception("Too long chunked request did not result in connection reset")
3286
3287     headers = { "Transfer-Encoding": 'chunked' }
3288     conn.request("POST", "hello", "80000000\r\na", headers)
3289     try:
3290         resp = conn.getresponse()
3291     except Exception, e:
3292         pass
3293     conn.close()
3294
3295     conn.request("POST", "hello", "10000000\r\na", headers)
3296     try:
3297         resp = conn.getresponse()
3298     except Exception, e:
3299         pass
3300     conn.close()
3301
3302 def test_ap_wps_disabled(dev, apdev):
3303     """WPS operations while WPS is disabled"""
3304     ssid = "test-wps-disabled"
3305     hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid })
3306     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3307     if "FAIL" not in hapd.request("WPS_PBC"):
3308         raise Exception("WPS_PBC succeeded unexpectedly")
3309     if "FAIL" not in hapd.request("WPS_CANCEL"):
3310         raise Exception("WPS_CANCEL succeeded unexpectedly")
3311
3312 def test_ap_wps_mixed_cred(dev, apdev):
3313     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
3314     ssid = "test-wps-wep"
3315     hostapd.add_ap(apdev[0]['ifname'],
3316                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3317                      "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" })
3318     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3319     hapd.request("WPS_PBC")
3320     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3321     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3322     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
3323     if ev is None:
3324         raise Exception("WPS-SUCCESS event timed out")
3325     nets = dev[0].list_networks()
3326     if len(nets) != 1:
3327         raise Exception("Unexpected number of network blocks")
3328     id = nets[0]['id']
3329     proto = dev[0].get_network(id, "proto")
3330     if proto != "WPA RSN":
3331         raise Exception("Unexpected merged proto field value: " + proto)
3332     pairwise = dev[0].get_network(id, "pairwise")
3333     if pairwise != "CCMP TKIP" and pairwise != "CCMP GCMP TKIP":
3334         raise Exception("Unexpected merged pairwise field value: " + pairwise)
3335
3336 def test_ap_wps_while_connected(dev, apdev):
3337     """WPS PBC provisioning while connected to another AP"""
3338     ssid = "test-wps-conf"
3339     hostapd.add_ap(apdev[0]['ifname'],
3340                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3341                      "wpa_passphrase": "12345678", "wpa": "2",
3342                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3343     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3344
3345     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
3346     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3347
3348     logger.info("WPS provisioning step")
3349     hapd.request("WPS_PBC")
3350     dev[0].dump_monitor()
3351     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3352     dev[0].wait_connected(timeout=30)
3353     status = dev[0].get_status()
3354     if status['bssid'] != apdev[0]['bssid']:
3355         raise Exception("Unexpected BSSID")
3356
3357 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
3358     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
3359     ssid = "test-wps-conf"
3360     hostapd.add_ap(apdev[0]['ifname'],
3361                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3362                      "wpa_passphrase": "12345678", "wpa": "2",
3363                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3364     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3365
3366     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
3367
3368     try:
3369         dev[0].request("STA_AUTOCONNECT 0")
3370         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3371
3372         logger.info("WPS provisioning step")
3373         hapd.request("WPS_PBC")
3374         dev[0].dump_monitor()
3375         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3376         dev[0].wait_connected(timeout=30)
3377         status = dev[0].get_status()
3378         if status['bssid'] != apdev[0]['bssid']:
3379             raise Exception("Unexpected BSSID")
3380     finally:
3381         dev[0].request("STA_AUTOCONNECT 1")
3382
3383 def test_ap_wps_from_event(dev, apdev):
3384     """WPS PBC event on AP to enable PBC"""
3385     ssid = "test-wps-conf"
3386     hapd = hostapd.add_ap(apdev[0]['ifname'],
3387                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3388                             "wpa_passphrase": "12345678", "wpa": "2",
3389                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3390     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3391     dev[0].dump_monitor()
3392     hapd.dump_monitor()
3393     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3394
3395     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
3396     if ev is None:
3397         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
3398     vals = ev.split(' ')
3399     if vals[1] != dev[0].p2p_interface_addr():
3400         raise Exception("Unexpected enrollee address: " + vals[1])
3401     if vals[5] != '4':
3402         raise Exception("Unexpected Device Password Id: " + vals[5])
3403     hapd.request("WPS_PBC")
3404     dev[0].wait_connected(timeout=30)
3405
3406 def test_ap_wps_ap_scan_2(dev, apdev):
3407     """AP_SCAN 2 for WPS"""
3408     ssid = "test-wps-conf"
3409     hapd = hostapd.add_ap(apdev[0]['ifname'],
3410                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3411                             "wpa_passphrase": "12345678", "wpa": "2",
3412                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3413     hapd.request("WPS_PBC")
3414
3415     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
3416     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
3417
3418     if "OK" not in wpas.request("AP_SCAN 2"):
3419         raise Exception("Failed to set AP_SCAN 2")
3420
3421     wpas.flush_scan_cache()
3422     wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
3423     wpas.request("WPS_PBC " + apdev[0]['bssid'])
3424     ev = wpas.wait_event(["WPS-SUCCESS"], timeout=15)
3425     if ev is None:
3426         raise Exception("WPS-SUCCESS event timed out")
3427     wpas.wait_connected(timeout=30)
3428     wpas.request("DISCONNECT")
3429     wpas.request("BSS_FLUSH 0")
3430     wpas.dump_monitor()
3431     wpas.request("REASSOCIATE")
3432     wpas.wait_connected(timeout=30)
3433
3434 def test_ap_wps_eapol_workaround(dev, apdev):
3435     """EAPOL workaround code path for 802.1X header length mismatch"""
3436     ssid = "test-wps"
3437     hostapd.add_ap(apdev[0]['ifname'],
3438                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
3439     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3440     bssid = apdev[0]['bssid']
3441     hapd.request("SET ext_eapol_frame_io 1")
3442     dev[0].request("SET ext_eapol_frame_io 1")
3443     hapd.request("WPS_PBC")
3444     dev[0].request("WPS_PBC")
3445
3446     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3447     if ev is None:
3448         raise Exception("Timeout on EAPOL-TX from hostapd")
3449
3450     res = dev[0].request("EAPOL_RX " + bssid + " 020000040193000501FFFF")
3451     if "OK" not in res:
3452         raise Exception("EAPOL_RX to wpa_supplicant failed")
3453
3454 def test_ap_wps_iteration(dev, apdev):
3455     """WPS PIN and iterate through APs without selected registrar"""
3456     ssid = "test-wps-conf"
3457     hapd = hostapd.add_ap(apdev[0]['ifname'],
3458                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3459                             "wpa_passphrase": "12345678", "wpa": "2",
3460                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3461
3462     ssid2 = "test-wps-conf2"
3463     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3464                            { "ssid": ssid2, "eap_server": "1", "wps_state": "2",
3465                              "wpa_passphrase": "12345678", "wpa": "2",
3466                              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3467
3468     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3469     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
3470     dev[0].dump_monitor()
3471     pin = dev[0].request("WPS_PIN any")
3472
3473     # Wait for iteration through all WPS APs to happen before enabling any
3474     # Registrar.
3475     for i in range(2):
3476         ev = dev[0].wait_event(["Associated with"], timeout=30)
3477         if ev is None:
3478             raise Exception("No association seen")
3479         ev = dev[0].wait_event(["WPS-M2D"], timeout=10)
3480         if ev is None:
3481             raise Exception("No M2D from AP")
3482         dev[0].wait_disconnected()
3483
3484     # Verify that each AP requested PIN
3485     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3486     if ev is None:
3487         raise Exception("No WPS-PIN-NEEDED event from AP")
3488     ev = hapd2.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3489     if ev is None:
3490         raise Exception("No WPS-PIN-NEEDED event from AP2")
3491
3492     # Provide PIN to one of the APs and verify that connection gets formed
3493     hapd.request("WPS_PIN any " + pin)
3494     dev[0].wait_connected(timeout=30)
3495
3496 def test_ap_wps_iteration_error(dev, apdev):
3497     """WPS AP iteration on no Selected Registrar and error case with an AP"""
3498     ssid = "test-wps-conf-pin"
3499     hapd = hostapd.add_ap(apdev[0]['ifname'],
3500                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3501                             "wpa_passphrase": "12345678", "wpa": "2",
3502                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3503                             "wps_independent": "1" })
3504     hapd.request("SET ext_eapol_frame_io 1")
3505     bssid = apdev[0]['bssid']
3506     pin = dev[0].wps_read_pin()
3507     dev[0].request("WPS_PIN any " + pin)
3508
3509     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3510     if ev is None:
3511         raise Exception("No EAPOL-TX (EAP-Request/Identity) from hostapd")
3512     dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
3513
3514     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3515     if ev is None:
3516         raise Exception("No EAPOL-TX (EAP-WSC/Start) from hostapd")
3517     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
3518     if ev is None:
3519         raise Exception("No CTRL-EVENT-EAP-STARTED")
3520
3521     # Do not forward any more EAPOL frames to test wpa_supplicant behavior for
3522     # a case with an incorrectly behaving WPS AP.
3523
3524     # Start the real target AP and activate registrar on it.
3525     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3526                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3527                             "wpa_passphrase": "12345678", "wpa": "2",
3528                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3529                             "wps_independent": "1" })
3530     hapd2.request("WPS_PIN any " + pin)
3531
3532     dev[0].wait_disconnected(timeout=15)
3533     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
3534     if ev is None:
3535         raise Exception("No CTRL-EVENT-EAP-STARTED for the second AP")
3536     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
3537     if ev is None:
3538         raise Exception("No WPS-CRED-RECEIVED for the second AP")
3539     dev[0].wait_connected(timeout=15)
3540
3541 def test_ap_wps_priority(dev, apdev):
3542     """WPS PIN provisioning with configured AP and wps_priority"""
3543     ssid = "test-wps-conf-pin"
3544     hostapd.add_ap(apdev[0]['ifname'],
3545                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3546                      "wpa_passphrase": "12345678", "wpa": "2",
3547                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3548     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3549     logger.info("WPS provisioning step")
3550     pin = dev[0].wps_read_pin()
3551     hapd.request("WPS_PIN any " + pin)
3552     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3553     dev[0].dump_monitor()
3554     try:
3555         dev[0].request("SET wps_priority 6")
3556         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3557         dev[0].wait_connected(timeout=30)
3558         netw = dev[0].list_networks()
3559         prio = dev[0].get_network(netw[0]['id'], 'priority')
3560         if prio != '6':
3561             raise Exception("Unexpected network priority: " + prio)
3562     finally:
3563         dev[0].request("SET wps_priority 0")
3564
3565 def test_ap_wps_and_non_wps(dev, apdev):
3566     """WPS and non-WPS AP in single hostapd process"""
3567     params = { "ssid": "wps", "eap_server": "1", "wps_state": "1" }
3568     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3569
3570     params = { "ssid": "no wps" }
3571     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
3572
3573     appin = hapd.request("WPS_AP_PIN random")
3574     if "FAIL" in appin:
3575         raise Exception("Could not generate random AP PIN")
3576     if appin not in hapd.request("WPS_AP_PIN get"):
3577         raise Exception("Could not fetch current AP PIN")
3578
3579     if "FAIL" in hapd.request("WPS_PBC"):
3580         raise Exception("WPS_PBC failed")
3581     if "FAIL" in hapd.request("WPS_CANCEL"):
3582         raise Exception("WPS_CANCEL failed")
3583
3584 def test_ap_wps_init_oom(dev, apdev):
3585     """Initial AP configuration and OOM during PSK generation"""
3586     ssid = "test-wps"
3587     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
3588     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3589
3590     with alloc_fail(hapd, 1, "base64_encode;wps_build_cred"):
3591         pin = dev[0].wps_read_pin()
3592         hapd.request("WPS_PIN any " + pin)
3593         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3594         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3595         dev[0].wait_disconnected()
3596
3597     hapd.request("WPS_PIN any " + pin)
3598     dev[0].wait_connected(timeout=30)
3599
3600 def test_ap_wps_er_oom(dev, apdev):
3601     """WPS ER OOM in XML processing"""
3602     try:
3603         _test_ap_wps_er_oom(dev, apdev)
3604     finally:
3605         dev[0].request("WPS_ER_STOP")
3606         dev[1].request("WPS_CANCEL")
3607         dev[0].request("DISCONNECT")
3608
3609 def _test_ap_wps_er_oom(dev, apdev):
3610     ssid = "wps-er-ap-config"
3611     ap_pin = "12345670"
3612     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3613     hostapd.add_ap(apdev[0]['ifname'],
3614                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3615                      "wpa_passphrase": "12345678", "wpa": "2",
3616                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3617                      "device_name": "Wireless AP", "manufacturer": "Company",
3618                      "model_name": "WAP", "model_number": "123",
3619                      "serial_number": "12345", "device_type": "6-0050F204-1",
3620                      "os_version": "01020300",
3621                      "config_methods": "label push_button",
3622                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
3623
3624     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
3625
3626     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3627         dev[0].request("WPS_ER_START ifname=lo")
3628         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=3)
3629         if ev is not None:
3630             raise Exception("Unexpected AP discovery")
3631
3632     dev[0].request("WPS_ER_STOP")
3633     dev[0].request("WPS_ER_START ifname=lo")
3634     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3635     if ev is None:
3636         raise Exception("AP discovery timed out")
3637
3638     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3639     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3640         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
3641         ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
3642         if ev is None:
3643             raise Exception("PBC scan failed")
3644         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
3645         if ev is None:
3646             raise Exception("Enrollee discovery timed out")
3647
3648 def test_ap_wps_er_init_oom(dev, apdev):
3649     """WPS ER and OOM during init"""
3650     try:
3651         _test_ap_wps_er_init_oom(dev, apdev)
3652     finally:
3653         dev[0].request("WPS_ER_STOP")
3654
3655 def _test_ap_wps_er_init_oom(dev, apdev):
3656     with alloc_fail(dev[0], 1, "wps_er_init"):
3657         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3658             raise Exception("WPS_ER_START succeeded during OOM")
3659     with alloc_fail(dev[0], 1, "http_server_init"):
3660         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3661             raise Exception("WPS_ER_START succeeded during OOM")
3662     with alloc_fail(dev[0], 2, "http_server_init"):
3663         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3664             raise Exception("WPS_ER_START succeeded during OOM")
3665     with alloc_fail(dev[0], 1, "eloop_register_sock;wps_er_ssdp_init"):
3666         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3667             raise Exception("WPS_ER_START succeeded during OOM")
3668     with fail_test(dev[0], 1, "os_get_random;wps_er_init"):
3669         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3670             raise Exception("WPS_ER_START succeeded during os_get_random failure")
3671
3672 def test_ap_wps_er_init_fail(dev, apdev):
3673     """WPS ER init failure"""
3674     if "FAIL" not in dev[0].request("WPS_ER_START ifname=does-not-exist"):
3675         dev[0].request("WPS_ER_STOP")
3676         raise Exception("WPS_ER_START with non-existing ifname succeeded")
3677
3678 def test_ap_wps_wpa_cli_action(dev, apdev, test_params):
3679     """WPS events and wpa_cli action script"""
3680     logdir = os.path.abspath(test_params['logdir'])
3681     pidfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.pid')
3682     logfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.res')
3683     actionfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.action.sh')
3684
3685     with open(actionfile, 'w') as f:
3686         f.write('#!/bin/sh\n')
3687         f.write('echo $* >> %s\n' % logfile)
3688         # Kill the process and wait some time before returning to allow all the
3689         # pending events to be processed with some of this happening after the
3690         # eloop SIGALRM signal has been scheduled.
3691         f.write('if [ $2 = "WPS-SUCCESS" -a -r %s ]; then kill `cat %s`; sleep 1; fi\n' % (pidfile, pidfile))
3692
3693     os.chmod(actionfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
3694              stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
3695
3696     ssid = "test-wps-conf"
3697     hostapd.add_ap(apdev[0]['ifname'],
3698                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3699                      "wpa_passphrase": "12345678", "wpa": "2",
3700                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3701     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3702
3703     prg = os.path.join(test_params['logdir'],
3704                        'alt-wpa_supplicant/wpa_supplicant/wpa_cli')
3705     if not os.path.exists(prg):
3706         prg = '../../wpa_supplicant/wpa_cli'
3707     arg = [ prg, '-P', pidfile, '-B', '-i', dev[0].ifname, '-a', actionfile ]
3708     subprocess.call(arg)
3709
3710     arg = [ 'ps', 'ax' ]
3711     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3712     out = cmd.communicate()[0]
3713     cmd.wait()
3714     logger.debug("Processes:\n" + out)
3715     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) not in out:
3716         raise Exception("Did not see wpa_cli running")
3717
3718     hapd.request("WPS_PIN any 12345670")
3719     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3720     dev[0].dump_monitor()
3721     dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3722     dev[0].wait_connected(timeout=30)
3723
3724     for i in range(30):
3725         if not os.path.exists(pidfile):
3726             break
3727         time.sleep(0.1)
3728
3729     if not os.path.exists(logfile):
3730         raise Exception("wpa_cli action results file not found")
3731     with open(logfile, 'r') as f:
3732         res = f.read()
3733     if "WPS-SUCCESS" not in res:
3734         raise Exception("WPS-SUCCESS event not seen in action file")
3735
3736     arg = [ 'ps', 'ax' ]
3737     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3738     out = cmd.communicate()[0]
3739     cmd.wait()
3740     logger.debug("Remaining processes:\n" + out)
3741     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) in out:
3742         raise Exception("wpa_cli still running")
3743
3744     if os.path.exists(pidfile):
3745         raise Exception("PID file not removed")
3746
3747 def test_ap_wps_er_ssdp_proto(dev, apdev):
3748     """WPS ER SSDP protocol testing"""
3749     try:
3750         _test_ap_wps_er_ssdp_proto(dev, apdev)
3751     finally:
3752         dev[0].request("WPS_ER_STOP")
3753
3754 def _test_ap_wps_er_ssdp_proto(dev, apdev):
3755     socket.setdefaulttimeout(1)
3756     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3757     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3758     sock.bind(("239.255.255.250", 1900))
3759     if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo foo"):
3760         raise Exception("Invalid filter accepted")
3761     if "OK" not in dev[0].request("WPS_ER_START ifname=lo 1.2.3.4"):
3762         raise Exception("WPS_ER_START with filter failed")
3763     (msg,addr) = sock.recvfrom(1000)
3764     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3765     if "M-SEARCH" not in msg:
3766         raise Exception("Not an M-SEARCH")
3767     sock.sendto("FOO", addr)
3768     time.sleep(0.1)
3769     dev[0].request("WPS_ER_STOP")
3770
3771     dev[0].request("WPS_ER_START ifname=lo")
3772     (msg,addr) = sock.recvfrom(1000)
3773     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3774     if "M-SEARCH" not in msg:
3775         raise Exception("Not an M-SEARCH")
3776     sock.sendto("FOO", addr)
3777     sock.sendto("HTTP/1.1 200 OK\r\nFOO\r\n\r\n", addr)
3778     sock.sendto("HTTP/1.1 200 OK\r\nNTS:foo\r\n\r\n", addr)
3779     sock.sendto("HTTP/1.1 200 OK\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3780     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   foo=1\r\n\r\n", addr)
3781     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   max-age=1\r\n\r\n", addr)
3782     sock.sendto("HTTP/1.1 200 OK\r\nusn:\r\n\r\n", addr)
3783     sock.sendto("HTTP/1.1 200 OK\r\nusn:foo\r\n\r\n", addr)
3784     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:\r\n\r\n", addr)
3785     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     \r\n\r\n", addr)
3786     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     foo\r\n\r\n", addr)
3787     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\n\r\n", addr)
3788     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)
3789     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\n\r\n", addr)
3790     with alloc_fail(dev[0], 1, "wps_er_ap_add"):
3791         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)
3792         time.sleep(0.1)
3793     with alloc_fail(dev[0], 2, "wps_er_ap_add"):
3794         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)
3795         time.sleep(0.1)
3796
3797     # Add an AP with bogus URL
3798     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)
3799     # Update timeout on AP without updating URL
3800     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)
3801     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3802     if ev is None:
3803         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3804
3805     # Add an AP with a valid URL (but no server listing to it)
3806     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)
3807     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3808     if ev is None:
3809         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3810
3811     sock.close()
3812
3813 wps_event_url = None
3814
3815 def gen_upnp_info(eventSubURL='wps_event', controlURL='wps_control',
3816                   udn='uuid:27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'):
3817     payload = '''<?xml version="1.0"?>
3818 <root xmlns="urn:schemas-upnp-org:device-1-0">
3819 <specVersion>
3820 <major>1</major>
3821 <minor>0</minor>
3822 </specVersion>
3823 <device>
3824 <deviceType>urn:schemas-wifialliance-org:device:WFADevice:1</deviceType>
3825 <friendlyName>WPS Access Point</friendlyName>
3826 <manufacturer>Company</manufacturer>
3827 <modelName>WAP</modelName>
3828 <modelNumber>123</modelNumber>
3829 <serialNumber>12345</serialNumber>
3830 '''
3831     if udn:
3832         payload += '<UDN>' + udn + '</UDN>'
3833     payload += '''<serviceList>
3834 <service>
3835 <serviceType>urn:schemas-wifialliance-org:service:WFAWLANConfig:1</serviceType>
3836 <serviceId>urn:wifialliance-org:serviceId:WFAWLANConfig1</serviceId>
3837 <SCPDURL>wps_scpd.xml</SCPDURL>
3838 '''
3839     if controlURL:
3840         payload += '<controlURL>' + controlURL + '</controlURL>\n'
3841     if eventSubURL:
3842         payload += '<eventSubURL>' + eventSubURL + '</eventSubURL>\n'
3843     payload += '''</service>
3844 </serviceList>
3845 </device>
3846 </root>
3847 '''
3848     hdr = 'HTTP/1.1 200 OK\r\n' + \
3849           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3850           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3851           'Connection: close\r\n' + \
3852           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3853           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3854     return hdr + payload
3855
3856 def gen_wps_control(payload_override=None):
3857     payload = '''<?xml version="1.0"?>
3858 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3859 <s:Body>
3860 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3861 <NewDeviceInfo>EEoAARAQIgABBBBHABAn6oAanlxOc72C+Jy80Q1+ECAABgIAAAADABAaABCJZ7DPtbU3Ust9
3862 Z3wJF07WEDIAwH45D3i1OqB7eJGwTzqeapS71h3KyXncK2xJZ+xqScrlorNEg6LijBJzG2Ca
3863 +FZli0iliDJd397yAx/jk4nFXco3q5ylBSvSw9dhJ5u1xBKSnTilKGlUHPhLP75PUqM3fot9
3864 7zwtFZ4bx6x1sBA6oEe2d0aUJmLumQGCiKEIWlnxs44zego/2tAe81bDzdPBM7o5HH/FUhD+
3865 KoGzFXp51atP+1n9Vta6AkI0Vye99JKLcC6Md9dMJltSVBgd4Xc4lRAEAAIAIxAQAAIADRAN
3866 AAEBEAgAAgAEEEQAAQIQIQAHQ29tcGFueRAjAANXQVAQJAADMTIzEEIABTEyMzQ1EFQACAAG
3867 AFDyBAABEBEAC1dpcmVsZXNzIEFQEDwAAQEQAgACAAAQEgACAAAQCQACAAAQLQAEgQIDABBJ
3868 AAYANyoAASA=
3869 </NewDeviceInfo>
3870 </u:GetDeviceInfoResponse>
3871 </s:Body>
3872 </s:Envelope>
3873 '''
3874     if payload_override:
3875         payload = payload_override
3876     hdr = 'HTTP/1.1 200 OK\r\n' + \
3877           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3878           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3879           'Connection: close\r\n' + \
3880           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3881           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3882     return hdr + payload
3883
3884 def gen_wps_event(sid='uuid:7eb3342a-8a5f-47fe-a585-0785bfec6d8a'):
3885     payload = ""
3886     hdr = 'HTTP/1.1 200 OK\r\n' + \
3887           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3888           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3889           'Connection: close\r\n' + \
3890           'Content-Length: ' + str(len(payload)) + '\r\n'
3891     if sid:
3892         hdr += 'SID: ' + sid + '\r\n'
3893     hdr += 'Timeout: Second-1801\r\n' + \
3894           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3895     return hdr + payload
3896
3897 class WPSAPHTTPServer(SocketServer.StreamRequestHandler):
3898     def handle(self):
3899         data = self.rfile.readline().strip()
3900         logger.info("HTTP server received: " + data)
3901         while True:
3902             hdr = self.rfile.readline().strip()
3903             if len(hdr) == 0:
3904                 break
3905             logger.info("HTTP header: " + hdr)
3906             if "CALLBACK:" in hdr:
3907                 global wps_event_url
3908                 wps_event_url = hdr.split(' ')[1].strip('<>')
3909
3910         if "GET /foo.xml" in data:
3911             self.handle_upnp_info()
3912         elif "POST /wps_control" in data:
3913             self.handle_wps_control()
3914         elif "SUBSCRIBE /wps_event" in data:
3915             self.handle_wps_event()
3916         else:
3917             self.handle_others(data)
3918
3919     def handle_upnp_info(self):
3920         self.wfile.write(gen_upnp_info())
3921
3922     def handle_wps_control(self):
3923         self.wfile.write(gen_wps_control())
3924
3925     def handle_wps_event(self):
3926         self.wfile.write(gen_wps_event())
3927
3928     def handle_others(self, data):
3929         logger.info("Ignore HTTP request: " + data)
3930
3931 class MyTCPServer(SocketServer.TCPServer):
3932     def __init__(self, addr, handler):
3933         self.allow_reuse_address = True
3934         SocketServer.TCPServer.__init__(self, addr, handler)
3935
3936 def wps_er_start(dev, http_server, max_age=1, wait_m_search=False,
3937                  location_url=None):
3938     socket.setdefaulttimeout(1)
3939     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3940     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3941     sock.bind(("239.255.255.250", 1900))
3942     dev.request("WPS_ER_START ifname=lo")
3943     for i in range(100):
3944         (msg,addr) = sock.recvfrom(1000)
3945         logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3946         if "M-SEARCH" in msg:
3947             break
3948         if not wait_m_search:
3949             raise Exception("Not an M-SEARCH")
3950         if i == 99:
3951             raise Exception("No M-SEARCH seen")
3952
3953     # Add an AP with a valid URL and server listing to it
3954     server = MyTCPServer(("127.0.0.1", 12345), http_server)
3955     if not location_url:
3956         location_url = 'http://127.0.0.1:12345/foo.xml'
3957     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)
3958     server.timeout = 1
3959     return server,sock
3960
3961 def wps_er_stop(dev, sock, server, on_alloc_fail=False):
3962     sock.close()
3963     server.server_close()
3964
3965     if on_alloc_fail:
3966         done = False
3967         for i in range(50):
3968             res = dev.request("GET_ALLOC_FAIL")
3969             if res.startswith("0:"):
3970                 done = True
3971                 break
3972             time.sleep(0.1)
3973         if not done:
3974             raise Exception("No allocation failure reported")
3975     else:
3976         ev = dev.wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3977         if ev is None:
3978             raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3979     dev.request("WPS_ER_STOP")
3980
3981 def run_wps_er_proto_test(dev, handler, no_event_url=False, location_url=None):
3982     try:
3983         uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3984         server,sock = wps_er_start(dev, handler, location_url=location_url)
3985         global wps_event_url
3986         wps_event_url = None
3987         server.handle_request()
3988         server.handle_request()
3989         server.handle_request()
3990         server.server_close()
3991         if no_event_url:
3992             if wps_event_url:
3993                 raise Exception("Received event URL unexpectedly")
3994             return
3995         if wps_event_url is None:
3996             raise Exception("Did not get event URL")
3997         logger.info("Event URL: " + wps_event_url)
3998     finally:
3999             dev.request("WPS_ER_STOP")
4000
4001 def send_wlanevent(url, uuid, data, no_response=False):
4002     conn = httplib.HTTPConnection(url.netloc)
4003     payload = '''<?xml version="1.0" encoding="utf-8"?>
4004 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
4005 <e:property><STAStatus>1</STAStatus></e:property>
4006 <e:property><APStatus>1</APStatus></e:property>
4007 <e:property><WLANEvent>'''
4008     payload += base64.b64encode(data)
4009     payload += '</WLANEvent></e:property></e:propertyset>'
4010     headers = { "Content-type": 'text/xml; charset="utf-8"',
4011                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4012                 "HOST": url.netloc,
4013                 "NT": "upnp:event",
4014                 "SID": "uuid:" + uuid,
4015                 "SEQ": "0",
4016                 "Content-Length": str(len(payload)) }
4017     conn.request("NOTIFY", url.path, payload, headers)
4018     if no_response:
4019         try:
4020             conn.getresponse()
4021         except Exception, e:
4022             pass
4023         return
4024     resp = conn.getresponse()
4025     if resp.status != 200:
4026         raise Exception("Unexpected HTTP response: %d" % resp.status)
4027
4028 def test_ap_wps_er_http_proto(dev, apdev):
4029     """WPS ER HTTP protocol testing"""
4030     try:
4031         _test_ap_wps_er_http_proto(dev, apdev)
4032     finally:
4033         dev[0].request("WPS_ER_STOP")
4034
4035 def _test_ap_wps_er_http_proto(dev, apdev):
4036     uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
4037     server,sock = wps_er_start(dev[0], WPSAPHTTPServer, max_age=15)
4038     global wps_event_url
4039     wps_event_url = None
4040     server.handle_request()
4041     server.handle_request()
4042     server.handle_request()
4043     server.server_close()
4044     if wps_event_url is None:
4045         raise Exception("Did not get event URL")
4046     logger.info("Event URL: " + wps_event_url)
4047
4048     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
4049     if ev is None:
4050         raise Exception("No WPS-ER-AP-ADD event")
4051     if uuid not in ev:
4052         raise Exception("UUID mismatch")
4053
4054     sock.close()
4055
4056     logger.info("Valid Probe Request notification")
4057     url = urlparse.urlparse(wps_event_url)
4058     conn = httplib.HTTPConnection(url.netloc)
4059     payload = '''<?xml version="1.0" encoding="utf-8"?>
4060 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
4061 <e:property><STAStatus>1</STAStatus></e:property>
4062 <e:property><APStatus>1</APStatus></e:property>
4063 <e:property><WLANEvent>ATAyOjAwOjAwOjAwOjAwOjAwEEoAARAQOgABAhAIAAIxSBBHABA2LbR7pTpRkYj7VFi5hrLk
4064 EFQACAAAAAAAAAAAEDwAAQMQAgACAAAQCQACAAAQEgACAAAQIQABIBAjAAEgECQAASAQEQAI
4065 RGV2aWNlIEEQSQAGADcqAAEg
4066 </WLANEvent></e:property>
4067 </e:propertyset>
4068 '''
4069     headers = { "Content-type": 'text/xml; charset="utf-8"',
4070                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4071                 "HOST": url.netloc,
4072                 "NT": "upnp:event",
4073                 "SID": "uuid:" + uuid,
4074                 "SEQ": "0",
4075                 "Content-Length": str(len(payload)) }
4076     conn.request("NOTIFY", url.path, payload, headers)
4077     resp = conn.getresponse()
4078     if resp.status != 200:
4079         raise Exception("Unexpected HTTP response: %d" % resp.status)
4080
4081     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=5)
4082     if ev is None:
4083         raise Exception("No WPS-ER-ENROLLEE-ADD event")
4084     if "362db47b-a53a-5191-88fb-5458b986b2e4" not in ev:
4085         raise Exception("No Enrollee UUID match")
4086
4087     logger.info("Incorrect event URL AP id")
4088     conn = httplib.HTTPConnection(url.netloc)
4089     conn.request("NOTIFY", url.path + '123', payload, headers)
4090     resp = conn.getresponse()
4091     if resp.status != 404:
4092         raise Exception("Unexpected HTTP response: %d" % resp.status)
4093
4094     logger.info("Missing AP id")
4095     conn = httplib.HTTPConnection(url.netloc)
4096     conn.request("NOTIFY", '/event/' + url.path.split('/')[2],
4097                  payload, headers)
4098     time.sleep(0.1)
4099
4100     logger.info("Incorrect event URL event id")
4101     conn = httplib.HTTPConnection(url.netloc)
4102     conn.request("NOTIFY", '/event/123456789/123', payload, headers)
4103     time.sleep(0.1)
4104
4105     logger.info("Incorrect event URL prefix")
4106     conn = httplib.HTTPConnection(url.netloc)
4107     conn.request("NOTIFY", '/foobar/123456789/123', payload, headers)
4108     resp = conn.getresponse()
4109     if resp.status != 404:
4110         raise Exception("Unexpected HTTP response: %d" % resp.status)
4111
4112     logger.info("Unsupported request")
4113     conn = httplib.HTTPConnection(url.netloc)
4114     conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4115     resp = conn.getresponse()
4116     if resp.status != 501:
4117         raise Exception("Unexpected HTTP response: %d" % resp.status)
4118
4119     logger.info("Unsupported request and OOM")
4120     with alloc_fail(dev[0], 1, "wps_er_http_req"):
4121         conn = httplib.HTTPConnection(url.netloc)
4122         conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4123         time.sleep(0.5)
4124
4125     logger.info("Too short WLANEvent")
4126     data = '\x00'
4127     send_wlanevent(url, uuid, data)
4128
4129     logger.info("Invalid WLANEventMAC")
4130     data = '\x00qwertyuiopasdfghjklzxcvbnm'
4131     send_wlanevent(url, uuid, data)
4132
4133     logger.info("Unknown WLANEventType")
4134     data = '\xff02:00:00:00:00:00'
4135     send_wlanevent(url, uuid, data)
4136
4137     logger.info("Probe Request notification without any attributes")
4138     data = '\x0102:00:00:00:00:00'
4139     send_wlanevent(url, uuid, data)
4140
4141     logger.info("Probe Request notification with invalid attribute")
4142     data = '\x0102:00:00:00:00:00\xff'
4143     send_wlanevent(url, uuid, data)
4144
4145     logger.info("EAP message without any attributes")
4146     data = '\x0202:00:00:00:00:00'
4147     send_wlanevent(url, uuid, data)
4148
4149     logger.info("EAP message with invalid attribute")
4150     data = '\x0202:00:00:00:00:00\xff'
4151     send_wlanevent(url, uuid, data)
4152
4153     logger.info("EAP message from new STA and not M1")
4154     data = '\x0202:ff:ff:ff:ff:ff' + '\x10\x22\x00\x01\x05'
4155     send_wlanevent(url, uuid, data)
4156
4157     logger.info("EAP message: M1")
4158     data = '\x0202:00:00:00:00:00'
4159     data += '\x10\x22\x00\x01\x04'
4160     data += '\x10\x47\x00\x10' + 16*'\x00'
4161     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4162     data += '\x10\x1a\x00\x10' + 16*'\x00'
4163     data += '\x10\x32\x00\xc0' + 192*'\x00'
4164     data += '\x10\x04\x00\x02\x00\x00'
4165     data += '\x10\x10\x00\x02\x00\x00'
4166     data += '\x10\x0d\x00\x01\x00'
4167     data += '\x10\x08\x00\x02\x00\x00'
4168     data += '\x10\x44\x00\x01\x00'
4169     data += '\x10\x21\x00\x00'
4170     data += '\x10\x23\x00\x00'
4171     data += '\x10\x24\x00\x00'
4172     data += '\x10\x42\x00\x00'
4173     data += '\x10\x54\x00\x08' + 8*'\x00'
4174     data += '\x10\x11\x00\x00'
4175     data += '\x10\x3c\x00\x01\x00'
4176     data += '\x10\x02\x00\x02\x00\x00'
4177     data += '\x10\x12\x00\x02\x00\x00'
4178     data += '\x10\x09\x00\x02\x00\x00'
4179     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4180     m1 = data
4181     send_wlanevent(url, uuid, data)
4182
4183     logger.info("EAP message: WSC_ACK")
4184     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0d'
4185     send_wlanevent(url, uuid, data)
4186
4187     logger.info("EAP message: M1")
4188     send_wlanevent(url, uuid, m1)
4189
4190     logger.info("EAP message: WSC_NACK")
4191     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0e'
4192     send_wlanevent(url, uuid, data)
4193
4194     logger.info("EAP message: M1 - Too long attribute values")
4195     data = '\x0202:00:00:00:00:00'
4196     data += '\x10\x11\x00\x21' + 33*'\x00'
4197     data += '\x10\x45\x00\x21' + 33*'\x00'
4198     data += '\x10\x42\x00\x21' + 33*'\x00'
4199     data += '\x10\x24\x00\x21' + 33*'\x00'
4200     data += '\x10\x23\x00\x21' + 33*'\x00'
4201     data += '\x10\x21\x00\x41' + 65*'\x00'
4202     data += '\x10\x49\x00\x09\x00\x37\x2a\x05\x02\x00\x00\x05\x00'
4203     send_wlanevent(url, uuid, data)
4204
4205     logger.info("EAP message: M1 missing UUID-E")
4206     data = '\x0202:00:00:00:00:00'
4207     data += '\x10\x22\x00\x01\x04'
4208     send_wlanevent(url, uuid, data)
4209
4210     logger.info("EAP message: M1 missing MAC Address")
4211     data += '\x10\x47\x00\x10' + 16*'\x00'
4212     send_wlanevent(url, uuid, data)
4213
4214     logger.info("EAP message: M1 missing Enrollee Nonce")
4215     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4216     send_wlanevent(url, uuid, data)
4217
4218     logger.info("EAP message: M1 missing Public Key")
4219     data += '\x10\x1a\x00\x10' + 16*'\x00'
4220     send_wlanevent(url, uuid, data)
4221
4222     logger.info("EAP message: M1 missing Authentication Type flags")
4223     data += '\x10\x32\x00\xc0' + 192*'\x00'
4224     send_wlanevent(url, uuid, data)
4225
4226     logger.info("EAP message: M1 missing Encryption Type Flags")
4227     data += '\x10\x04\x00\x02\x00\x00'
4228     send_wlanevent(url, uuid, data)
4229
4230     logger.info("EAP message: M1 missing Connection Type flags")
4231     data += '\x10\x10\x00\x02\x00\x00'
4232     send_wlanevent(url, uuid, data)
4233
4234     logger.info("EAP message: M1 missing Config Methods")
4235     data += '\x10\x0d\x00\x01\x00'
4236     send_wlanevent(url, uuid, data)
4237
4238     logger.info("EAP message: M1 missing Wi-Fi Protected Setup State")
4239     data += '\x10\x08\x00\x02\x00\x00'
4240     send_wlanevent(url, uuid, data)
4241
4242     logger.info("EAP message: M1 missing Manufacturer")
4243     data += '\x10\x44\x00\x01\x00'
4244     send_wlanevent(url, uuid, data)
4245
4246     logger.info("EAP message: M1 missing Model Name")
4247     data += '\x10\x21\x00\x00'
4248     send_wlanevent(url, uuid, data)
4249
4250     logger.info("EAP message: M1 missing Model Number")
4251     data += '\x10\x23\x00\x00'
4252     send_wlanevent(url, uuid, data)
4253
4254     logger.info("EAP message: M1 missing Serial Number")
4255     data += '\x10\x24\x00\x00'
4256     send_wlanevent(url, uuid, data)
4257
4258     logger.info("EAP message: M1 missing Primary Device Type")
4259     data += '\x10\x42\x00\x00'
4260     send_wlanevent(url, uuid, data)
4261
4262     logger.info("EAP message: M1 missing Device Name")
4263     data += '\x10\x54\x00\x08' + 8*'\x00'
4264     send_wlanevent(url, uuid, data)
4265
4266     logger.info("EAP message: M1 missing RF Bands")
4267     data += '\x10\x11\x00\x00'
4268     send_wlanevent(url, uuid, data)
4269
4270     logger.info("EAP message: M1 missing Association State")
4271     data += '\x10\x3c\x00\x01\x00'
4272     send_wlanevent(url, uuid, data)
4273
4274     logger.info("EAP message: M1 missing Device Password ID")
4275     data += '\x10\x02\x00\x02\x00\x00'
4276     send_wlanevent(url, uuid, data)
4277
4278     logger.info("EAP message: M1 missing Configuration Error")
4279     data += '\x10\x12\x00\x02\x00\x00'
4280     send_wlanevent(url, uuid, data)
4281
4282     logger.info("EAP message: M1 missing OS Version")
4283     data += '\x10\x09\x00\x02\x00\x00'
4284     send_wlanevent(url, uuid, data)
4285
4286     logger.info("Check max concurrent requests")
4287     addr = (url.hostname, url.port)
4288     socks = {}
4289     for i in range(20):
4290         socks[i] = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4291                                  socket.IPPROTO_TCP)
4292         socks[i].connect(addr)
4293     for i in range(20):
4294         socks[i].send("GET / HTTP/1.1\r\n\r\n")
4295     count = 0
4296     for i in range(20):
4297         try:
4298             res = socks[i].recv(100)
4299             if "HTTP/1" in res:
4300                 count += 1
4301         except:
4302             pass
4303         socks[i].close()
4304     logger.info("%d concurrent HTTP GET operations returned response" % count)
4305     if count < 10:
4306         raise Exception("Too few concurrent HTTP connections accepted")
4307
4308     logger.info("OOM in HTTP server")
4309     for func in [ "http_request_init", "httpread_create",
4310                   "eloop_register_timeout;httpread_create",
4311                   "eloop_register_sock;httpread_create",
4312                   "httpread_hdr_analyze" ]:
4313         with alloc_fail(dev[0], 1, func):
4314             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4315                                  socket.IPPROTO_TCP)
4316             sock.connect(addr)
4317             sock.send("GET / HTTP/1.1\r\n\r\n")
4318             try:
4319                 sock.recv(100)
4320             except:
4321                 pass
4322             sock.close()
4323
4324     logger.info("Invalid HTTP header")
4325     for req in [ " GET / HTTP/1.1\r\n\r\n",
4326                  "HTTP/1.1 200 OK\r\n\r\n",
4327                  "HTTP/\r\n\r\n",
4328                  "GET %%a%aa% HTTP/1.1\r\n\r\n",
4329                  "GET / HTTP/1.1\r\n FOO\r\n\r\n",
4330                  "NOTIFY / HTTP/1.1\r\n" + 4097*'a' + '\r\n\r\n',
4331                  "NOTIFY / HTTP/1.1\r\n\r\n" + 8193*'a',
4332                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n foo\r\n",
4333                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n1\r\nfoo\r\n",
4334                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\n",
4335                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\naa\ra\r\n\ra" ]:
4336         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4337                              socket.IPPROTO_TCP)
4338         sock.settimeout(0.1)
4339         sock.connect(addr)
4340         sock.send(req)
4341         try:
4342             sock.recv(100)
4343         except:
4344             pass
4345         sock.close()
4346
4347     with alloc_fail(dev[0], 2, "httpread_read_handler"):
4348         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4349                              socket.IPPROTO_TCP)
4350         sock.connect(addr)
4351         sock.send("NOTIFY / HTTP/1.1\r\n\r\n" + 4500*'a')
4352         try:
4353             sock.recv(100)
4354         except:
4355             pass
4356         sock.close()
4357
4358     conn = httplib.HTTPConnection(url.netloc)
4359     payload = '<foo'
4360     headers = { "Content-type": 'text/xml; charset="utf-8"',
4361                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4362                 "HOST": url.netloc,
4363                 "NT": "upnp:event",
4364                 "SID": "uuid:" + uuid,
4365                 "SEQ": "0",
4366                 "Content-Length": str(len(payload)) }
4367     conn.request("NOTIFY", url.path, payload, headers)
4368     resp = conn.getresponse()
4369     if resp.status != 200:
4370         raise Exception("Unexpected HTTP response: %d" % resp.status)
4371
4372     conn = httplib.HTTPConnection(url.netloc)
4373     payload = '<WLANEvent foo></WLANEvent>'
4374     headers = { "Content-type": 'text/xml; charset="utf-8"',
4375                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4376                 "HOST": url.netloc,
4377                 "NT": "upnp:event",
4378                 "SID": "uuid:" + uuid,
4379                 "SEQ": "0",
4380                 "Content-Length": str(len(payload)) }
4381     conn.request("NOTIFY", url.path, payload, headers)
4382     resp = conn.getresponse()
4383     if resp.status != 200:
4384         raise Exception("Unexpected HTTP response: %d" % resp.status)
4385
4386     with alloc_fail(dev[0], 1, "xml_get_first_item"):
4387         send_wlanevent(url, uuid, '')
4388
4389     with alloc_fail(dev[0], 1, "wpabuf_alloc_ext_data;xml_get_base64_item"):
4390         send_wlanevent(url, uuid, 'foo')
4391
4392     for func in [ "wps_init",
4393                   "wps_process_manufacturer",
4394                   "wps_process_model_name",
4395                   "wps_process_model_number",
4396                   "wps_process_serial_number",
4397                   "wps_process_dev_name" ]:
4398         with alloc_fail(dev[0], 1, func):
4399             send_wlanevent(url, uuid, m1)
4400
4401     with alloc_fail(dev[0], 1, "wps_er_http_resp_ok"):
4402         send_wlanevent(url, uuid, m1, no_response=True)
4403
4404     with alloc_fail(dev[0], 1, "wps_er_http_resp_not_found"):
4405         url2 = urlparse.urlparse(wps_event_url.replace('/event/', '/notfound/'))
4406         send_wlanevent(url2, uuid, m1, no_response=True)
4407
4408     logger.info("EAP message: M1")
4409     data = '\x0202:11:22:00:00:00'
4410     data += '\x10\x22\x00\x01\x04'
4411     data += '\x10\x47\x00\x10' + 16*'\x00'
4412     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4413     data += '\x10\x1a\x00\x10' + 16*'\x00'
4414     data += '\x10\x32\x00\xc0' + 192*'\x00'
4415     data += '\x10\x04\x00\x02\x00\x00'
4416     data += '\x10\x10\x00\x02\x00\x00'
4417     data += '\x10\x0d\x00\x01\x00'
4418     data += '\x10\x08\x00\x02\x00\x00'
4419     data += '\x10\x44\x00\x01\x00'
4420     data += '\x10\x21\x00\x00'
4421     data += '\x10\x23\x00\x00'
4422     data += '\x10\x24\x00\x00'
4423     data += '\x10\x42\x00\x00'
4424     data += '\x10\x54\x00\x08' + 8*'\x00'
4425     data += '\x10\x11\x00\x00'
4426     data += '\x10\x3c\x00\x01\x00'
4427     data += '\x10\x02\x00\x02\x00\x00'
4428     data += '\x10\x12\x00\x02\x00\x00'
4429     data += '\x10\x09\x00\x02\x00\x00'
4430     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4431     dev[0].dump_monitor()
4432     with alloc_fail(dev[0], 1, "wps_er_add_sta_data"):
4433         send_wlanevent(url, uuid, data)
4434         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=0.1)
4435         if ev is not None:
4436             raise Exception("Unexpected enrollee add event")
4437     send_wlanevent(url, uuid, data)
4438     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=2)
4439     if ev is None:
4440         raise Exception("Enrollee add event not seen")
4441
4442     with alloc_fail(dev[0], 1, "base64_encode;wps_er_soap_hdr"):
4443         send_wlanevent(url, uuid, data)
4444
4445     with alloc_fail(dev[0], 1, "wpabuf_alloc;wps_er_soap_hdr"):
4446         send_wlanevent(url, uuid, data)
4447
4448     with alloc_fail(dev[0], 1, "http_client_url_parse;wps_er_sta_send_msg"):
4449         send_wlanevent(url, uuid, data)
4450
4451     with alloc_fail(dev[0], 1, "http_client_addr;wps_er_sta_send_msg"):
4452         send_wlanevent(url, uuid, data)
4453
4454 def test_ap_wps_er_http_proto_no_event_sub_url(dev, apdev):
4455     """WPS ER HTTP protocol testing - no eventSubURL"""
4456     class WPSAPHTTPServer_no_event_sub_url(WPSAPHTTPServer):
4457         def handle_upnp_info(self):
4458             self.wfile.write(gen_upnp_info(eventSubURL=None))
4459     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_event_sub_url,
4460                           no_event_url=True)
4461
4462 def test_ap_wps_er_http_proto_event_sub_url_dns(dev, apdev):
4463     """WPS ER HTTP protocol testing - DNS name in eventSubURL"""
4464     class WPSAPHTTPServer_event_sub_url_dns(WPSAPHTTPServer):
4465         def handle_upnp_info(self):
4466             self.wfile.write(gen_upnp_info(eventSubURL='http://example.com/wps_event'))
4467     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_event_sub_url_dns,
4468                           no_event_url=True)
4469
4470 def test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4471     """WPS ER HTTP protocol testing - subscribe OOM"""
4472     try:
4473         _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev)
4474     finally:
4475         dev[0].request("WPS_ER_STOP")
4476
4477 def _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4478     tests = [ (1, "http_client_url_parse"),
4479               (1, "wpabuf_alloc;wps_er_subscribe"),
4480               (1, "http_client_addr"),
4481               (1, "eloop_register_sock;http_client_addr"),
4482               (1, "eloop_register_timeout;http_client_addr") ]
4483     for count,func in tests:
4484         with alloc_fail(dev[0], count, func):
4485             server,sock = wps_er_start(dev[0], WPSAPHTTPServer)
4486             server.handle_request()
4487             server.handle_request()
4488             wps_er_stop(dev[0], sock, server, on_alloc_fail=True)
4489
4490 def test_ap_wps_er_http_proto_no_sid(dev, apdev):
4491     """WPS ER HTTP protocol testing - no SID"""
4492     class WPSAPHTTPServer_no_sid(WPSAPHTTPServer):
4493         def handle_wps_event(self):
4494             self.wfile.write(gen_wps_event(sid=None))
4495     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_sid)
4496
4497 def test_ap_wps_er_http_proto_invalid_sid_no_uuid(dev, apdev):
4498     """WPS ER HTTP protocol testing - invalid SID - no UUID"""
4499     class WPSAPHTTPServer_invalid_sid_no_uuid(WPSAPHTTPServer):
4500         def handle_wps_event(self):
4501             self.wfile.write(gen_wps_event(sid='FOO'))
4502     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_no_uuid)
4503
4504 def test_ap_wps_er_http_proto_invalid_sid_uuid(dev, apdev):
4505     """WPS ER HTTP protocol testing - invalid SID UUID"""
4506     class WPSAPHTTPServer_invalid_sid_uuid(WPSAPHTTPServer):
4507         def handle_wps_event(self):
4508             self.wfile.write(gen_wps_event(sid='uuid:FOO'))
4509     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_uuid)
4510
4511 def test_ap_wps_er_http_proto_subscribe_failing(dev, apdev):
4512     """WPS ER HTTP protocol testing - SUBSCRIBE failing"""
4513     class WPSAPHTTPServer_fail_subscribe(WPSAPHTTPServer):
4514         def handle_wps_event(self):
4515             payload = ""
4516             hdr = 'HTTP/1.1 404 Not Found\r\n' + \
4517                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4518                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4519                   'Connection: close\r\n' + \
4520                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4521                   'Timeout: Second-1801\r\n' + \
4522                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4523             self.wfile.write(hdr + payload)
4524     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_fail_subscribe)
4525
4526 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4527     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4528     class WPSAPHTTPServer_subscribe_invalid_response(WPSAPHTTPServer):
4529         def handle_wps_event(self):
4530             payload = ""
4531             hdr = 'HTTP/1.1 FOO\r\n' + \
4532                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4533                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4534                   'Connection: close\r\n' + \
4535                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4536                   'Timeout: Second-1801\r\n' + \
4537                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4538             self.wfile.write(hdr + payload)
4539     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_subscribe_invalid_response)
4540
4541 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4542     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4543     class WPSAPHTTPServer_invalid_m1(WPSAPHTTPServer):
4544         def handle_wps_control(self):
4545             payload = '''<?xml version="1.0"?>
4546 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
4547 <s:Body>
4548 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
4549 <NewDeviceInfo>Rk9P</NewDeviceInfo>
4550 </u:GetDeviceInfoResponse>
4551 </s:Body>
4552 </s:Envelope>
4553 '''
4554             self.wfile.write(gen_wps_control(payload_override=payload))
4555     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_m1, no_event_url=True)
4556
4557 def test_ap_wps_er_http_proto_upnp_info_no_device(dev, apdev):
4558     """WPS ER HTTP protocol testing - No device in UPnP info"""
4559     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4560         def handle_upnp_info(self):
4561             payload = '''<?xml version="1.0"?>
4562 <root xmlns="urn:schemas-upnp-org:device-1-0">
4563 <specVersion>
4564 <major>1</major>
4565 <minor>0</minor>
4566 </specVersion>
4567 </root>
4568 '''
4569             hdr = 'HTTP/1.1 200 OK\r\n' + \
4570                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4571                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4572                   'Connection: close\r\n' + \
4573                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4574                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4575             self.wfile.write(hdr + payload)
4576     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4577
4578 def test_ap_wps_er_http_proto_upnp_info_no_device_type(dev, apdev):
4579     """WPS ER HTTP protocol testing - No deviceType in UPnP info"""
4580     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4581         def handle_upnp_info(self):
4582             payload = '''<?xml version="1.0"?>
4583 <root xmlns="urn:schemas-upnp-org:device-1-0">
4584 <specVersion>
4585 <major>1</major>
4586 <minor>0</minor>
4587 </specVersion>
4588 <device>
4589 </device>
4590 </root>
4591 '''
4592             hdr = 'HTTP/1.1 200 OK\r\n' + \
4593                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4594                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4595                   'Connection: close\r\n' + \
4596                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4597                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4598             self.wfile.write(hdr + payload)
4599     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4600
4601 def test_ap_wps_er_http_proto_upnp_info_invalid_udn_uuid(dev, apdev):
4602     """WPS ER HTTP protocol testing - Invalid UDN UUID"""
4603     class WPSAPHTTPServer_invalid_udn_uuid(WPSAPHTTPServer):
4604         def handle_upnp_info(self):
4605             self.wfile.write(gen_upnp_info(udn='uuid:foo'))
4606     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_udn_uuid)
4607
4608 def test_ap_wps_er_http_proto_no_control_url(dev, apdev):
4609     """WPS ER HTTP protocol testing - no controlURL"""
4610     class WPSAPHTTPServer_no_control_url(WPSAPHTTPServer):
4611         def handle_upnp_info(self):
4612             self.wfile.write(gen_upnp_info(controlURL=None))
4613     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_control_url,
4614                           no_event_url=True)
4615
4616 def test_ap_wps_er_http_proto_control_url_dns(dev, apdev):
4617     """WPS ER HTTP protocol testing - DNS name in controlURL"""
4618     class WPSAPHTTPServer_control_url_dns(WPSAPHTTPServer):
4619         def handle_upnp_info(self):
4620             self.wfile.write(gen_upnp_info(controlURL='http://example.com/wps_control'))
4621     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_control_url_dns,
4622                           no_event_url=True)
4623
4624 def test_ap_wps_http_timeout(dev, apdev):
4625     """WPS AP/ER and HTTP timeout"""
4626     try:
4627         _test_ap_wps_http_timeout(dev, apdev)
4628     finally:
4629         dev[0].request("WPS_ER_STOP")
4630
4631 def _test_ap_wps_http_timeout(dev, apdev):
4632     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
4633     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
4634
4635     location = ssdp_get_location(ap_uuid)
4636     url = urlparse.urlparse(location)
4637     addr = (url.hostname, url.port)
4638     logger.debug("Open HTTP connection to hostapd, but do not complete request")
4639     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4640                          socket.IPPROTO_TCP)
4641     sock.connect(addr)
4642     sock.send("G")
4643
4644     class DummyServer(SocketServer.StreamRequestHandler):
4645         def handle(self):
4646             logger.debug("DummyServer - start 31 sec wait")
4647             time.sleep(31)
4648             logger.debug("DummyServer - wait done")
4649
4650     logger.debug("Start WPS ER")
4651     server,sock2 = wps_er_start(dev[0], DummyServer, max_age=40,
4652                                 wait_m_search=True)
4653
4654     logger.debug("Start server to accept, but not complete, HTTP connection from WPS ER")
4655     # This will wait for 31 seconds..
4656     server.handle_request()
4657
4658     logger.debug("Complete HTTP connection with hostapd (that should have already closed the connection)")
4659     try:
4660         sock.send("ET / HTTP/1.1\r\n\r\n")
4661         res = sock.recv(100)
4662         sock.close()
4663     except:
4664         pass
4665
4666 def test_ap_wps_er_url_parse(dev, apdev):
4667     """WPS ER and URL parsing special cases"""
4668     try:
4669         _test_ap_wps_er_url_parse(dev, apdev)
4670     finally:
4671         dev[0].request("WPS_ER_STOP")
4672
4673 def _test_ap_wps_er_url_parse(dev, apdev):
4674     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4675     sock.settimeout(1)
4676     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4677     sock.bind(("239.255.255.250", 1900))
4678     dev[0].request("WPS_ER_START ifname=lo")
4679     (msg,addr) = sock.recvfrom(1000)
4680     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4681     if "M-SEARCH" not in msg:
4682         raise Exception("Not an M-SEARCH")
4683     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)
4684     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4685     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)
4686     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4687     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)
4688     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4689
4690     sock.close()
4691
4692 def test_ap_wps_er_link_update(dev, apdev):
4693     """WPS ER and link update special cases"""
4694     class WPSAPHTTPServer_link_update(WPSAPHTTPServer):
4695         def handle_upnp_info(self):
4696             self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4697     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update)
4698
4699     class WPSAPHTTPServer_link_update2(WPSAPHTTPServer):
4700         def handle_others(self, data):
4701             if "GET / " in data:
4702                 self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4703     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update2,
4704                           location_url='http://127.0.0.1:12345')
4705
4706 def test_ap_wps_er_http_client(dev, apdev):
4707     """WPS ER and HTTP client special cases"""
4708     with alloc_fail(dev[0], 1, "http_link_update"):
4709         run_wps_er_proto_test(dev[0], WPSAPHTTPServer)
4710
4711     with alloc_fail(dev[0], 1, "wpabuf_alloc;http_client_url"):
4712         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4713
4714     with alloc_fail(dev[0], 1, "httpread_create;http_client_tx_ready"):
4715         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4716
4717     class WPSAPHTTPServer_req_as_resp(WPSAPHTTPServer):
4718         def handle_upnp_info(self):
4719             self.wfile.write("GET / HTTP/1.1\r\n\r\n")
4720     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_req_as_resp,
4721                           no_event_url=True)
4722
4723 def test_ap_wps_init_oom(dev, apdev):
4724     """wps_init OOM cases"""
4725     ssid = "test-wps"
4726     appin = "12345670"
4727     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4728                "ap_pin": appin }
4729     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4730     pin = dev[0].wps_read_pin()
4731
4732     with alloc_fail(hapd, 1, "wps_init"):
4733         hapd.request("WPS_PIN any " + pin)
4734         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4735         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4736         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4737         if ev is None:
4738             raise Exception("No EAP failure reported")
4739         dev[0].request("WPS_CANCEL")
4740
4741     with alloc_fail(dev[0], 2, "wps_init"):
4742         hapd.request("WPS_PIN any " + pin)
4743         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4744         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4745         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4746         if ev is None:
4747             raise Exception("No EAP failure reported")
4748         dev[0].request("WPS_CANCEL")
4749
4750     with alloc_fail(dev[0], 2, "wps_init"):
4751         hapd.request("WPS_PBC")
4752         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4753         dev[0].request("WPS_PBC %s" % (apdev[0]['bssid']))
4754         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4755         if ev is None:
4756             raise Exception("No EAP failure reported")
4757         dev[0].request("WPS_CANCEL")
4758
4759     dev[0].dump_monitor()
4760     new_ssid = "wps-new-ssid"
4761     new_passphrase = "1234567890"
4762     with alloc_fail(dev[0], 3, "wps_init"):
4763         dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
4764                        new_passphrase, no_wait=True)
4765         ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4766         if ev is None:
4767             raise Exception("No EAP failure reported")
4768
4769     dev[0].flush_scan_cache()
4770
4771 def test_ap_wps_invalid_assoc_req_elem(dev, apdev):
4772     """WPS and invalid IE in Association Request frame"""
4773     ssid = "test-wps"
4774     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4775     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4776     pin = "12345670"
4777     hapd.request("WPS_PIN any " + pin)
4778     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4779     try:
4780         dev[0].request("VENDOR_ELEM_ADD 13 dd050050f20410")
4781         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4782         for i in range(5):
4783             ev = hapd.wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
4784             if ev and "vendor=14122" in ev:
4785                 break
4786         if ev is None or "vendor=14122" not in ev:
4787             raise Exception("EAP-WSC not started")
4788         dev[0].request("WPS_CANCEL")
4789     finally:
4790         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
4791
4792 def test_ap_wps_pbc_pin_mismatch(dev, apdev):
4793     """WPS PBC/PIN mismatch"""
4794     ssid = "test-wps"
4795     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4796     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4797     hapd.request("SET wps_version_number 0x10")
4798     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4799     hapd.request("WPS_PBC")
4800     pin = dev[0].wps_read_pin()
4801     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4802     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4803     if ev is None:
4804         raise Exception("Scan did not complete")
4805     dev[0].request("WPS_CANCEL")
4806
4807     hapd.request("WPS_CANCEL")
4808     dev[0].flush_scan_cache()
4809
4810 def test_ap_wps_ie_invalid(dev, apdev):
4811     """WPS PIN attempt with AP that has invalid WSC IE"""
4812     ssid = "test-wps"
4813     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4814                "vendor_elements": "dd050050f20410" }
4815     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4816     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4817     hostapd.add_ap(apdev[1]['ifname'], params)
4818     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4819     pin = dev[0].wps_read_pin()
4820     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4821     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4822     if ev is None:
4823         raise Exception("Scan did not complete")
4824     dev[0].request("WPS_CANCEL")
4825
4826 def test_ap_wps_scan_prio_order(dev, apdev):
4827     """WPS scan priority ordering"""
4828     ssid = "test-wps"
4829     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4830     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4831     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4832     hostapd.add_ap(apdev[1]['ifname'], params)
4833     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4834     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4835     pin = dev[0].wps_read_pin()
4836     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4837     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4838     if ev is None:
4839         raise Exception("Scan did not complete")
4840     dev[0].request("WPS_CANCEL")
4841
4842 def test_ap_wps_probe_req_ie_oom(dev, apdev):
4843     """WPS ProbeReq IE OOM"""
4844     ssid = "test-wps"
4845     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4846     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4847     pin = dev[0].wps_read_pin()
4848     hapd.request("WPS_PIN any " + pin)
4849     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4850     with alloc_fail(dev[0], 1, "wps_build_probe_req_ie"):
4851         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4852         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4853         if ev is None:
4854             raise Exception("Association not seen")
4855     dev[0].request("WPS_CANCEL")
4856
4857     with alloc_fail(dev[0], 1, "wps_ie_encapsulate"):
4858         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4859         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4860         if ev is None:
4861             raise Exception("Association not seen")
4862     dev[0].request("WPS_CANCEL")
4863
4864 def test_ap_wps_assoc_req_ie_oom(dev, apdev):
4865     """WPS AssocReq IE OOM"""
4866     ssid = "test-wps"
4867     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4868     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4869     pin = dev[0].wps_read_pin()
4870     hapd.request("WPS_PIN any " + pin)
4871     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4872     with alloc_fail(dev[0], 1, "wps_build_assoc_req_ie"):
4873         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4874         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4875         if ev is None:
4876             raise Exception("Association not seen")
4877     dev[0].request("WPS_CANCEL")
4878
4879 def test_ap_wps_assoc_resp_ie_oom(dev, apdev):
4880     """WPS AssocResp IE OOM"""
4881     ssid = "test-wps"
4882     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4883     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4884     pin = dev[0].wps_read_pin()
4885     hapd.request("WPS_PIN any " + pin)
4886     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4887     with alloc_fail(hapd, 1, "wps_build_assoc_resp_ie"):
4888         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4889         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4890         if ev is None:
4891             raise Exception("Association not seen")
4892     dev[0].request("WPS_CANCEL")
4893
4894 def test_ap_wps_bss_info_errors(dev, apdev):
4895     """WPS BSS info errors"""
4896     params = { "ssid": "1",
4897                "vendor_elements": "dd0e0050f20410440001ff101100010a" }
4898     hostapd.add_ap(apdev[0]['ifname'], params)
4899     params = { 'ssid': "2", "vendor_elements": "dd050050f20410" }
4900     hostapd.add_ap(apdev[1]['ifname'], params)
4901     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4902     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4903     bss = dev[0].get_bss(apdev[0]['bssid'])
4904     logger.info("BSS: " + str(bss))
4905     if "wps_state" in bss:
4906         raise Exception("Unexpected wps_state in BSS info")
4907     if 'wps_device_name' not in bss:
4908         raise Exception("No wps_device_name in BSS info")
4909     if bss['wps_device_name'] != '_':
4910         raise Exception("Unexpected wps_device_name value")
4911     bss = dev[0].get_bss(apdev[1]['bssid'])
4912     logger.info("BSS: " + str(bss))
4913
4914     with alloc_fail(dev[0], 1, "=wps_attr_text"):
4915         bss = dev[0].get_bss(apdev[0]['bssid'])
4916         logger.info("BSS(OOM): " + str(bss))
4917
4918 def wps_run_pbc_fail_ap(apdev, dev, hapd):
4919     hapd.request("WPS_PBC")
4920     dev.scan_for_bss(apdev['bssid'], freq="2412")
4921     dev.request("WPS_PBC " + apdev['bssid'])
4922     ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4923     if ev is None:
4924         raise Exception("No EAP failure reported")
4925     dev.request("WPS_CANCEL")
4926     dev.wait_disconnected()
4927     for i in range(5):
4928         try:
4929             dev.flush_scan_cache()
4930             break
4931         except Exception, e:
4932             if str(e).startswith("Failed to trigger scan"):
4933                 # Try again
4934                 time.sleep(1)
4935             else:
4936                 raise
4937
4938 def wps_run_pbc_fail(apdev, dev):
4939     hapd = wps_start_ap(apdev)
4940     wps_run_pbc_fail_ap(apdev, dev, hapd)
4941
4942 def test_ap_wps_pk_oom(dev, apdev):
4943     """WPS and public key OOM"""
4944     with alloc_fail(dev[0], 1, "wps_build_public_key"):
4945         wps_run_pbc_fail(apdev[0], dev[0])
4946
4947 def test_ap_wps_pk_oom_ap(dev, apdev):
4948     """WPS and public key OOM on AP"""
4949     hapd = wps_start_ap(apdev[0])
4950     with alloc_fail(hapd, 1, "wps_build_public_key"):
4951         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4952
4953 def test_ap_wps_encr_oom_ap(dev, apdev):
4954     """WPS and encrypted settings decryption OOM on AP"""
4955     hapd = wps_start_ap(apdev[0])
4956     pin = dev[0].wps_read_pin()
4957     hapd.request("WPS_PIN any " + pin)
4958     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4959     with alloc_fail(hapd, 1, "wps_decrypt_encr_settings"):
4960         dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " " + pin)
4961         ev = hapd.wait_event(["WPS-FAIL"], timeout=10)
4962         if ev is None:
4963             raise Exception("No WPS-FAIL reported")
4964         dev[0].request("WPS_CANCEL")
4965     dev[0].wait_disconnected()
4966
4967 def test_ap_wps_encr_no_random_ap(dev, apdev):
4968     """WPS and no random data available for encryption on AP"""
4969     hapd = wps_start_ap(apdev[0])
4970     with fail_test(hapd, 1, "os_get_random;wps_build_encr_settings"):
4971         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4972
4973 def test_ap_wps_e_hash_no_random_sta(dev, apdev):
4974     """WPS and no random data available for e-hash on STA"""
4975     with fail_test(dev[0], 1, "os_get_random;wps_build_e_hash"):
4976         wps_run_pbc_fail(apdev[0], dev[0])
4977
4978 def test_ap_wps_m1_no_random(dev, apdev):
4979     """WPS and no random for M1 on STA"""
4980     with fail_test(dev[0], 1, "os_get_random;wps_build_m1"):
4981         wps_run_pbc_fail(apdev[0], dev[0])
4982
4983 def test_ap_wps_m1_oom(dev, apdev):
4984     """WPS and OOM for M1 on STA"""
4985     with alloc_fail(dev[0], 1, "wps_build_m1"):
4986         wps_run_pbc_fail(apdev[0], dev[0])
4987
4988 def test_ap_wps_m3_oom(dev, apdev):
4989     """WPS and OOM for M3 on STA"""
4990     with alloc_fail(dev[0], 1, "wps_build_m3"):
4991         wps_run_pbc_fail(apdev[0], dev[0])
4992
4993 def test_ap_wps_m5_oom(dev, apdev):
4994     """WPS and OOM for M5 on STA"""
4995     hapd = wps_start_ap(apdev[0])
4996     hapd.request("WPS_PBC")
4997     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4998     for i in range(1, 3):
4999         with alloc_fail(dev[0], i, "wps_build_m5"):
5000             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
5001             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5002             if ev is None:
5003                 raise Exception("No EAP failure reported")
5004             dev[0].request("WPS_CANCEL")
5005             dev[0].wait_disconnected()
5006     dev[0].flush_scan_cache()
5007
5008 def test_ap_wps_m5_no_random(dev, apdev):
5009     """WPS and no random for M5 on STA"""
5010     with fail_test(dev[0], 1,
5011                    "os_get_random;wps_build_encr_settings;wps_build_m5"):
5012         wps_run_pbc_fail(apdev[0], dev[0])
5013
5014 def test_ap_wps_m7_oom(dev, apdev):
5015     """WPS and OOM for M7 on STA"""
5016     hapd = wps_start_ap(apdev[0])
5017     hapd.request("WPS_PBC")
5018     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5019     for i in range(1, 3):
5020         with alloc_fail(dev[0], i, "wps_build_m7"):
5021             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
5022             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5023             if ev is None:
5024                 raise Exception("No EAP failure reported")
5025             dev[0].request("WPS_CANCEL")
5026             dev[0].wait_disconnected()
5027     dev[0].flush_scan_cache()
5028
5029 def test_ap_wps_m7_no_random(dev, apdev):
5030     """WPS and no random for M7 on STA"""
5031     with fail_test(dev[0], 1,
5032                    "os_get_random;wps_build_encr_settings;wps_build_m7"):
5033         wps_run_pbc_fail(apdev[0], dev[0])
5034
5035 def test_ap_wps_wsc_done_oom(dev, apdev):
5036     """WPS and OOM for WSC_Done on STA"""
5037     with alloc_fail(dev[0], 1, "wps_build_wsc_done"):
5038         wps_run_pbc_fail(apdev[0], dev[0])
5039
5040 def test_ap_wps_random_psk_fail(dev, apdev):
5041     """WPS and no random for PSK on AP"""
5042     ssid = "test-wps"
5043     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
5044     appin = "12345670"
5045     try:
5046         os.remove(pskfile)
5047     except:
5048         pass
5049
5050     try:
5051         with open(pskfile, "w") as f:
5052             f.write("# WPA PSKs\n")
5053
5054         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5055                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
5056                    "rsn_pairwise": "CCMP", "ap_pin": appin,
5057                    "wpa_psk_file": pskfile }
5058         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
5059
5060         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
5061         with fail_test(hapd, 1, "os_get_random;wps_build_cred_network_key"):
5062             dev[0].request("WPS_REG " + apdev[0]['bssid'] + " " + appin)
5063             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5064             if ev is None:
5065                 raise Exception("No EAP failure reported")
5066             dev[0].request("WPS_CANCEL")
5067         dev[0].wait_disconnected()
5068
5069         with fail_test(hapd, 1, "os_get_random;wps_build_cred"):
5070             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5071
5072         with alloc_fail(hapd, 1, "wps_build_cred"):
5073             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5074
5075         with alloc_fail(hapd, 2, "wps_build_cred"):
5076             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5077     finally:
5078         os.remove(pskfile)
5079
5080 def wps_ext_eap_identity_req(dev, hapd, bssid):
5081     logger.debug("EAP-Identity/Request")
5082     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5083     if ev is None:
5084         raise Exception("Timeout on EAPOL-TX from hostapd")
5085     res = dev.request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
5086     if "OK" not in res:
5087         raise Exception("EAPOL_RX to wpa_supplicant failed")
5088
5089 def wps_ext_eap_identity_resp(hapd, dev, addr):
5090     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
5091     if ev is None:
5092         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
5093     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
5094     if "OK" not in res:
5095         raise Exception("EAPOL_RX to hostapd failed")
5096
5097 def wps_ext_eap_wsc(dst, src, src_addr, msg):
5098     logger.debug(msg)
5099     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5100     if ev is None:
5101         raise Exception("Timeout on EAPOL-TX")
5102     res = dst.request("EAPOL_RX " + src_addr + " " + ev.split(' ')[2])
5103     if "OK" not in res:
5104         raise Exception("EAPOL_RX failed")
5105
5106 def wps_start_ext(apdev, dev, pbc=False, pin=None):
5107     addr = dev.own_addr()
5108     bssid = apdev['bssid']
5109     ssid = "test-wps-conf"
5110     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5111                "wpa_passphrase": "12345678", "wpa": "2",
5112                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
5113     hapd = hostapd.add_ap(apdev['ifname'], params)
5114
5115     if pbc:
5116         hapd.request("WPS_PBC")
5117     else:
5118         if pin is None:
5119             pin = dev.wps_read_pin()
5120         hapd.request("WPS_PIN any " + pin)
5121     dev.scan_for_bss(bssid, freq="2412")
5122     hapd.request("SET ext_eapol_frame_io 1")
5123     dev.request("SET ext_eapol_frame_io 1")
5124
5125     if pbc:
5126         dev.request("WPS_PBC " + bssid)
5127     else:
5128         dev.request("WPS_PIN " + bssid + " " + pin)
5129     return addr,bssid,hapd
5130
5131 def wps_auth_corrupt(dst, src, addr):
5132     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5133     if ev is None:
5134         raise Exception("Timeout on EAPOL-TX")
5135     src.request("SET ext_eapol_frame_io 0")
5136     dst.request("SET ext_eapol_frame_io 0")
5137     msg = ev.split(' ')[2]
5138     if msg[-24:-16] != '10050008':
5139         raise Exception("Could not find Authenticator attribute")
5140     # Corrupt Authenticator value
5141     msg = msg[:-1] + '%x' % ((int(msg[-1], 16) + 1) % 16)
5142     res = dst.request("EAPOL_RX " + addr + " " + msg)
5143     if "OK" not in res:
5144         raise Exception("EAPOL_RX failed")
5145
5146 def wps_fail_finish(hapd, dev, fail_str):
5147     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5148     if ev is None:
5149         raise Exception("WPS-FAIL not indicated")
5150     if fail_str not in ev:
5151         raise Exception("Unexpected WPS-FAIL value: " + ev)
5152     dev.request("WPS_CANCEL")
5153     dev.wait_disconnected()
5154
5155 def wps_auth_corrupt_from_ap(dev, hapd, bssid, fail_str):
5156     wps_auth_corrupt(dev, hapd, bssid)
5157     wps_fail_finish(hapd, dev, fail_str)
5158
5159 def wps_auth_corrupt_to_ap(dev, hapd, addr, fail_str):
5160     wps_auth_corrupt(hapd, dev, addr)
5161     wps_fail_finish(hapd, dev, fail_str)
5162
5163 def test_ap_wps_authenticator_mismatch_m2(dev, apdev):
5164     """WPS and Authenticator attribute mismatch in M2"""
5165     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5166     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5167     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5168     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5169     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5170     logger.debug("M2")
5171     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=5")
5172
5173 def test_ap_wps_authenticator_mismatch_m3(dev, apdev):
5174     """WPS and Authenticator attribute mismatch in M3"""
5175     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5176     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5177     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5178     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5179     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5180     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5181     logger.debug("M3")
5182     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=7")
5183
5184 def test_ap_wps_authenticator_mismatch_m4(dev, apdev):
5185     """WPS and Authenticator attribute mismatch in M4"""
5186     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5187     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5188     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5189     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5190     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5191     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5192     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5193     logger.debug("M4")
5194     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=8")
5195
5196 def test_ap_wps_authenticator_mismatch_m5(dev, apdev):
5197     """WPS and Authenticator attribute mismatch in M5"""
5198     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5199     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5200     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5201     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5202     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5203     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5204     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5205     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5206     logger.debug("M5")
5207     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=9")
5208
5209 def test_ap_wps_authenticator_mismatch_m6(dev, apdev):
5210     """WPS and Authenticator attribute mismatch in M6"""
5211     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5212     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5213     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5214     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5215     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5216     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5217     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5218     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5219     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5220     logger.debug("M6")
5221     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=10")
5222
5223 def test_ap_wps_authenticator_mismatch_m7(dev, apdev):
5224     """WPS and Authenticator attribute mismatch in M7"""
5225     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5226     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5227     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5228     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5229     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5230     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5231     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5232     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5233     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5234     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5235     logger.debug("M7")
5236     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=11")
5237
5238 def test_ap_wps_authenticator_mismatch_m8(dev, apdev):
5239     """WPS and Authenticator attribute mismatch in M8"""
5240     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5241     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5242     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5243     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5244     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5245     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5246     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5247     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5248     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5249     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5250     wps_ext_eap_wsc(hapd, dev[0], addr, "M7")
5251     logger.debug("M8")
5252     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=12")
5253
5254 def test_ap_wps_authenticator_missing_m2(dev, apdev):
5255     """WPS and Authenticator attribute missing from M2"""
5256     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5257     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5258     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5259     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5260     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5261     logger.debug("M2")
5262     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5263     if ev is None:
5264         raise Exception("Timeout on EAPOL-TX")
5265     hapd.request("SET ext_eapol_frame_io 0")
5266     dev[0].request("SET ext_eapol_frame_io 0")
5267     msg = ev.split(' ')[2]
5268     if msg[-24:-16] != '10050008':
5269         raise Exception("Could not find Authenticator attribute")
5270     # Remove Authenticator value
5271     msg = msg[:-24]
5272     mlen = "%04x" % (int(msg[4:8], 16) - 12)
5273     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:]
5274     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5275     if "OK" not in res:
5276         raise Exception("EAPOL_RX failed")
5277     wps_fail_finish(hapd, dev[0], "msg=5")
5278
5279 def test_ap_wps_m2_dev_passwd_id_p2p(dev, apdev):
5280     """WPS and M2 with different Device Password ID (P2P)"""
5281     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5282     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5283     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5284     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5285     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5286     logger.debug("M2")
5287     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5288     if ev is None:
5289         raise Exception("Timeout on EAPOL-TX")
5290     hapd.request("SET ext_eapol_frame_io 0")
5291     dev[0].request("SET ext_eapol_frame_io 0")
5292     msg = ev.split(' ')[2]
5293     if msg[722:730] != '10120002':
5294         raise Exception("Could not find Device Password ID attribute")
5295     # Replace Device Password ID value. This will fail Authenticator check, but
5296     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5297     # log.
5298     msg = msg[0:730] + "0005" + msg[734:]
5299     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5300     if "OK" not in res:
5301         raise Exception("EAPOL_RX failed")
5302     wps_fail_finish(hapd, dev[0], "msg=5")
5303
5304 def test_ap_wps_m2_dev_passwd_id_change_pin_to_pbc(dev, apdev):
5305     """WPS and M2 with different Device Password ID (PIN to PBC)"""
5306     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5307     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5308     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5309     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5310     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5311     logger.debug("M2")
5312     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5313     if ev is None:
5314         raise Exception("Timeout on EAPOL-TX")
5315     hapd.request("SET ext_eapol_frame_io 0")
5316     dev[0].request("SET ext_eapol_frame_io 0")
5317     msg = ev.split(' ')[2]
5318     if msg[722:730] != '10120002':
5319         raise Exception("Could not find Device Password ID attribute")
5320     # Replace Device Password ID value (PIN --> PBC). This will be rejected.
5321     msg = msg[0:730] + "0004" + msg[734:]
5322     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5323     if "OK" not in res:
5324         raise Exception("EAPOL_RX failed")
5325     wps_fail_finish(hapd, dev[0], "msg=5")
5326
5327 def test_ap_wps_m2_dev_passwd_id_change_pbc_to_pin(dev, apdev):
5328     """WPS and M2 with different Device Password ID (PBC to PIN)"""
5329     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5330     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5331     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5332     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5333     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5334     logger.debug("M2")
5335     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5336     if ev is None:
5337         raise Exception("Timeout on EAPOL-TX")
5338     hapd.request("SET ext_eapol_frame_io 0")
5339     dev[0].request("SET ext_eapol_frame_io 0")
5340     msg = ev.split(' ')[2]
5341     if msg[722:730] != '10120002':
5342         raise Exception("Could not find Device Password ID attribute")
5343     # Replace Device Password ID value. This will fail Authenticator check, but
5344     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5345     # log.
5346     msg = msg[0:730] + "0000" + msg[734:]
5347     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5348     if "OK" not in res:
5349         raise Exception("EAPOL_RX failed")
5350     wps_fail_finish(hapd, dev[0], "msg=5")
5351     dev[0].flush_scan_cache()
5352
5353 def test_ap_wps_m2_missing_dev_passwd_id(dev, apdev):
5354     """WPS and M2 without Device Password ID"""
5355     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5356     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5357     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5358     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5359     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5360     logger.debug("M2")
5361     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5362     if ev is None:
5363         raise Exception("Timeout on EAPOL-TX")
5364     hapd.request("SET ext_eapol_frame_io 0")
5365     dev[0].request("SET ext_eapol_frame_io 0")
5366     msg = ev.split(' ')[2]
5367     if msg[722:730] != '10120002':
5368         raise Exception("Could not find Device Password ID attribute")
5369     # Remove Device Password ID value. This will fail Authenticator check, but
5370     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5371     # log.
5372     mlen = "%04x" % (int(msg[4:8], 16) - 6)
5373     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:722] + msg[734:]
5374     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5375     if "OK" not in res:
5376         raise Exception("EAPOL_RX failed")
5377     wps_fail_finish(hapd, dev[0], "msg=5")
5378
5379 def test_ap_wps_m2_missing_registrar_nonce(dev, apdev):
5380     """WPS and M2 without Registrar Nonce"""
5381     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5382     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5383     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5384     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5385     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5386     logger.debug("M2")
5387     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5388     if ev is None:
5389         raise Exception("Timeout on EAPOL-TX")
5390     hapd.request("SET ext_eapol_frame_io 0")
5391     dev[0].request("SET ext_eapol_frame_io 0")
5392     msg = ev.split(' ')[2]
5393     if msg[96:104] != '10390010':
5394         raise Exception("Could not find Registrar Nonce attribute")
5395     # Remove Registrar Nonce. This will fail Authenticator check, but
5396     # allows the code path in wps_process_registrar_nonce() to be checked from
5397     # the debug log.
5398     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5399     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:96] + msg[136:]
5400     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5401     if "OK" not in res:
5402         raise Exception("EAPOL_RX failed")
5403     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5404     if ev is None:
5405         raise Exception("Disconnect event not seen")
5406     dev[0].request("WPS_CANCEL")
5407     dev[0].flush_scan_cache()
5408
5409 def test_ap_wps_m2_missing_enrollee_nonce(dev, apdev):
5410     """WPS and M2 without Enrollee Nonce"""
5411     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5412     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5413     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5414     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5415     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5416     logger.debug("M2")
5417     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5418     if ev is None:
5419         raise Exception("Timeout on EAPOL-TX")
5420     hapd.request("SET ext_eapol_frame_io 0")
5421     dev[0].request("SET ext_eapol_frame_io 0")
5422     msg = ev.split(' ')[2]
5423     if msg[56:64] != '101a0010':
5424         raise Exception("Could not find enrollee Nonce attribute")
5425     # Remove Enrollee Nonce. This will fail Authenticator check, but
5426     # allows the code path in wps_process_enrollee_nonce() to be checked from
5427     # the debug log.
5428     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5429     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:56] + msg[96:]
5430     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5431     if "OK" not in res:
5432         raise Exception("EAPOL_RX failed")
5433     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5434     if ev is None:
5435         raise Exception("Disconnect event not seen")
5436     dev[0].request("WPS_CANCEL")
5437     dev[0].flush_scan_cache()
5438
5439 def test_ap_wps_m2_missing_uuid_r(dev, apdev):
5440     """WPS and M2 without UUID-R"""
5441     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5442     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5443     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5444     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5445     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5446     logger.debug("M2")
5447     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5448     if ev is None:
5449         raise Exception("Timeout on EAPOL-TX")
5450     hapd.request("SET ext_eapol_frame_io 0")
5451     dev[0].request("SET ext_eapol_frame_io 0")
5452     msg = ev.split(' ')[2]
5453     if msg[136:144] != '10480010':
5454         raise Exception("Could not find enrollee Nonce attribute")
5455     # Remove UUID-R. This will fail Authenticator check, but allows the code
5456     # path in wps_process_uuid_r() to be checked from the debug log.
5457     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5458     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:136] + msg[176:]
5459     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5460     if "OK" not in res:
5461         raise Exception("EAPOL_RX failed")
5462     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5463     if ev is None:
5464         raise Exception("Disconnect event not seen")
5465     dev[0].request("WPS_CANCEL")
5466     dev[0].flush_scan_cache()
5467
5468 def test_ap_wps_m2_invalid(dev, apdev):
5469     """WPS and M2 parsing failure"""
5470     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5471     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5472     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5473     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5474     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5475     logger.debug("M2")
5476     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5477     if ev is None:
5478         raise Exception("Timeout on EAPOL-TX")
5479     hapd.request("SET ext_eapol_frame_io 0")
5480     dev[0].request("SET ext_eapol_frame_io 0")
5481     msg = ev.split(' ')[2]
5482     if msg[136:144] != '10480010':
5483         raise Exception("Could not find enrollee Nonce attribute")
5484     # Remove UUID-R. This will fail Authenticator check, but allows the code
5485     # path in wps_process_uuid_r() to be checked from the debug log.
5486     mlen = "%04x" % (int(msg[4:8], 16) - 1)
5487     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:-2]
5488     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5489     if "OK" not in res:
5490         raise Exception("EAPOL_RX failed")
5491     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5492     if ev is None:
5493         raise Exception("Disconnect event not seen")
5494     dev[0].request("WPS_CANCEL")
5495     dev[0].flush_scan_cache()
5496
5497 def test_ap_wps_m2_missing_msg_type(dev, apdev):
5498     """WPS and M2 without Message Type"""
5499     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5500     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5501     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5502     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5503     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5504     logger.debug("M2")
5505     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5506     if ev is None:
5507         raise Exception("Timeout on EAPOL-TX")
5508     hapd.request("SET ext_eapol_frame_io 0")
5509     dev[0].request("SET ext_eapol_frame_io 0")
5510     msg = ev.split(' ')[2]
5511     if msg[46:54] != '10220001':
5512         raise Exception("Could not find Message Type attribute")
5513     # Remove Message Type. This will fail Authenticator check, but allows the
5514     # code path in wps_process_wsc_msg() to be checked from the debug log.
5515     mlen = "%04x" % (int(msg[4:8], 16) - 5)
5516     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:46] + msg[56:]
5517     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5518     if "OK" not in res:
5519         raise Exception("EAPOL_RX failed")
5520     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5521     if ev is None:
5522         raise Exception("Disconnect event not seen")
5523     dev[0].request("WPS_CANCEL")
5524     dev[0].flush_scan_cache()
5525
5526 def test_ap_wps_m2_unknown_msg_type(dev, apdev):
5527     """WPS and M2 but unknown Message Type"""
5528     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5529     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5530     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5531     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5532     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5533     logger.debug("M2")
5534     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5535     if ev is None:
5536         raise Exception("Timeout on EAPOL-TX")
5537     hapd.request("SET ext_eapol_frame_io 0")
5538     dev[0].request("SET ext_eapol_frame_io 0")
5539     msg = ev.split(' ')[2]
5540     if msg[46:54] != '10220001':
5541         raise Exception("Could not find Message Type attribute")
5542     # Replace Message Type value. This will be rejected.
5543     msg = msg[0:54] + "00" + msg[56:]
5544     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5545     if "OK" not in res:
5546         raise Exception("EAPOL_RX failed")
5547     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5548     if ev is None:
5549         raise Exception("Disconnect event not seen")
5550     dev[0].request("WPS_CANCEL")
5551     dev[0].flush_scan_cache()
5552
5553 def test_ap_wps_m2_unknown_opcode(dev, apdev):
5554     """WPS and M2 but unknown opcode"""
5555     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5556     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5557     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5558     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5559     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5560     logger.debug("M2")
5561     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5562     if ev is None:
5563         raise Exception("Timeout on EAPOL-TX")
5564     hapd.request("SET ext_eapol_frame_io 0")
5565     dev[0].request("SET ext_eapol_frame_io 0")
5566     msg = ev.split(' ')[2]
5567     # Replace opcode. This will be discarded in EAP-WSC processing.
5568     msg = msg[0:32] + "00" + msg[34:]
5569     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5570     if "OK" not in res:
5571         raise Exception("EAPOL_RX failed")
5572     dev[0].request("WPS_CANCEL")
5573     dev[0].wait_disconnected()
5574     dev[0].flush_scan_cache()
5575
5576 def test_ap_wps_m2_unknown_opcode2(dev, apdev):
5577     """WPS and M2 but unknown opcode (WSC_Start)"""
5578     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5579     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5580     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5581     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5582     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5583     logger.debug("M2")
5584     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5585     if ev is None:
5586         raise Exception("Timeout on EAPOL-TX")
5587     hapd.request("SET ext_eapol_frame_io 0")
5588     dev[0].request("SET ext_eapol_frame_io 0")
5589     msg = ev.split(' ')[2]
5590     # Replace opcode. This will be discarded in EAP-WSC processing.
5591     msg = msg[0:32] + "01" + msg[34:]
5592     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5593     if "OK" not in res:
5594         raise Exception("EAPOL_RX failed")
5595     dev[0].request("WPS_CANCEL")
5596     dev[0].wait_disconnected()
5597     dev[0].flush_scan_cache()
5598
5599 def test_ap_wps_m2_unknown_opcode3(dev, apdev):
5600     """WPS and M2 but unknown opcode (WSC_Done)"""
5601     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5602     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5603     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5604     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5605     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5606     logger.debug("M2")
5607     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5608     if ev is None:
5609         raise Exception("Timeout on EAPOL-TX")
5610     hapd.request("SET ext_eapol_frame_io 0")
5611     dev[0].request("SET ext_eapol_frame_io 0")
5612     msg = ev.split(' ')[2]
5613     # Replace opcode. This will be discarded in WPS Enrollee processing.
5614     msg = msg[0:32] + "05" + msg[34:]
5615     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5616     if "OK" not in res:
5617         raise Exception("EAPOL_RX failed")
5618     dev[0].request("WPS_CANCEL")
5619     dev[0].wait_disconnected()
5620     dev[0].flush_scan_cache()
5621
5622 def wps_m2_but_other(dev, apdev, title, msgtype):
5623     addr,bssid,hapd = wps_start_ext(apdev, dev)
5624     wps_ext_eap_identity_req(dev, hapd, bssid)
5625     wps_ext_eap_identity_resp(hapd, dev, addr)
5626     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5627     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5628     logger.debug(title)
5629     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5630     if ev is None:
5631         raise Exception("Timeout on EAPOL-TX")
5632     hapd.request("SET ext_eapol_frame_io 0")
5633     dev.request("SET ext_eapol_frame_io 0")
5634     msg = ev.split(' ')[2]
5635     if msg[46:54] != '10220001':
5636         raise Exception("Could not find Message Type attribute")
5637     # Replace Message Type value. This will be rejected.
5638     msg = msg[0:54] + msgtype + msg[56:]
5639     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5640     if "OK" not in res:
5641         raise Exception("EAPOL_RX failed")
5642     ev = dev.wait_event(["WPS-FAIL"], timeout=5)
5643     if ev is None:
5644         raise Exception("WPS-FAIL event not seen")
5645     dev.request("WPS_CANCEL")
5646     dev.wait_disconnected()
5647
5648 def wps_m4_but_other(dev, apdev, title, msgtype):
5649     addr,bssid,hapd = wps_start_ext(apdev, dev)
5650     wps_ext_eap_identity_req(dev, hapd, bssid)
5651     wps_ext_eap_identity_resp(hapd, dev, addr)
5652     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5653     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5654     wps_ext_eap_wsc(dev, hapd, bssid, "M2")
5655     wps_ext_eap_wsc(hapd, dev, addr, "M3")
5656     logger.debug(title)
5657     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5658     if ev is None:
5659         raise Exception("Timeout on EAPOL-TX")
5660     hapd.request("SET ext_eapol_frame_io 0")
5661     dev.request("SET ext_eapol_frame_io 0")
5662     msg = ev.split(' ')[2]
5663     if msg[46:54] != '10220001':
5664         raise Exception("Could not find Message Type attribute")
5665     # Replace Message Type value. This will be rejected.
5666     msg = msg[0:54] + msgtype + msg[56:]
5667     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5668     if "OK" not in res:
5669         raise Exception("EAPOL_RX failed")
5670     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5671     if ev is None:
5672         raise Exception("WPS-FAIL event not seen")
5673     dev.request("WPS_CANCEL")
5674     dev.wait_disconnected()
5675
5676 def test_ap_wps_m2_msg_type_m4(dev, apdev):
5677     """WPS and M2 but Message Type M4"""
5678     wps_m2_but_other(dev[0], apdev[0], "M2/M4", "08")
5679
5680 def test_ap_wps_m2_msg_type_m6(dev, apdev):
5681     """WPS and M2 but Message Type M6"""
5682     wps_m2_but_other(dev[0], apdev[0], "M2/M6", "0a")
5683
5684 def test_ap_wps_m2_msg_type_m8(dev, apdev):
5685     """WPS and M2 but Message Type M8"""
5686     wps_m2_but_other(dev[0], apdev[0], "M2/M8", "0c")
5687
5688 def test_ap_wps_m4_msg_type_m2(dev, apdev):
5689     """WPS and M4 but Message Type M2"""
5690     wps_m4_but_other(dev[0], apdev[0], "M4/M2", "05")
5691
5692 def test_ap_wps_m4_msg_type_m2d(dev, apdev):
5693     """WPS and M4 but Message Type M2D"""
5694     wps_m4_but_other(dev[0], apdev[0], "M4/M2D", "06")
5695
5696 def test_ap_wps_config_methods(dev, apdev):
5697     """WPS configuration method parsing"""
5698     ssid = "test-wps-conf"
5699     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5700                "wpa_passphrase": "12345678", "wpa": "2",
5701                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5702                "config_methods": "ethernet display ext_nfc_token int_nfc_token physical_display physical_push_button" }
5703     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
5704     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5705                "wpa_passphrase": "12345678", "wpa": "2",
5706                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5707                "config_methods": "display push_button" }
5708     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
5709
5710 def test_ap_wps_set_selected_registrar_proto(dev, apdev):
5711     """WPS UPnP SetSelectedRegistrar protocol testing"""
5712     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5713     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5714
5715     location = ssdp_get_location(ap_uuid)
5716     urls = upnp_get_urls(location)
5717     eventurl = urlparse.urlparse(urls['event_sub_url'])
5718     ctrlurl = urlparse.urlparse(urls['control_url'])
5719     url = urlparse.urlparse(location)
5720     conn = httplib.HTTPConnection(url.netloc)
5721
5722     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
5723         def handle(self):
5724             data = self.rfile.readline().strip()
5725             logger.debug(data)
5726             self.wfile.write(gen_wps_event())
5727
5728     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
5729     server.timeout = 1
5730
5731     headers = { "callback": '<http://127.0.0.1:12345/event>',
5732                 "NT": "upnp:event",
5733                 "timeout": "Second-1234" }
5734     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
5735     resp = conn.getresponse()
5736     if resp.status != 200:
5737         raise Exception("Unexpected HTTP response: %d" % resp.status)
5738     sid = resp.getheader("sid")
5739     logger.debug("Subscription SID " + sid)
5740     server.handle_request()
5741
5742     tests = [ (500, "10"),
5743               (200, "104a000110" + "1041000101" + "101200020000" +
5744                "105300023148" +
5745                "1049002c00372a0001200124111111111111222222222222333333333333444444444444555555555555666666666666" +
5746                "10480010362db47ba53a519188fb5458b986b2e4"),
5747               (200, "104a000110" + "1041000100" + "101200020000" +
5748                "105300020000"),
5749               (200, "104a000110" + "1041000100"),
5750               (200, "104a000110") ]
5751     for status,test in tests:
5752         tlvs = binascii.unhexlify(test)
5753         newmsg = base64.b64encode(tlvs)
5754         msg = '<?xml version="1.0"?>\n'
5755         msg += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
5756         msg += '<s:Body>'
5757         msg += '<u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">'
5758         msg += '<NewMessage>'
5759         msg += newmsg
5760         msg += "</NewMessage></u:SetSelectedRegistrar></s:Body></s:Envelope>"
5761         headers = { "Content-type": 'text/xml; charset="utf-8"' }
5762         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
5763         conn.request("POST", ctrlurl.path, msg, headers)
5764         resp = conn.getresponse()
5765         if resp.status != status:
5766             raise Exception("Unexpected HTTP response: %d (expected %d)" % (resp.status, status))
5767
5768 def test_ap_wps_adv_oom(dev, apdev):
5769     """WPS AP and advertisement OOM"""
5770     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5771     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5772
5773     with alloc_fail(hapd, 1, "=msearchreply_state_machine_start"):
5774         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5775                           no_recv=True)
5776         time.sleep(0.2)
5777
5778     with alloc_fail(hapd, 1, "eloop_register_timeout;msearchreply_state_machine_start"):
5779         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5780                           no_recv=True)
5781         time.sleep(0.2)
5782
5783     with alloc_fail(hapd, 1,
5784                     "next_advertisement;advertisement_state_machine_stop"):
5785         hapd.disable()
5786
5787     with alloc_fail(hapd, 1, "ssdp_listener_start"):
5788         if "FAIL" not in hapd.request("ENABLE"):
5789             raise Exception("ENABLE succeeded during OOM")
5790
5791 def test_wps_config_methods(dev):
5792     """WPS config method update"""
5793     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
5794     wpas.interface_add("wlan5")
5795     if "OK" not in wpas.request("SET config_methods display label"):
5796         raise Exception("Failed to set config_methods")
5797     if wpas.request("GET config_methods").strip() != "display label":
5798         raise Exception("config_methods were not updated")
5799     if "OK" not in wpas.request("SET config_methods "):
5800         raise Exception("Failed to clear config_methods")
5801     if wpas.request("GET config_methods").strip() != "":
5802         raise Exception("config_methods were not cleared")
5803
5804 WPS_VENDOR_ID_WFA = 14122
5805 WPS_VENDOR_TYPE = 1
5806
5807 # EAP-WSC Op-Code values
5808 WSC_Start = 0x01
5809 WSC_ACK = 0x02
5810 WSC_NACK = 0x03
5811 WSC_MSG = 0x04
5812 WSC_Done = 0x05
5813 WSC_FRAG_ACK = 0x06
5814
5815 ATTR_AP_CHANNEL = 0x1001
5816 ATTR_ASSOC_STATE = 0x1002
5817 ATTR_AUTH_TYPE = 0x1003
5818 ATTR_AUTH_TYPE_FLAGS = 0x1004
5819 ATTR_AUTHENTICATOR = 0x1005
5820 ATTR_CONFIG_METHODS = 0x1008
5821 ATTR_CONFIG_ERROR = 0x1009
5822 ATTR_CONFIRM_URL4 = 0x100a
5823 ATTR_CONFIRM_URL6 = 0x100b
5824 ATTR_CONN_TYPE = 0x100c
5825 ATTR_CONN_TYPE_FLAGS = 0x100d
5826 ATTR_CRED = 0x100e
5827 ATTR_ENCR_TYPE = 0x100f
5828 ATTR_ENCR_TYPE_FLAGS = 0x1010
5829 ATTR_DEV_NAME = 0x1011
5830 ATTR_DEV_PASSWORD_ID = 0x1012
5831 ATTR_E_HASH1 = 0x1014
5832 ATTR_E_HASH2 = 0x1015
5833 ATTR_E_SNONCE1 = 0x1016
5834 ATTR_E_SNONCE2 = 0x1017
5835 ATTR_ENCR_SETTINGS = 0x1018
5836 ATTR_ENROLLEE_NONCE = 0x101a
5837 ATTR_FEATURE_ID = 0x101b
5838 ATTR_IDENTITY = 0x101c
5839 ATTR_IDENTITY_PROOF = 0x101d
5840 ATTR_KEY_WRAP_AUTH = 0x101e
5841 ATTR_KEY_ID = 0x101f
5842 ATTR_MAC_ADDR = 0x1020
5843 ATTR_MANUFACTURER = 0x1021
5844 ATTR_MSG_TYPE = 0x1022
5845 ATTR_MODEL_NAME = 0x1023
5846 ATTR_MODEL_NUMBER = 0x1024
5847 ATTR_NETWORK_INDEX = 0x1026
5848 ATTR_NETWORK_KEY = 0x1027
5849 ATTR_NETWORK_KEY_INDEX = 0x1028
5850 ATTR_NEW_DEVICE_NAME = 0x1029
5851 ATTR_NEW_PASSWORD = 0x102a
5852 ATTR_OOB_DEVICE_PASSWORD = 0x102c
5853 ATTR_OS_VERSION = 0x102d
5854 ATTR_POWER_LEVEL = 0x102f
5855 ATTR_PSK_CURRENT = 0x1030
5856 ATTR_PSK_MAX = 0x1031
5857 ATTR_PUBLIC_KEY = 0x1032
5858 ATTR_RADIO_ENABLE = 0x1033
5859 ATTR_REBOOT = 0x1034
5860 ATTR_REGISTRAR_CURRENT = 0x1035
5861 ATTR_REGISTRAR_ESTABLISHED = 0x1036
5862 ATTR_REGISTRAR_LIST = 0x1037
5863 ATTR_REGISTRAR_MAX = 0x1038
5864 ATTR_REGISTRAR_NONCE = 0x1039
5865 ATTR_REQUEST_TYPE = 0x103a
5866 ATTR_RESPONSE_TYPE = 0x103b
5867 ATTR_RF_BANDS = 0x103c
5868 ATTR_R_HASH1 = 0x103d
5869 ATTR_R_HASH2 = 0x103e
5870 ATTR_R_SNONCE1 = 0x103f
5871 ATTR_R_SNONCE2 = 0x1040
5872 ATTR_SELECTED_REGISTRAR = 0x1041
5873 ATTR_SERIAL_NUMBER = 0x1042
5874 ATTR_WPS_STATE = 0x1044
5875 ATTR_SSID = 0x1045
5876 ATTR_TOTAL_NETWORKS = 0x1046
5877 ATTR_UUID_E = 0x1047
5878 ATTR_UUID_R = 0x1048
5879 ATTR_VENDOR_EXT = 0x1049
5880 ATTR_VERSION = 0x104a
5881 ATTR_X509_CERT_REQ = 0x104b
5882 ATTR_X509_CERT = 0x104c
5883 ATTR_EAP_IDENTITY = 0x104d
5884 ATTR_MSG_COUNTER = 0x104e
5885 ATTR_PUBKEY_HASH = 0x104f
5886 ATTR_REKEY_KEY = 0x1050
5887 ATTR_KEY_LIFETIME = 0x1051
5888 ATTR_PERMITTED_CFG_METHODS = 0x1052
5889 ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053
5890 ATTR_PRIMARY_DEV_TYPE = 0x1054
5891 ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055
5892 ATTR_PORTABLE_DEV = 0x1056
5893 ATTR_AP_SETUP_LOCKED = 0x1057
5894 ATTR_APPLICATION_EXT = 0x1058
5895 ATTR_EAP_TYPE = 0x1059
5896 ATTR_IV = 0x1060
5897 ATTR_KEY_PROVIDED_AUTO = 0x1061
5898 ATTR_802_1X_ENABLED = 0x1062
5899 ATTR_APPSESSIONKEY = 0x1063
5900 ATTR_WEPTRANSMITKEY = 0x1064
5901 ATTR_REQUESTED_DEV_TYPE = 0x106a
5902
5903 # Message Type
5904 WPS_Beacon = 0x01
5905 WPS_ProbeRequest = 0x02
5906 WPS_ProbeResponse = 0x03
5907 WPS_M1 = 0x04
5908 WPS_M2 = 0x05
5909 WPS_M2D = 0x06
5910 WPS_M3 = 0x07
5911 WPS_M4 = 0x08
5912 WPS_M5 = 0x09
5913 WPS_M6 = 0x0a
5914 WPS_M7 = 0x0b
5915 WPS_M8 = 0x0c
5916 WPS_WSC_ACK = 0x0d
5917 WPS_WSC_NACK = 0x0e
5918 WPS_WSC_DONE = 0x0f
5919
5920 def get_wsc_msg(dev):
5921     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
5922     if ev is None:
5923         raise Exception("Timeout on EAPOL-TX")
5924     data = binascii.unhexlify(ev.split(' ')[2])
5925     msg = {}
5926
5927     # Parse EAPOL header
5928     if len(data) < 4:
5929         raise Exception("No room for EAPOL header")
5930     version,type,length = struct.unpack('>BBH', data[0:4])
5931     msg['eapol_version'] = version
5932     msg['eapol_type'] = type
5933     msg['eapol_length'] = length
5934     data = data[4:]
5935     if length != len(data):
5936         raise Exception("EAPOL header length mismatch (%d != %d)" % (length, len(data)))
5937     if type != 0:
5938         raise Exception("Unexpected EAPOL header type: %d" % type)
5939
5940     # Parse EAP header
5941     if len(data) < 4:
5942         raise Exception("No room for EAP header")
5943     code,identifier,length = struct.unpack('>BBH', data[0:4])
5944     msg['eap_code'] = code
5945     msg['eap_identifier'] = identifier
5946     msg['eap_length'] = length
5947     data = data[4:]
5948     if msg['eapol_length'] != msg['eap_length']:
5949         raise Exception("EAP header length mismatch (%d != %d)" % (msg['eapol_length'], length))
5950
5951     # Parse EAP expanded header
5952     if len(data) < 1:
5953         raise Exception("No EAP type included")
5954     msg['eap_type'], = struct.unpack('B', data[0])
5955     data = data[1:]
5956
5957     if msg['eap_type'] == 254:
5958         if len(data) < 3 + 4:
5959             raise Exception("Truncated EAP expanded header")
5960         msg['eap_vendor_id'], msg['eap_vendor_type'] = struct.unpack('>LL', '\0' + data[0:7])
5961         data = data[7:]
5962     else:
5963         raise Exception("Unexpected EAP type")
5964
5965     if msg['eap_vendor_id'] != WPS_VENDOR_ID_WFA:
5966         raise Exception("Unexpected Vendor-Id")
5967     if msg['eap_vendor_type'] != WPS_VENDOR_TYPE:
5968         raise Exception("Unexpected Vendor-Type")
5969
5970     # Parse EAP-WSC header
5971     if len(data) < 2:
5972         raise Exception("Truncated EAP-WSC header")
5973     msg['wsc_opcode'], msg['wsc_flags'] = struct.unpack('BB', data[0:2])
5974     data = data[2:]
5975
5976     # Parse WSC attributes
5977     msg['raw_attrs'] = data
5978     attrs = {}
5979     while len(data) > 0:
5980         if len(data) < 4:
5981             raise Exception("Truncated attribute header")
5982         attr,length = struct.unpack('>HH', data[0:4])
5983         data = data[4:]
5984         if length > len(data):
5985             raise Exception("Truncated attribute 0x%04x" % attr)
5986         attrs[attr] = data[0:length]
5987         data = data[length:]
5988     msg['wsc_attrs'] = attrs
5989
5990     if ATTR_MSG_TYPE in attrs:
5991         msg['wsc_msg_type'], = struct.unpack('B', attrs[ATTR_MSG_TYPE])
5992
5993     return msg
5994
5995 def recv_wsc_msg(dev, opcode, msg_type):
5996     msg = get_wsc_msg(dev)
5997     if msg['wsc_opcode'] != opcode or msg['wsc_msg_type'] != msg_type:
5998         raise Exception("Unexpected Op-Code/MsgType")
5999     return msg, msg['wsc_attrs'], msg['raw_attrs']
6000
6001 def build_wsc_attr(attr, payload):
6002     return struct.pack('>HH', attr, len(payload)) + payload
6003
6004 def build_attr_msg_type(msg_type):
6005     return build_wsc_attr(ATTR_MSG_TYPE, struct.pack('B', msg_type))
6006
6007 def build_eap_wsc(eap_code, eap_id, payload, opcode=WSC_MSG):
6008     length = 4 + 8 + 2 + len(payload)
6009     # EAPOL header
6010     msg = struct.pack('>BBH', 2, 0, length)
6011     # EAP header
6012     msg += struct.pack('>BBH', eap_code, eap_id, length)
6013     # EAP expanded header for EAP-WSC
6014     msg += struct.pack('B', 254)
6015     msg += struct.pack('>L', WPS_VENDOR_ID_WFA)[1:4]
6016     msg += struct.pack('>L', WPS_VENDOR_TYPE)
6017     # EAP-WSC header
6018     msg += struct.pack('BB', opcode, 0)
6019     # WSC attributes
6020     msg += payload
6021     return msg
6022
6023 def build_eap_success(eap_id):
6024     length = 4
6025     # EAPOL header
6026     msg = struct.pack('>BBH', 2, 0, length)
6027     # EAP header
6028     msg += struct.pack('>BBH', 3, eap_id, length)
6029     return msg
6030
6031 def build_eap_failure(eap_id):
6032     length = 4
6033     # EAPOL header
6034     msg = struct.pack('>BBH', 2, 0, length)
6035     # EAP header
6036     msg += struct.pack('>BBH', 4, eap_id, length)
6037     return msg
6038
6039 def send_wsc_msg(dev, src, msg):
6040     res = dev.request("EAPOL_RX " + src + " " + binascii.hexlify(msg))
6041     if "OK" not in res:
6042         raise Exception("EAPOL_RX failed")
6043
6044 group_5_prime = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF
6045 group_5_generator = 2
6046
6047 def wsc_kdf(key, label, bits):
6048     result = ''
6049     i = 1
6050     while len(result) * 8 < bits:
6051         data = struct.pack('>L', i) + label + struct.pack('>L', bits)
6052         m = hmac.new(key, data, hashlib.sha256)
6053         result += m.digest()
6054         i += 1
6055     return result[0:bits / 8]
6056
6057 def wsc_keys(kdk):
6058     keys = wsc_kdf(kdk, "Wi-Fi Easy and Secure Key Derivation", 640)
6059     authkey = keys[0:32]
6060     keywrapkey = keys[32:48]
6061     emsk = keys[48:80]
6062     return authkey,keywrapkey,emsk
6063
6064 def wsc_dev_pw_half_psk(authkey, dev_pw):
6065     m = hmac.new(authkey, dev_pw, hashlib.sha256)
6066     return m.digest()[0:16]
6067
6068 def wsc_dev_pw_psk(authkey, dev_pw):
6069     dev_pw_1 = dev_pw[0:len(dev_pw) / 2]
6070     dev_pw_2 = dev_pw[len(dev_pw) / 2:]
6071     psk1 = wsc_dev_pw_half_psk(authkey, dev_pw_1)
6072     psk2 = wsc_dev_pw_half_psk(authkey, dev_pw_2)
6073     return psk1,psk2
6074
6075 def build_attr_authenticator(authkey, prev_msg, curr_msg):
6076     m = hmac.new(authkey, prev_msg + curr_msg, hashlib.sha256)
6077     auth = m.digest()[0:8]
6078     return build_wsc_attr(ATTR_AUTHENTICATOR, auth)
6079
6080 def build_attr_encr_settings(authkey, keywrapkey, data):
6081     m = hmac.new(authkey, data, hashlib.sha256)
6082     kwa = m.digest()[0:8]
6083     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6084     iv = 16*'\x99'
6085     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6086     pad_len = 16 - len(data) % 16
6087     ps = pad_len * struct.pack('B', pad_len)
6088     data += ps
6089     wrapped = aes.encrypt(data)
6090     return build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6091
6092 def decrypt_attr_encr_settings(authkey, keywrapkey, data):
6093     if len(data) < 32 or len(data) % 16 != 0:
6094         raise Exception("Unexpected Encrypted Settings length: %d" % len(data))
6095     iv = data[0:16]
6096     encr = data[16:]
6097     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6098     decrypted = aes.decrypt(encr)
6099     pad_len, = struct.unpack('B', decrypted[-1])
6100     if pad_len > len(decrypted):
6101         raise Exception("Invalid padding in Encrypted Settings")
6102     for i in range(-pad_len, -1):
6103         if decrypted[i] != decrypted[-1]:
6104             raise Exception("Invalid PS value in Encrypted Settings")
6105     
6106     decrypted = decrypted[0:len(decrypted) - pad_len]
6107     if len(decrypted) < 12:
6108         raise Exception("Truncated Encrypted Settings plaintext")
6109     kwa = decrypted[-12:]
6110     attr,length = struct.unpack(">HH", kwa[0:4])
6111     if attr != ATTR_KEY_WRAP_AUTH or length != 8:
6112         raise Exception("Invalid KWA header")
6113     kwa = kwa[4:]
6114     decrypted = decrypted[0:len(decrypted) - 12]
6115
6116     m = hmac.new(authkey, decrypted, hashlib.sha256)
6117     calc_kwa = m.digest()[0:8]
6118     if kwa != calc_kwa:
6119         raise Exception("KWA mismatch")
6120
6121     return decrypted
6122
6123 def zeropad_str(val, pad_len):
6124     while len(val) < pad_len * 2:
6125         val = '0' + val
6126     return val
6127
6128 def wsc_dh_init():
6129     # For now, use a hardcoded private key. In theory, this is supposed to be
6130     # randomly selected.
6131     own_private = 0x123456789
6132     own_public = pow(group_5_generator, own_private, group_5_prime)
6133     pk = binascii.unhexlify(zeropad_str(format(own_public, '02x'), 192))
6134     return own_private, pk
6135
6136 def wsc_dh_kdf(peer_pk, own_private, mac_addr, e_nonce, r_nonce):
6137     peer_public = long(binascii.hexlify(peer_pk), 16)
6138     if peer_public < 2 or peer_public >= group_5_prime:
6139         raise Exception("Invalid peer public key")
6140     if pow(peer_public, (group_5_prime - 1) / 2, group_5_prime) != 1:
6141         raise Exception("Unexpected Legendre symbol for peer public key")
6142
6143     shared_secret = pow(peer_public, own_private, group_5_prime)
6144     ss = zeropad_str(format(shared_secret, "02x"), 192)
6145     logger.debug("DH shared secret: " + ss)
6146
6147     dhkey = hashlib.sha256(binascii.unhexlify(ss)).digest()
6148     logger.debug("DHKey: " + binascii.hexlify(dhkey))
6149
6150     m = hmac.new(dhkey, e_nonce + mac_addr + r_nonce, hashlib.sha256)
6151     kdk = m.digest()
6152     logger.debug("KDK: " + binascii.hexlify(kdk))
6153     authkey,keywrapkey,emsk = wsc_keys(kdk)
6154     logger.debug("AuthKey: " + binascii.hexlify(authkey))
6155     logger.debug("KeyWrapKey: " + binascii.hexlify(keywrapkey))
6156     logger.debug("EMSK: " + binascii.hexlify(emsk))
6157     return authkey,keywrapkey
6158
6159 def wsc_dev_pw_hash(authkey, dev_pw, e_pk, r_pk):
6160     psk1,psk2 = wsc_dev_pw_psk(authkey, dev_pw)
6161     logger.debug("PSK1: " + binascii.hexlify(psk1))
6162     logger.debug("PSK2: " + binascii.hexlify(psk2))
6163
6164     # Note: Secret values are supposed to be random, but hardcoded values are
6165     # fine for testing.
6166     s1 = 16*'\x77'
6167     m = hmac.new(authkey, s1 + psk1 + e_pk + r_pk, hashlib.sha256)
6168     hash1 = m.digest()
6169     logger.debug("Hash1: " + binascii.hexlify(hash1))
6170
6171     s2 = 16*'\x88'
6172     m = hmac.new(authkey, s2 + psk2 + e_pk + r_pk, hashlib.sha256)
6173     hash2 = m.digest()
6174     logger.debug("Hash2: " + binascii.hexlify(hash2))
6175     return s1,s2,hash1,hash2
6176
6177 def build_m1(eap_id, uuid_e, mac_addr, e_nonce, e_pk,
6178              manufacturer='', model_name='', config_methods='\x00\x00'):
6179     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6180     attrs += build_attr_msg_type(WPS_M1)
6181     attrs += build_wsc_attr(ATTR_UUID_E, uuid_e)
6182     attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6183     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6184     attrs += build_wsc_attr(ATTR_PUBLIC_KEY, e_pk)
6185     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6186     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6187     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6188     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, config_methods)
6189     attrs += build_wsc_attr(ATTR_WPS_STATE, '\x00')
6190     attrs += build_wsc_attr(ATTR_MANUFACTURER, manufacturer)
6191     attrs += build_wsc_attr(ATTR_MODEL_NAME, model_name)
6192     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6193     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6194     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6195     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6196     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6197     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6198     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, '\x00\x00')
6199     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6200     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6201     m1 = build_eap_wsc(2, eap_id, attrs)
6202     return m1, attrs
6203
6204 def build_m2(authkey, m1, eap_id, e_nonce, r_nonce, uuid_r, r_pk,
6205              dev_pw_id='\x00\x00', eap_code=1):
6206     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6207     attrs += build_attr_msg_type(WPS_M2)
6208     if e_nonce:
6209         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6210     if r_nonce:
6211         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6212     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6213     if r_pk:
6214         attrs += build_wsc_attr(ATTR_PUBLIC_KEY, r_pk)
6215     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6216     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6217     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6218     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6219     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6220     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6221     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6222     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6223     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6224     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6225     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6226     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6227     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6228     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6229     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6230     attrs += build_attr_authenticator(authkey, m1, attrs)
6231     m2 = build_eap_wsc(eap_code, eap_id, attrs)
6232     return m2, attrs
6233
6234 def build_m2d(m1, eap_id, e_nonce, r_nonce, uuid_r, dev_pw_id=None, eap_code=1):
6235     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6236     attrs += build_attr_msg_type(WPS_M2D)
6237     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6238     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6239     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6240     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6241     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6242     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6243     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6244     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6245     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6246     #attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6247     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6248     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6249     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6250     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6251     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6252     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6253     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6254     if dev_pw_id:
6255         attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6256     m2d = build_eap_wsc(eap_code, eap_id, attrs)
6257     return m2d, attrs
6258
6259 def build_ack(eap_id, e_nonce, r_nonce, msg_type=WPS_WSC_ACK, eap_code=1):
6260     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6261     if msg_type is not None:
6262         attrs += build_attr_msg_type(msg_type)
6263     if e_nonce:
6264         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6265     if r_nonce:
6266         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6267     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_ACK)
6268     return msg, attrs
6269
6270 def build_nack(eap_id, e_nonce, r_nonce, config_error='\x00\x00',
6271                msg_type=WPS_WSC_NACK, eap_code=1):
6272     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6273     if msg_type is not None:
6274         attrs += build_attr_msg_type(msg_type)
6275     if e_nonce:
6276         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6277     if r_nonce:
6278         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6279     if config_error:
6280         attrs += build_wsc_attr(ATTR_CONFIG_ERROR, config_error)
6281     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_NACK)
6282     return msg, attrs
6283
6284 def test_wps_ext(dev, apdev):
6285     """WPS against external implementation"""
6286     pin = "12345670"
6287     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6288     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6289     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6290
6291     logger.debug("Receive WSC/Start from AP")
6292     msg = get_wsc_msg(hapd)
6293     if msg['wsc_opcode'] != WSC_Start:
6294         raise Exception("Unexpected Op-Code for WSC/Start")
6295     wsc_start_id = msg['eap_identifier']
6296
6297     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6298     uuid_e = 16*'\x11'
6299     e_nonce = 16*'\x22'
6300     own_private, e_pk = wsc_dh_init()
6301
6302     logger.debug("Send M1 to AP")
6303     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
6304                                 e_nonce, e_pk)
6305     send_wsc_msg(hapd, addr, m1)
6306
6307     logger.debug("Receive M2 from AP")
6308     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
6309
6310     authkey,keywrapkey = wsc_dh_kdf(m2_attrs[ATTR_PUBLIC_KEY], own_private,
6311                                     mac_addr, e_nonce,
6312                                     m2_attrs[ATTR_REGISTRAR_NONCE])
6313     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk,
6314                                                 m2_attrs[ATTR_PUBLIC_KEY])
6315
6316     logger.debug("Send M3 to AP")
6317     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6318     attrs += build_attr_msg_type(WPS_M3)
6319     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6320                             m2_attrs[ATTR_REGISTRAR_NONCE])
6321     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
6322     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
6323     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
6324     raw_m3_attrs = attrs
6325     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6326     send_wsc_msg(hapd, addr, m3)
6327
6328     logger.debug("Receive M4 from AP")
6329     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
6330
6331     logger.debug("Send M5 to AP")
6332     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6333     attrs += build_attr_msg_type(WPS_M5)
6334     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6335                             m2_attrs[ATTR_REGISTRAR_NONCE])
6336     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
6337     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6338     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
6339     raw_m5_attrs = attrs
6340     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6341     send_wsc_msg(hapd, addr, m5)
6342
6343     logger.debug("Receive M6 from AP")
6344     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
6345
6346     logger.debug("Send M7 to AP")
6347     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6348     attrs += build_attr_msg_type(WPS_M7)
6349     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6350                             m2_attrs[ATTR_REGISTRAR_NONCE])
6351     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
6352     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6353     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
6354     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6355     raw_m7_attrs = attrs
6356     send_wsc_msg(hapd, addr, m7)
6357
6358     logger.debug("Receive M8 from AP")
6359     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
6360     m8_cred = decrypt_attr_encr_settings(authkey, keywrapkey,
6361                                          m8_attrs[ATTR_ENCR_SETTINGS])
6362     logger.debug("M8 Credential: " + binascii.hexlify(m8_cred))
6363
6364     logger.debug("Prepare WSC_Done")
6365     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6366     attrs += build_attr_msg_type(WPS_WSC_DONE)
6367     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6368     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6369                             m2_attrs[ATTR_REGISTRAR_NONCE])
6370     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
6371     # Do not send WSC_Done yet to allow exchangw with STA complete before the
6372     # AP disconnects.
6373
6374     uuid_r = 16*'\x33'
6375     r_nonce = 16*'\x44'
6376
6377     eap_id = wsc_start_id
6378     logger.debug("Send WSC/Start to STA")
6379     wsc_start = build_eap_wsc(1, eap_id, "", opcode=WSC_Start)
6380     send_wsc_msg(dev[0], bssid, wsc_start)
6381     eap_id = (eap_id + 1) % 256
6382
6383     logger.debug("Receive M1 from STA")
6384     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6385
6386     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6387                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6388                                     r_nonce)
6389     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6390                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6391
6392     logger.debug("Send M2 to STA")
6393     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6394                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6395                                 r_nonce, uuid_r, e_pk)
6396     send_wsc_msg(dev[0], bssid, m2)
6397     eap_id = (eap_id + 1) % 256
6398
6399     logger.debug("Receive M3 from STA")
6400     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6401
6402     logger.debug("Send M4 to STA")
6403     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6404     attrs += build_attr_msg_type(WPS_M4)
6405     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6406     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6407     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6408     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6409     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6410     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6411     raw_m4_attrs = attrs
6412     m4 = build_eap_wsc(1, eap_id, attrs)
6413     send_wsc_msg(dev[0], bssid, m4)
6414     eap_id = (eap_id + 1) % 256
6415
6416     logger.debug("Receive M5 from STA")
6417     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6418
6419     logger.debug("Send M6 to STA")
6420     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6421     attrs += build_attr_msg_type(WPS_M6)
6422     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6423                             m1_attrs[ATTR_ENROLLEE_NONCE])
6424     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6425     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6426     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6427     raw_m6_attrs = attrs
6428     m6 = build_eap_wsc(1, eap_id, attrs)
6429     send_wsc_msg(dev[0], bssid, m6)
6430     eap_id = (eap_id + 1) % 256
6431
6432     logger.debug("Receive M7 from STA")
6433     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6434
6435     logger.debug("Send M8 to STA")
6436     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6437     attrs += build_attr_msg_type(WPS_M8)
6438     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6439                             m1_attrs[ATTR_ENROLLEE_NONCE])
6440     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6441     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6442     raw_m8_attrs = attrs
6443     m8 = build_eap_wsc(1, eap_id, attrs)
6444     send_wsc_msg(dev[0], bssid, m8)
6445     eap_id = (eap_id + 1) % 256
6446
6447     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=5)
6448     if ev is None:
6449         raise Exception("wpa_supplicant did not report credential")
6450
6451     logger.debug("Receive WSC_Done from STA")
6452     msg = get_wsc_msg(dev[0])
6453     if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6454         raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6455
6456     logger.debug("Send WSC_Done to AP")
6457     hapd.request("SET ext_eapol_frame_io 0")
6458     dev[0].request("SET ext_eapol_frame_io 0")
6459     send_wsc_msg(hapd, addr, wsc_done)
6460
6461     ev = hapd.wait_event(["WPS-REG-SUCCESS"], timeout=5)
6462     if ev is None:
6463         raise Exception("hostapd did not report WPS success")
6464
6465     dev[0].wait_connected()
6466
6467 def wps_start_kwa(dev, apdev):
6468     pin = "12345670"
6469     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6470     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6471     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6472     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6473
6474     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6475     uuid_r = 16*'\x33'
6476     r_nonce = 16*'\x44'
6477     own_private, e_pk = wsc_dh_init()
6478
6479     logger.debug("Receive M1 from STA")
6480     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6481     eap_id = (msg['eap_identifier'] + 1) % 256
6482
6483     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6484                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6485                                     r_nonce)
6486     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6487                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6488
6489     logger.debug("Send M2 to STA")
6490     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6491                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6492                                 r_nonce, uuid_r, e_pk)
6493     send_wsc_msg(dev[0], bssid, m2)
6494     eap_id = (eap_id + 1) % 256
6495
6496     logger.debug("Receive M3 from STA")
6497     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6498
6499     logger.debug("Send M4 to STA")
6500     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6501     attrs += build_attr_msg_type(WPS_M4)
6502     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6503     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6504     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6505
6506     return r_s1, keywrapkey, authkey, raw_m3_attrs, eap_id, bssid, attrs
6507
6508 def wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id):
6509     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6510     m4 = build_eap_wsc(1, eap_id, attrs)
6511     send_wsc_msg(dev[0], bssid, m4)
6512     eap_id = (eap_id + 1) % 256
6513
6514     logger.debug("Receive M5 from STA")
6515     msg = get_wsc_msg(dev[0])
6516     if msg['wsc_opcode'] != WSC_NACK:
6517         raise Exception("Unexpected message - expected WSC_Nack")
6518
6519     dev[0].request("WPS_CANCEL")
6520     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6521     dev[0].wait_disconnected()
6522
6523 def test_wps_ext_kwa_proto_no_kwa(dev, apdev):
6524     """WPS and KWA error: No KWA attribute"""
6525     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6526     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6527     # Encrypted Settings without KWA
6528     iv = 16*'\x99'
6529     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6530     pad_len = 16 - len(data) % 16
6531     ps = pad_len * struct.pack('B', pad_len)
6532     data += ps
6533     wrapped = aes.encrypt(data)
6534     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6535     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6536
6537 def test_wps_ext_kwa_proto_data_after_kwa(dev, apdev):
6538     """WPS and KWA error: Data after KWA"""
6539     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6540     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6541     # Encrypted Settings and data after KWA
6542     m = hmac.new(authkey, data, hashlib.sha256)
6543     kwa = m.digest()[0:8]
6544     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6545     data += build_wsc_attr(ATTR_VENDOR_EXT, "1234567890")
6546     iv = 16*'\x99'
6547     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6548     pad_len = 16 - len(data) % 16
6549     ps = pad_len * struct.pack('B', pad_len)
6550     data += ps
6551     wrapped = aes.encrypt(data)
6552     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6553     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6554
6555 def test_wps_ext_kwa_proto_kwa_mismatch(dev, apdev):
6556     """WPS and KWA error: KWA mismatch"""
6557     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6558     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6559     # Encrypted Settings and KWA with incorrect value
6560     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, 8*'\x00')
6561     iv = 16*'\x99'
6562     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6563     pad_len = 16 - len(data) % 16
6564     ps = pad_len * struct.pack('B', pad_len)
6565     data += ps
6566     wrapped = aes.encrypt(data)
6567     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6568     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6569
6570 def wps_run_cred_proto(dev, apdev, m8_cred, connect=False, no_connect=False):
6571     pin = "12345670"
6572     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6573     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6574     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6575     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6576
6577     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6578     uuid_r = 16*'\x33'
6579     r_nonce = 16*'\x44'
6580     own_private, e_pk = wsc_dh_init()
6581
6582     logger.debug("Receive M1 from STA")
6583     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6584     eap_id = (msg['eap_identifier'] + 1) % 256
6585
6586     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6587                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6588                                     r_nonce)
6589     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6590                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6591
6592     logger.debug("Send M2 to STA")
6593     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6594                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6595                                 r_nonce, uuid_r, e_pk)
6596     send_wsc_msg(dev[0], bssid, m2)
6597     eap_id = (eap_id + 1) % 256
6598
6599     logger.debug("Receive M3 from STA")
6600     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6601
6602     logger.debug("Send M4 to STA")
6603     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6604     attrs += build_attr_msg_type(WPS_M4)
6605     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6606     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6607     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6608     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6609     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6610     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6611     raw_m4_attrs = attrs
6612     m4 = build_eap_wsc(1, eap_id, attrs)
6613     send_wsc_msg(dev[0], bssid, m4)
6614     eap_id = (eap_id + 1) % 256
6615
6616     logger.debug("Receive M5 from STA")
6617     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6618
6619     logger.debug("Send M6 to STA")
6620     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6621     attrs += build_attr_msg_type(WPS_M6)
6622     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6623                             m1_attrs[ATTR_ENROLLEE_NONCE])
6624     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6625     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6626     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6627     raw_m6_attrs = attrs
6628     m6 = build_eap_wsc(1, eap_id, attrs)
6629     send_wsc_msg(dev[0], bssid, m6)
6630     eap_id = (eap_id + 1) % 256
6631
6632     logger.debug("Receive M7 from STA")
6633     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6634
6635     logger.debug("Send M8 to STA")
6636     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6637     attrs += build_attr_msg_type(WPS_M8)
6638     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6639                             m1_attrs[ATTR_ENROLLEE_NONCE])
6640     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6641     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6642     raw_m8_attrs = attrs
6643     m8 = build_eap_wsc(1, eap_id, attrs)
6644     send_wsc_msg(dev[0], bssid, m8)
6645     eap_id = (eap_id + 1) % 256
6646
6647     if no_connect:
6648         logger.debug("Receive WSC_Done from STA")
6649         msg = get_wsc_msg(dev[0])
6650         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6651             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6652
6653         hapd.request("SET ext_eapol_frame_io 0")
6654         dev[0].request("SET ext_eapol_frame_io 0")
6655
6656         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6657
6658         dev[0].wait_disconnected()
6659         dev[0].request("REMOVE_NETWORK all")
6660     elif connect:
6661         logger.debug("Receive WSC_Done from STA")
6662         msg = get_wsc_msg(dev[0])
6663         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6664             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6665
6666         hapd.request("SET ext_eapol_frame_io 0")
6667         dev[0].request("SET ext_eapol_frame_io 0")
6668
6669         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6670
6671         dev[0].wait_connected()
6672     else:
6673         # Verify STA NACK's the credential
6674         msg = get_wsc_msg(dev[0])
6675         if msg['wsc_opcode'] != WSC_NACK:
6676             raise Exception("Unexpected message - expected WSC_Nack")
6677         dev[0].request("WPS_CANCEL")
6678         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6679         dev[0].wait_disconnected()
6680
6681 def build_cred(nw_idx='\x01', ssid='test-wps-conf', auth_type='\x00\x20',
6682                encr_type='\x00\x08', nw_key="12345678",
6683                mac_addr='\x00\x00\x00\x00\x00\x00'):
6684     attrs = ''
6685     if nw_idx is not None:
6686         attrs += build_wsc_attr(ATTR_NETWORK_INDEX, nw_idx)
6687     if ssid is not None:
6688         attrs += build_wsc_attr(ATTR_SSID, ssid)
6689     if auth_type is not None:
6690         attrs += build_wsc_attr(ATTR_AUTH_TYPE, auth_type)
6691     if encr_type is not None:
6692         attrs += build_wsc_attr(ATTR_ENCR_TYPE, encr_type)
6693     if nw_key is not None:
6694         attrs += build_wsc_attr(ATTR_NETWORK_KEY, nw_key)
6695     if mac_addr is not None:
6696         attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6697     return build_wsc_attr(ATTR_CRED, attrs)
6698
6699 def test_wps_ext_cred_proto_success(dev, apdev):
6700     """WPS and Credential: success"""
6701     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6702     m8_cred = build_cred(mac_addr=mac_addr)
6703     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6704
6705 def test_wps_ext_cred_proto_mac_addr_mismatch(dev, apdev):
6706     """WPS and Credential: MAC Address mismatch"""
6707     m8_cred = build_cred()
6708     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6709
6710 def test_wps_ext_cred_proto_zero_padding(dev, apdev):
6711     """WPS and Credential: zeropadded attributes"""
6712     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6713     m8_cred = build_cred(mac_addr=mac_addr, ssid='test-wps-conf\x00',
6714                          nw_key="12345678\x00")
6715     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6716
6717 def test_wps_ext_cred_proto_ssid_missing(dev, apdev):
6718     """WPS and Credential: SSID missing"""
6719     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6720     m8_cred = build_cred(mac_addr=mac_addr, ssid=None)
6721     wps_run_cred_proto(dev, apdev, m8_cred)
6722
6723 def test_wps_ext_cred_proto_ssid_zero_len(dev, apdev):
6724     """WPS and Credential: Zero-length SSID"""
6725     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6726     m8_cred = build_cred(mac_addr=mac_addr, ssid="")
6727     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6728
6729 def test_wps_ext_cred_proto_auth_type_missing(dev, apdev):
6730     """WPS and Credential: Auth Type missing"""
6731     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6732     m8_cred = build_cred(mac_addr=mac_addr, auth_type=None)
6733     wps_run_cred_proto(dev, apdev, m8_cred)
6734
6735 def test_wps_ext_cred_proto_encr_type_missing(dev, apdev):
6736     """WPS and Credential: Encr Type missing"""
6737     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6738     m8_cred = build_cred(mac_addr=mac_addr, encr_type=None)
6739     wps_run_cred_proto(dev, apdev, m8_cred)
6740
6741 def test_wps_ext_cred_proto_network_key_missing(dev, apdev):
6742     """WPS and Credential: Network Key missing"""
6743     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6744     m8_cred = build_cred(mac_addr=mac_addr, nw_key=None)
6745     wps_run_cred_proto(dev, apdev, m8_cred)
6746
6747 def test_wps_ext_cred_proto_network_key_missing_open(dev, apdev):
6748     """WPS and Credential: Network Key missing (open)"""
6749     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6750     m8_cred = build_cred(mac_addr=mac_addr, auth_type='\x00\x01',
6751                          encr_type='\x00\x01', nw_key=None, ssid="foo")
6752     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6753
6754 def test_wps_ext_cred_proto_mac_addr_missing(dev, apdev):
6755     """WPS and Credential: MAC Address missing"""
6756     m8_cred = build_cred(mac_addr=None)
6757     wps_run_cred_proto(dev, apdev, m8_cred)
6758
6759 def test_wps_ext_cred_proto_invalid_encr_type(dev, apdev):
6760     """WPS and Credential: Invalid Encr Type"""
6761     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6762     m8_cred = build_cred(mac_addr=mac_addr, encr_type='\x00\x00')
6763     wps_run_cred_proto(dev, apdev, m8_cred)
6764
6765 def test_wps_ext_cred_proto_missing_cred(dev, apdev):
6766     """WPS and Credential: Missing Credential"""
6767     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6768     m8_cred = ''
6769     wps_run_cred_proto(dev, apdev, m8_cred)
6770
6771 def test_wps_ext_proto_m2_no_public_key(dev, apdev):
6772     """WPS and no Public Key in M2"""
6773     pin = "12345670"
6774     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6775     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6776     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6777     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6778
6779     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6780     uuid_r = 16*'\x33'
6781     r_nonce = 16*'\x44'
6782     own_private, e_pk = wsc_dh_init()
6783
6784     logger.debug("Receive M1 from STA")
6785     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6786     eap_id = (msg['eap_identifier'] + 1) % 256
6787
6788     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6789                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6790                                     r_nonce)
6791     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6792                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6793
6794     logger.debug("Send M2 to STA")
6795     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6796                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6797                                 r_nonce, uuid_r, None)
6798     send_wsc_msg(dev[0], bssid, m2)
6799     eap_id = (eap_id + 1) % 256
6800
6801     # Verify STA NACK's the credential
6802     msg = get_wsc_msg(dev[0])
6803     if msg['wsc_opcode'] != WSC_NACK:
6804         raise Exception("Unexpected message - expected WSC_Nack")
6805     dev[0].request("WPS_CANCEL")
6806     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6807     dev[0].wait_disconnected()
6808
6809 def test_wps_ext_proto_m2_invalid_public_key(dev, apdev):
6810     """WPS and invalid Public Key in M2"""
6811     pin = "12345670"
6812     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6813     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6814     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6815     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6816
6817     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6818     uuid_r = 16*'\x33'
6819     r_nonce = 16*'\x44'
6820     own_private, e_pk = wsc_dh_init()
6821
6822     logger.debug("Receive M1 from STA")
6823     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6824     eap_id = (msg['eap_identifier'] + 1) % 256
6825
6826     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6827                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6828                                     r_nonce)
6829     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6830                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6831
6832     logger.debug("Send M2 to STA")
6833     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6834                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6835                                 r_nonce, uuid_r, 192*'\xff')
6836     send_wsc_msg(dev[0], bssid, m2)
6837     eap_id = (eap_id + 1) % 256
6838
6839     # Verify STA NACK's the credential
6840     msg = get_wsc_msg(dev[0])
6841     if msg['wsc_opcode'] != WSC_NACK:
6842         raise Exception("Unexpected message - expected WSC_Nack")
6843     dev[0].request("WPS_CANCEL")
6844     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6845     dev[0].wait_disconnected()
6846
6847 def test_wps_ext_proto_m2_public_key_oom(dev, apdev):
6848     """WPS and Public Key OOM in M2"""
6849     pin = "12345670"
6850     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6851     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6852     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6853     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6854
6855     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6856     uuid_r = 16*'\x33'
6857     r_nonce = 16*'\x44'
6858     own_private, e_pk = wsc_dh_init()
6859
6860     logger.debug("Receive M1 from STA")
6861     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6862     eap_id = (msg['eap_identifier'] + 1) % 256
6863
6864     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6865                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6866                                     r_nonce)
6867     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6868                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6869
6870     logger.debug("Send M2 to STA")
6871     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6872                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6873                                 r_nonce, uuid_r, e_pk)
6874     with alloc_fail(dev[0], 1, "wpabuf_alloc_copy;wps_process_pubkey"):
6875         send_wsc_msg(dev[0], bssid, m2)
6876         eap_id = (eap_id + 1) % 256
6877
6878         # Verify STA NACK's the credential
6879         msg = get_wsc_msg(dev[0])
6880         if msg['wsc_opcode'] != WSC_NACK:
6881             raise Exception("Unexpected message - expected WSC_Nack")
6882         dev[0].request("WPS_CANCEL")
6883         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6884         dev[0].wait_disconnected()
6885
6886 def test_wps_ext_proto_nack_m3(dev, apdev):
6887     """WPS and NACK M3"""
6888     pin = "12345670"
6889     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6890     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6891     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6892     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6893
6894     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6895     uuid_r = 16*'\x33'
6896     r_nonce = 16*'\x44'
6897     own_private, e_pk = wsc_dh_init()
6898
6899     logger.debug("Receive M1 from STA")
6900     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6901     eap_id = (msg['eap_identifier'] + 1) % 256
6902
6903     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6904                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6905                                     r_nonce)
6906     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6907                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6908
6909     logger.debug("Send M2 to STA")
6910     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6911                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6912                                 r_nonce, uuid_r, e_pk)
6913     send_wsc_msg(dev[0], bssid, m2)
6914     eap_id = (eap_id + 1) % 256
6915
6916     logger.debug("Receive M3 from STA")
6917     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6918
6919     logger.debug("Send NACK to STA")
6920     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
6921                             r_nonce, config_error='\x01\x23')
6922     send_wsc_msg(dev[0], bssid, msg)
6923     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
6924     if ev is None:
6925         raise Exception("Failure not reported")
6926     if "msg=7 config_error=291" not in ev:
6927         raise Exception("Unexpected failure reason: " + ev)
6928
6929 def test_wps_ext_proto_nack_m5(dev, apdev):
6930     """WPS and NACK M5"""
6931     pin = "12345670"
6932     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6933     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6934     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6935     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6936
6937     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6938     uuid_r = 16*'\x33'
6939     r_nonce = 16*'\x44'
6940     own_private, e_pk = wsc_dh_init()
6941
6942     logger.debug("Receive M1 from STA")
6943     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6944     eap_id = (msg['eap_identifier'] + 1) % 256
6945
6946     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6947                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6948                                     r_nonce)
6949     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6950                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6951
6952     logger.debug("Send M2 to STA")
6953     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6954                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6955                                 r_nonce, uuid_r, e_pk)
6956     send_wsc_msg(dev[0], bssid, m2)
6957     eap_id = (eap_id + 1) % 256
6958
6959     logger.debug("Receive M3 from STA")
6960     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6961
6962     logger.debug("Send M4 to STA")
6963     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6964     attrs += build_attr_msg_type(WPS_M4)
6965     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6966     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6967     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6968     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6969     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6970     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6971     raw_m4_attrs = attrs
6972     m4 = build_eap_wsc(1, eap_id, attrs)
6973     send_wsc_msg(dev[0], bssid, m4)
6974     eap_id = (eap_id + 1) % 256
6975
6976     logger.debug("Receive M5 from STA")
6977     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6978
6979     logger.debug("Send NACK to STA")
6980     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
6981                             r_nonce, config_error='\x01\x24')
6982     send_wsc_msg(dev[0], bssid, msg)
6983     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
6984     if ev is None:
6985         raise Exception("Failure not reported")
6986     if "msg=9 config_error=292" not in ev:
6987         raise Exception("Unexpected failure reason: " + ev)
6988
6989 def wps_nack_m3(dev, apdev):
6990     pin = "00000000"
6991     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
6992     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6993     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6994     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6995
6996     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6997     uuid_r = 16*'\x33'
6998     r_nonce = 16*'\x44'
6999     own_private, e_pk = wsc_dh_init()
7000
7001     logger.debug("Receive M1 from STA")
7002     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7003     eap_id = (msg['eap_identifier'] + 1) % 256
7004
7005     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7006                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7007                                     r_nonce)
7008     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7009                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7010
7011     logger.debug("Send M2 to STA")
7012     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7013                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7014                                 r_nonce, uuid_r, e_pk, dev_pw_id='\x00\x04')
7015     send_wsc_msg(dev[0], bssid, m2)
7016     eap_id = (eap_id + 1) % 256
7017
7018     logger.debug("Receive M3 from STA")
7019     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7020     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid
7021
7022 def test_wps_ext_proto_nack_m3_no_config_error(dev, apdev):
7023     """WPS and NACK M3 missing Config Error"""
7024     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7025     logger.debug("Send NACK to STA")
7026     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, config_error=None)
7027     send_wsc_msg(dev[0], bssid, msg)
7028     dev[0].request("WPS_CANCEL")
7029     dev[0].wait_disconnected()
7030     dev[0].flush_scan_cache()
7031
7032 def test_wps_ext_proto_nack_m3_no_e_nonce(dev, apdev):
7033     """WPS and NACK M3 missing E-Nonce"""
7034     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7035     logger.debug("Send NACK to STA")
7036     msg, attrs = build_nack(eap_id, None, r_nonce)
7037     send_wsc_msg(dev[0], bssid, msg)
7038     dev[0].request("WPS_CANCEL")
7039     dev[0].wait_disconnected()
7040     dev[0].flush_scan_cache()
7041
7042 def test_wps_ext_proto_nack_m3_e_nonce_mismatch(dev, apdev):
7043     """WPS and NACK M3 E-Nonce mismatch"""
7044     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7045     logger.debug("Send NACK to STA")
7046     msg, attrs = build_nack(eap_id, 16*'\x00', r_nonce)
7047     send_wsc_msg(dev[0], bssid, msg)
7048     dev[0].request("WPS_CANCEL")
7049     dev[0].wait_disconnected()
7050     dev[0].flush_scan_cache()
7051
7052 def test_wps_ext_proto_nack_m3_no_r_nonce(dev, apdev):
7053     """WPS and NACK M3 missing R-Nonce"""
7054     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7055     logger.debug("Send NACK to STA")
7056     msg, attrs = build_nack(eap_id, e_nonce, None)
7057     send_wsc_msg(dev[0], bssid, msg)
7058     dev[0].request("WPS_CANCEL")
7059     dev[0].wait_disconnected()
7060     dev[0].flush_scan_cache()
7061
7062 def test_wps_ext_proto_nack_m3_r_nonce_mismatch(dev, apdev):
7063     """WPS and NACK M3 R-Nonce mismatch"""
7064     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7065     logger.debug("Send NACK to STA")
7066     msg, attrs = build_nack(eap_id, e_nonce, 16*'\x00')
7067     send_wsc_msg(dev[0], bssid, msg)
7068     dev[0].request("WPS_CANCEL")
7069     dev[0].wait_disconnected()
7070     dev[0].flush_scan_cache()
7071
7072 def test_wps_ext_proto_nack_m3_no_msg_type(dev, apdev):
7073     """WPS and NACK M3 no Message Type"""
7074     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7075     logger.debug("Send NACK to STA")
7076     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=None)
7077     send_wsc_msg(dev[0], bssid, msg)
7078     dev[0].request("WPS_CANCEL")
7079     dev[0].wait_disconnected()
7080     dev[0].flush_scan_cache()
7081
7082 def test_wps_ext_proto_nack_m3_invalid_msg_type(dev, apdev):
7083     """WPS and NACK M3 invalid Message Type"""
7084     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7085     logger.debug("Send NACK to STA")
7086     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=123)
7087     send_wsc_msg(dev[0], bssid, msg)
7088     dev[0].request("WPS_CANCEL")
7089     dev[0].wait_disconnected()
7090     dev[0].flush_scan_cache()
7091
7092 def test_wps_ext_proto_nack_m3_invalid_attr(dev, apdev):
7093     """WPS and NACK M3 invalid attribute"""
7094     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7095     logger.debug("Send NACK to STA")
7096     attrs = '\x10\x10\x00'
7097     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_NACK)
7098     send_wsc_msg(dev[0], bssid, msg)
7099     dev[0].request("WPS_CANCEL")
7100     dev[0].wait_disconnected()
7101     dev[0].flush_scan_cache()
7102
7103 def test_wps_ext_proto_ack_m3_no_e_nonce(dev, apdev):
7104     """WPS and ACK M3 missing E-Nonce"""
7105     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7106     logger.debug("Send NACK to STA")
7107     msg, attrs = build_ack(eap_id, None, r_nonce)
7108     send_wsc_msg(dev[0], bssid, msg)
7109     dev[0].request("WPS_CANCEL")
7110     dev[0].wait_disconnected()
7111     dev[0].flush_scan_cache()
7112
7113 def test_wps_ext_proto_ack_m3_e_nonce_mismatch(dev, apdev):
7114     """WPS and ACK M3 E-Nonce mismatch"""
7115     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7116     logger.debug("Send NACK to STA")
7117     msg, attrs = build_ack(eap_id, 16*'\x00', r_nonce)
7118     send_wsc_msg(dev[0], bssid, msg)
7119     dev[0].request("WPS_CANCEL")
7120     dev[0].wait_disconnected()
7121     dev[0].flush_scan_cache()
7122
7123 def test_wps_ext_proto_ack_m3_no_r_nonce(dev, apdev):
7124     """WPS and ACK M3 missing R-Nonce"""
7125     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7126     logger.debug("Send NACK to STA")
7127     msg, attrs = build_ack(eap_id, e_nonce, None)
7128     send_wsc_msg(dev[0], bssid, msg)
7129     dev[0].request("WPS_CANCEL")
7130     dev[0].wait_disconnected()
7131     dev[0].flush_scan_cache()
7132
7133 def test_wps_ext_proto_ack_m3_r_nonce_mismatch(dev, apdev):
7134     """WPS and ACK M3 R-Nonce mismatch"""
7135     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7136     logger.debug("Send NACK to STA")
7137     msg, attrs = build_ack(eap_id, e_nonce, 16*'\x00')
7138     send_wsc_msg(dev[0], bssid, msg)
7139     dev[0].request("WPS_CANCEL")
7140     dev[0].wait_disconnected()
7141     dev[0].flush_scan_cache()
7142
7143 def test_wps_ext_proto_ack_m3_no_msg_type(dev, apdev):
7144     """WPS and ACK M3 no Message Type"""
7145     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7146     logger.debug("Send NACK to STA")
7147     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=None)
7148     send_wsc_msg(dev[0], bssid, msg)
7149     dev[0].request("WPS_CANCEL")
7150     dev[0].wait_disconnected()
7151     dev[0].flush_scan_cache()
7152
7153 def test_wps_ext_proto_ack_m3_invalid_msg_type(dev, apdev):
7154     """WPS and ACK M3 invalid Message Type"""
7155     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7156     logger.debug("Send NACK to STA")
7157     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=123)
7158     send_wsc_msg(dev[0], bssid, msg)
7159     dev[0].request("WPS_CANCEL")
7160     dev[0].wait_disconnected()
7161     dev[0].flush_scan_cache()
7162
7163 def test_wps_ext_proto_ack_m3_invalid_attr(dev, apdev):
7164     """WPS and ACK M3 invalid attribute"""
7165     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7166     logger.debug("Send ACK to STA")
7167     attrs = '\x10\x10\x00'
7168     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_ACK)
7169     send_wsc_msg(dev[0], bssid, msg)
7170     dev[0].request("WPS_CANCEL")
7171     dev[0].wait_disconnected()
7172     dev[0].flush_scan_cache()
7173
7174 def test_wps_ext_proto_ack_m3(dev, apdev):
7175     """WPS and ACK M3"""
7176     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7177     logger.debug("Send ACK to STA")
7178     msg, attrs = build_ack(eap_id, e_nonce, r_nonce)
7179     send_wsc_msg(dev[0], bssid, msg)
7180     dev[0].request("WPS_CANCEL")
7181     dev[0].wait_disconnected()
7182     dev[0].flush_scan_cache()
7183
7184 def wps_to_m3_helper(dev, apdev):
7185     pin = "12345670"
7186     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7187     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7188     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7189     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7190
7191     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7192     uuid_r = 16*'\x33'
7193     r_nonce = 16*'\x44'
7194     own_private, e_pk = wsc_dh_init()
7195
7196     logger.debug("Receive M1 from STA")
7197     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7198     eap_id = (msg['eap_identifier'] + 1) % 256
7199
7200     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7201                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7202                                     r_nonce)
7203     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7204                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7205
7206     logger.debug("Send M2 to STA")
7207     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7208                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7209                                 r_nonce, uuid_r, e_pk)
7210     send_wsc_msg(dev[0], bssid, m2)
7211     eap_id = (eap_id + 1) % 256
7212
7213     logger.debug("Receive M3 from STA")
7214     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7215     return eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey
7216
7217 def wps_to_m3(dev, apdev):
7218     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)
7219     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s1, raw_m3_attrs, authkey, keywrapkey
7220
7221 def wps_to_m5(dev, apdev):
7222     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)
7223
7224     logger.debug("Send M4 to STA")
7225     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7226     attrs += build_attr_msg_type(WPS_M4)
7227     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
7228     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7229     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7230     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7231     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7232     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7233     raw_m4_attrs = attrs
7234     m4 = build_eap_wsc(1, eap_id, attrs)
7235     send_wsc_msg(dev[0], bssid, m4)
7236     eap_id = (eap_id + 1) % 256
7237
7238     logger.debug("Receive M5 from STA")
7239     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
7240
7241     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s2, raw_m5_attrs, authkey, keywrapkey
7242
7243 def test_wps_ext_proto_m4_missing_r_hash1(dev, apdev):
7244     """WPS and no R-Hash1 in M4"""
7245     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7246
7247     logger.debug("Send M4 to STA")
7248     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7249     attrs += build_attr_msg_type(WPS_M4)
7250     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7251     #attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7252     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7253     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7254     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7255     attrs += build_attr_authenticator(authkey, m3, attrs)
7256     m4 = build_eap_wsc(1, eap_id, attrs)
7257     send_wsc_msg(dev[0], bssid, m4)
7258     eap_id = (eap_id + 1) % 256
7259
7260     logger.debug("Receive M5 (NACK) from STA")
7261     msg = get_wsc_msg(dev[0])
7262     if msg['wsc_opcode'] != WSC_NACK:
7263         raise Exception("Unexpected message - expected WSC_Nack")
7264
7265     dev[0].request("WPS_CANCEL")
7266     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7267     dev[0].wait_disconnected()
7268
7269 def test_wps_ext_proto_m4_missing_r_hash2(dev, apdev):
7270     """WPS and no R-Hash2 in M4"""
7271     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7272
7273     logger.debug("Send M4 to STA")
7274     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7275     attrs += build_attr_msg_type(WPS_M4)
7276     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7277     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7278     #attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7279     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7280     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7281     attrs += build_attr_authenticator(authkey, m3, attrs)
7282     m4 = build_eap_wsc(1, eap_id, attrs)
7283     send_wsc_msg(dev[0], bssid, m4)
7284     eap_id = (eap_id + 1) % 256
7285
7286     logger.debug("Receive M5 (NACK) from STA")
7287     msg = get_wsc_msg(dev[0])
7288     if msg['wsc_opcode'] != WSC_NACK:
7289         raise Exception("Unexpected message - expected WSC_Nack")
7290
7291     dev[0].request("WPS_CANCEL")
7292     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7293     dev[0].wait_disconnected()
7294
7295 def test_wps_ext_proto_m4_missing_r_snonce1(dev, apdev):
7296     """WPS and no R-SNonce1 in M4"""
7297     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7298
7299     logger.debug("Send M4 to STA")
7300     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7301     attrs += build_attr_msg_type(WPS_M4)
7302     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7303     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7304     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7305     #data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7306     data = ''
7307     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7308     attrs += build_attr_authenticator(authkey, m3, attrs)
7309     m4 = build_eap_wsc(1, eap_id, attrs)
7310     send_wsc_msg(dev[0], bssid, m4)
7311     eap_id = (eap_id + 1) % 256
7312
7313     logger.debug("Receive M5 (NACK) from STA")
7314     msg = get_wsc_msg(dev[0])
7315     if msg['wsc_opcode'] != WSC_NACK:
7316         raise Exception("Unexpected message - expected WSC_Nack")
7317
7318     dev[0].request("WPS_CANCEL")
7319     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7320     dev[0].wait_disconnected()
7321
7322 def test_wps_ext_proto_m4_invalid_pad_string(dev, apdev):
7323     """WPS and invalid pad string in M4"""
7324     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7325
7326     logger.debug("Send M4 to STA")
7327     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7328     attrs += build_attr_msg_type(WPS_M4)
7329     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7330     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7331     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7332     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7333
7334     m = hmac.new(authkey, data, hashlib.sha256)
7335     kwa = m.digest()[0:8]
7336     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7337     iv = 16*'\x99'
7338     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7339     pad_len = 16 - len(data) % 16
7340     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', pad_len - 1)
7341     data += ps
7342     wrapped = aes.encrypt(data)
7343     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7344
7345     attrs += build_attr_authenticator(authkey, m3, attrs)
7346     m4 = build_eap_wsc(1, eap_id, attrs)
7347     send_wsc_msg(dev[0], bssid, m4)
7348     eap_id = (eap_id + 1) % 256
7349
7350     logger.debug("Receive M5 (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_m4_invalid_pad_value(dev, apdev):
7360     """WPS and invalid pad value in M4"""
7361     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7362
7363     logger.debug("Send M4 to STA")
7364     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7365     attrs += build_attr_msg_type(WPS_M4)
7366     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7367     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7368     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7369     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7370
7371     m = hmac.new(authkey, data, hashlib.sha256)
7372     kwa = m.digest()[0:8]
7373     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7374     iv = 16*'\x99'
7375     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7376     pad_len = 16 - len(data) % 16
7377     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', 255)
7378     data += ps
7379     wrapped = aes.encrypt(data)
7380     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7381
7382     attrs += build_attr_authenticator(authkey, m3, attrs)
7383     m4 = build_eap_wsc(1, eap_id, attrs)
7384     send_wsc_msg(dev[0], bssid, m4)
7385     eap_id = (eap_id + 1) % 256
7386
7387     logger.debug("Receive M5 (NACK) from STA")
7388     msg = get_wsc_msg(dev[0])
7389     if msg['wsc_opcode'] != WSC_NACK:
7390         raise Exception("Unexpected message - expected WSC_Nack")
7391
7392     dev[0].request("WPS_CANCEL")
7393     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7394     dev[0].wait_disconnected()
7395
7396 def test_wps_ext_proto_m4_no_encr_settings(dev, apdev):
7397     """WPS and no Encr Settings in M4"""
7398     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7399
7400     logger.debug("Send M4 to STA")
7401     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7402     attrs += build_attr_msg_type(WPS_M4)
7403     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7404     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7405     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7406     attrs += build_attr_authenticator(authkey, m3, attrs)
7407     m4 = build_eap_wsc(1, eap_id, attrs)
7408     send_wsc_msg(dev[0], bssid, m4)
7409     eap_id = (eap_id + 1) % 256
7410
7411     logger.debug("Receive M5 (NACK) from STA")
7412     msg = get_wsc_msg(dev[0])
7413     if msg['wsc_opcode'] != WSC_NACK:
7414         raise Exception("Unexpected message - expected WSC_Nack")
7415
7416     dev[0].request("WPS_CANCEL")
7417     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7418     dev[0].wait_disconnected()
7419
7420 def test_wps_ext_proto_m6_missing_r_snonce2(dev, apdev):
7421     """WPS and no R-SNonce2 in M6"""
7422     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7423
7424     logger.debug("Send M6 to STA")
7425     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7426     attrs += build_attr_msg_type(WPS_M6)
7427     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7428     #data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7429     data = ''
7430     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7431     attrs += build_attr_authenticator(authkey, m5, attrs)
7432     m6 = build_eap_wsc(1, eap_id, attrs)
7433     send_wsc_msg(dev[0], bssid, m6)
7434     eap_id = (eap_id + 1) % 256
7435
7436     logger.debug("Receive M7 (NACK) from STA")
7437     msg = get_wsc_msg(dev[0])
7438     if msg['wsc_opcode'] != WSC_NACK:
7439         raise Exception("Unexpected message - expected WSC_Nack")
7440
7441     dev[0].request("WPS_CANCEL")
7442     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7443     dev[0].wait_disconnected()
7444
7445 def test_wps_ext_proto_m6_no_encr_settings(dev, apdev):
7446     """WPS and no Encr Settings in M6"""
7447     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7448
7449     logger.debug("Send M6 to STA")
7450     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7451     attrs += build_attr_msg_type(WPS_M6)
7452     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7453     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7454     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7455     attrs += build_attr_authenticator(authkey, m5, attrs)
7456     m6 = build_eap_wsc(1, eap_id, attrs)
7457     send_wsc_msg(dev[0], bssid, m6)
7458     eap_id = (eap_id + 1) % 256
7459
7460     logger.debug("Receive M7 (NACK) from STA")
7461     msg = get_wsc_msg(dev[0])
7462     if msg['wsc_opcode'] != WSC_NACK:
7463         raise Exception("Unexpected message - expected WSC_Nack")
7464
7465     dev[0].request("WPS_CANCEL")
7466     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7467     dev[0].wait_disconnected()
7468
7469 def test_wps_ext_proto_m8_no_encr_settings(dev, apdev):
7470     """WPS and no Encr Settings in M6"""
7471     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7472
7473     logger.debug("Send M6 to STA")
7474     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7475     attrs += build_attr_msg_type(WPS_M6)
7476     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7477     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7478     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7479     attrs += build_attr_authenticator(authkey, m5, attrs)
7480     raw_m6_attrs = attrs
7481     m6 = build_eap_wsc(1, eap_id, attrs)
7482     send_wsc_msg(dev[0], bssid, m6)
7483     eap_id = (eap_id + 1) % 256
7484
7485     logger.debug("Receive M7 from STA")
7486     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
7487
7488     logger.debug("Send M8 to STA")
7489     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7490     attrs += build_attr_msg_type(WPS_M8)
7491     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7492     #attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
7493     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7494     raw_m8_attrs = attrs
7495     m8 = build_eap_wsc(1, eap_id, attrs)
7496     send_wsc_msg(dev[0], bssid, m8)
7497
7498     logger.debug("Receive WSC_Done (NACK) from STA")
7499     msg = get_wsc_msg(dev[0])
7500     if msg['wsc_opcode'] != WSC_NACK:
7501         raise Exception("Unexpected message - expected WSC_Nack")
7502
7503     dev[0].request("WPS_CANCEL")
7504     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7505     dev[0].wait_disconnected()
7506
7507 def wps_start_ext_reg(apdev, dev):
7508     addr = dev.own_addr()
7509     bssid = apdev['bssid']
7510     ssid = "test-wps-conf"
7511     appin = "12345670"
7512     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
7513                "wpa_passphrase": "12345678", "wpa": "2",
7514                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
7515                "ap_pin": appin }
7516     hapd = hostapd.add_ap(apdev['ifname'], params)
7517
7518     dev.scan_for_bss(bssid, freq="2412")
7519     hapd.request("SET ext_eapol_frame_io 1")
7520     dev.request("SET ext_eapol_frame_io 1")
7521
7522     dev.request("WPS_REG " + bssid + " " + appin)
7523
7524     return addr,bssid,hapd
7525
7526 def wps_run_ap_settings_proto(dev, apdev, ap_settings, success):
7527     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7528     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7529     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7530
7531     logger.debug("Receive M1 from AP")
7532     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7533     mac_addr = m1_attrs[ATTR_MAC_ADDR]
7534     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7535     e_pk = m1_attrs[ATTR_PUBLIC_KEY]
7536
7537     appin = '12345670'
7538     uuid_r = 16*'\x33'
7539     r_nonce = 16*'\x44'
7540     own_private, r_pk = wsc_dh_init()
7541     authkey,keywrapkey = wsc_dh_kdf(e_pk, own_private, mac_addr, e_nonce,
7542                                     r_nonce)
7543     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, appin, e_pk, r_pk)
7544
7545     logger.debug("Send M2 to AP")
7546     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, msg['eap_identifier'],
7547                                 e_nonce, r_nonce, uuid_r, r_pk, eap_code=2)
7548     send_wsc_msg(hapd, addr, m2)
7549
7550     logger.debug("Receive M3 from AP")
7551     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M3)
7552
7553     logger.debug("Send M4 to AP")
7554     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7555     attrs += build_attr_msg_type(WPS_M4)
7556     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7557     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7558     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7559     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7560     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7561     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7562     raw_m4_attrs = attrs
7563     m4 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7564     send_wsc_msg(hapd, addr, m4)
7565
7566     logger.debug("Receive M5 from AP")
7567     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M5)
7568
7569     logger.debug("Send M6 to STA")
7570     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7571     attrs += build_attr_msg_type(WPS_M6)
7572     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7573     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7574     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7575     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
7576     raw_m6_attrs = attrs
7577     m6 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7578     send_wsc_msg(hapd, addr, m6)
7579
7580     logger.debug("Receive M7 from AP")
7581     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M7)
7582
7583     logger.debug("Send M8 to STA")
7584     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7585     attrs += build_attr_msg_type(WPS_M8)
7586     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7587     if ap_settings:
7588         attrs += build_attr_encr_settings(authkey, keywrapkey, ap_settings)
7589     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7590     raw_m8_attrs = attrs
7591     m8 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7592     send_wsc_msg(hapd, addr, m8)
7593
7594     if success:
7595         ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
7596         if ev is None:
7597             raise Exception("New AP settings not reported")
7598         logger.debug("Receive WSC_Done from AP")
7599         msg = get_wsc_msg(hapd)
7600         if msg['wsc_opcode'] != WSC_Done:
7601             raise Exception("Unexpected message - expected WSC_Done")
7602
7603         logger.debug("Send WSC_ACK to AP")
7604         ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
7605                               eap_code=2)
7606         send_wsc_msg(hapd, addr, ack)
7607         dev[0].wait_disconnected()
7608     else:
7609         ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
7610         if ev is None:
7611             raise Exception("WPS failure not reported")
7612         logger.debug("Receive WSC_NACK from AP")
7613         msg = get_wsc_msg(hapd)
7614         if msg['wsc_opcode'] != WSC_NACK:
7615             raise Exception("Unexpected message - expected WSC_NACK")
7616
7617         logger.debug("Send WSC_NACK to AP")
7618         nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7619                                 eap_code=2)
7620         send_wsc_msg(hapd, addr, nack)
7621         dev[0].wait_disconnected()
7622
7623 def test_wps_ext_ap_settings_success(dev, apdev):
7624     """WPS and AP Settings: success"""
7625     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7626     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7627     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7628     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7629     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7630     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7631     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7632
7633 def test_wps_ext_ap_settings_missing(dev, apdev):
7634     """WPS and AP Settings: missing"""
7635     wps_run_ap_settings_proto(dev, apdev, None, False)
7636
7637 def test_wps_ext_ap_settings_mac_addr_mismatch(dev, apdev):
7638     """WPS and AP Settings: MAC Address mismatch"""
7639     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7640     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7641     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7642     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7643     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7644     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, '\x00\x00\x00\x00\x00\x00')
7645     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7646
7647 def test_wps_ext_ap_settings_mac_addr_missing(dev, apdev):
7648     """WPS and AP Settings: missing MAC Address"""
7649     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7650     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7651     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7652     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7653     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7654     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7655
7656 def test_wps_ext_ap_settings_reject_encr_type(dev, apdev):
7657     """WPS and AP Settings: reject Encr Type"""
7658     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7659     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7660     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7661     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x00')
7662     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7663     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7664     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7665
7666 def test_wps_ext_ap_settings_m2d(dev, apdev):
7667     """WPS and AP Settings: M2D"""
7668     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7669     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7670     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7671
7672     logger.debug("Receive M1 from AP")
7673     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7674     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7675
7676     r_nonce = 16*'\x44'
7677     uuid_r = 16*'\x33'
7678
7679     logger.debug("Send M2D to AP")
7680     m2d, raw_m2d_attrs = build_m2d(raw_m1_attrs, msg['eap_identifier'],
7681                                    e_nonce, r_nonce, uuid_r,
7682                                    dev_pw_id='\x00\x00', eap_code=2)
7683     send_wsc_msg(hapd, addr, m2d)
7684
7685     ev = hapd.wait_event(["WPS-M2D"], timeout=5)
7686     if ev is None:
7687         raise Exception("M2D not reported")
7688
7689     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7690
7691 def wps_wait_ap_nack(hapd, dev, e_nonce, r_nonce):
7692     logger.debug("Receive WSC_NACK from AP")
7693     msg = get_wsc_msg(hapd)
7694     if msg['wsc_opcode'] != WSC_NACK:
7695         raise Exception("Unexpected message - expected WSC_NACK")
7696
7697     logger.debug("Send WSC_NACK to AP")
7698     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7699                             eap_code=2)
7700     send_wsc_msg(hapd, dev.own_addr(), nack)
7701     dev.wait_disconnected()
7702
7703 def test_wps_ext_m3_missing_e_hash1(dev, apdev):
7704     """WPS proto: M3 missing E-Hash1"""
7705     pin = "12345670"
7706     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7707     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7708     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7709
7710     logger.debug("Receive WSC/Start from AP")
7711     msg = get_wsc_msg(hapd)
7712     if msg['wsc_opcode'] != WSC_Start:
7713         raise Exception("Unexpected Op-Code for WSC/Start")
7714
7715     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7716     uuid_e = 16*'\x11'
7717     e_nonce = 16*'\x22'
7718     own_private, e_pk = wsc_dh_init()
7719
7720     logger.debug("Send M1 to AP")
7721     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7722                                 e_nonce, e_pk)
7723     send_wsc_msg(hapd, addr, m1)
7724
7725     logger.debug("Receive M2 from AP")
7726     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7727     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7728     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7729
7730     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7731                                     r_nonce)
7732     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7733
7734     logger.debug("Send M3 to AP")
7735     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7736     attrs += build_attr_msg_type(WPS_M3)
7737     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7738     #attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7739     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7740     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7741     raw_m3_attrs = attrs
7742     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7743     send_wsc_msg(hapd, addr, m3)
7744
7745     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7746
7747 def test_wps_ext_m3_missing_e_hash2(dev, apdev):
7748     """WPS proto: M3 missing E-Hash2"""
7749     pin = "12345670"
7750     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7751     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7752     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7753
7754     logger.debug("Receive WSC/Start from AP")
7755     msg = get_wsc_msg(hapd)
7756     if msg['wsc_opcode'] != WSC_Start:
7757         raise Exception("Unexpected Op-Code for WSC/Start")
7758
7759     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7760     uuid_e = 16*'\x11'
7761     e_nonce = 16*'\x22'
7762     own_private, e_pk = wsc_dh_init()
7763
7764     logger.debug("Send M1 to AP")
7765     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7766                                 e_nonce, e_pk)
7767     send_wsc_msg(hapd, addr, m1)
7768
7769     logger.debug("Receive M2 from AP")
7770     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7771     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7772     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7773
7774     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7775                                     r_nonce)
7776     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7777
7778     logger.debug("Send M3 to AP")
7779     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7780     attrs += build_attr_msg_type(WPS_M3)
7781     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7782     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7783     #attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7784     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7785     raw_m3_attrs = attrs
7786     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7787     send_wsc_msg(hapd, addr, m3)
7788
7789     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7790
7791 def test_wps_ext_m5_missing_e_snonce1(dev, apdev):
7792     """WPS proto: M5 missing E-SNonce1"""
7793     pin = "12345670"
7794     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7795     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7796     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7797
7798     logger.debug("Receive WSC/Start from AP")
7799     msg = get_wsc_msg(hapd)
7800     if msg['wsc_opcode'] != WSC_Start:
7801         raise Exception("Unexpected Op-Code for WSC/Start")
7802
7803     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7804     uuid_e = 16*'\x11'
7805     e_nonce = 16*'\x22'
7806     own_private, e_pk = wsc_dh_init()
7807
7808     logger.debug("Send M1 to AP")
7809     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7810                                 e_nonce, e_pk)
7811     send_wsc_msg(hapd, addr, m1)
7812
7813     logger.debug("Receive M2 from AP")
7814     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7815     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7816     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7817
7818     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7819                                     r_nonce)
7820     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7821
7822     logger.debug("Send M3 to AP")
7823     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7824     attrs += build_attr_msg_type(WPS_M3)
7825     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7826     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7827     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7828     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7829     raw_m3_attrs = attrs
7830     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7831     send_wsc_msg(hapd, addr, m3)
7832
7833     logger.debug("Receive M4 from AP")
7834     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7835
7836     logger.debug("Send M5 to AP")
7837     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7838     attrs += build_attr_msg_type(WPS_M5)
7839     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7840     #data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7841     data = ''
7842     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7843     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7844     raw_m5_attrs = attrs
7845     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7846     send_wsc_msg(hapd, addr, m5)
7847
7848     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7849
7850 def test_wps_ext_m5_e_snonce1_mismatch(dev, apdev):
7851     """WPS proto: M5 E-SNonce1 mismatch"""
7852     pin = "12345670"
7853     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7854     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7855     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7856
7857     logger.debug("Receive WSC/Start from AP")
7858     msg = get_wsc_msg(hapd)
7859     if msg['wsc_opcode'] != WSC_Start:
7860         raise Exception("Unexpected Op-Code for WSC/Start")
7861
7862     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7863     uuid_e = 16*'\x11'
7864     e_nonce = 16*'\x22'
7865     own_private, e_pk = wsc_dh_init()
7866
7867     logger.debug("Send M1 to AP")
7868     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7869                                 e_nonce, e_pk)
7870     send_wsc_msg(hapd, addr, m1)
7871
7872     logger.debug("Receive M2 from AP")
7873     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7874     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7875     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7876
7877     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7878                                     r_nonce)
7879     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7880
7881     logger.debug("Send M3 to AP")
7882     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7883     attrs += build_attr_msg_type(WPS_M3)
7884     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7885     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7886     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7887     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7888     raw_m3_attrs = attrs
7889     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7890     send_wsc_msg(hapd, addr, m3)
7891
7892     logger.debug("Receive M4 from AP")
7893     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7894
7895     logger.debug("Send M5 to AP")
7896     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7897     attrs += build_attr_msg_type(WPS_M5)
7898     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7899     data = build_wsc_attr(ATTR_E_SNONCE1, 16*'\x00')
7900     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7901     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7902     raw_m5_attrs = attrs
7903     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7904     send_wsc_msg(hapd, addr, m5)
7905
7906     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7907
7908 def test_wps_ext_m7_missing_e_snonce2(dev, apdev):
7909     """WPS proto: M7 missing E-SNonce2"""
7910     pin = "12345670"
7911     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7912     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7913     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7914
7915     logger.debug("Receive WSC/Start from AP")
7916     msg = get_wsc_msg(hapd)
7917     if msg['wsc_opcode'] != WSC_Start:
7918         raise Exception("Unexpected Op-Code for WSC/Start")
7919
7920     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7921     uuid_e = 16*'\x11'
7922     e_nonce = 16*'\x22'
7923     own_private, e_pk = wsc_dh_init()
7924
7925     logger.debug("Send M1 to AP")
7926     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7927                                 e_nonce, e_pk)
7928     send_wsc_msg(hapd, addr, m1)
7929
7930     logger.debug("Receive M2 from AP")
7931     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7932     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7933     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7934
7935     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7936                                     r_nonce)
7937     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7938
7939     logger.debug("Send M3 to AP")
7940     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7941     attrs += build_attr_msg_type(WPS_M3)
7942     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7943     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7944     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7945     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7946     raw_m3_attrs = attrs
7947     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7948     send_wsc_msg(hapd, addr, m3)
7949
7950     logger.debug("Receive M4 from AP")
7951     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7952
7953     logger.debug("Send M5 to AP")
7954     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7955     attrs += build_attr_msg_type(WPS_M5)
7956     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7957     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7958     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7959     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7960     raw_m5_attrs = attrs
7961     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7962     send_wsc_msg(hapd, addr, m5)
7963
7964     logger.debug("Receive M6 from AP")
7965     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
7966
7967     logger.debug("Send M7 to AP")
7968     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7969     attrs += build_attr_msg_type(WPS_M7)
7970     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7971     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
7972     data = ''
7973     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7974     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
7975     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7976     raw_m7_attrs = attrs
7977     send_wsc_msg(hapd, addr, m7)
7978
7979     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7980
7981 def test_wps_ext_m7_e_snonce2_mismatch(dev, apdev):
7982     """WPS proto: M7 E-SNonce2 mismatch"""
7983     pin = "12345670"
7984     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7985     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7986     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7987
7988     logger.debug("Receive WSC/Start from AP")
7989     msg = get_wsc_msg(hapd)
7990     if msg['wsc_opcode'] != WSC_Start:
7991         raise Exception("Unexpected Op-Code for WSC/Start")
7992
7993     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7994     uuid_e = 16*'\x11'
7995     e_nonce = 16*'\x22'
7996     own_private, e_pk = wsc_dh_init()
7997
7998     logger.debug("Send M1 to AP")
7999     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8000                                 e_nonce, e_pk)
8001     send_wsc_msg(hapd, addr, m1)
8002
8003     logger.debug("Receive M2 from AP")
8004     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8005     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8006     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8007
8008     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8009                                     r_nonce)
8010     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8011
8012     logger.debug("Send M3 to AP")
8013     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8014     attrs += build_attr_msg_type(WPS_M3)
8015     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8016     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8017     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8018     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8019     raw_m3_attrs = attrs
8020     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8021     send_wsc_msg(hapd, addr, m3)
8022
8023     logger.debug("Receive M4 from AP")
8024     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8025
8026     logger.debug("Send M5 to AP")
8027     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8028     attrs += build_attr_msg_type(WPS_M5)
8029     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8030     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8031     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8032     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8033     raw_m5_attrs = attrs
8034     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8035     send_wsc_msg(hapd, addr, m5)
8036
8037     logger.debug("Receive M6 from AP")
8038     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8039
8040     logger.debug("Send M7 to AP")
8041     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8042     attrs += build_attr_msg_type(WPS_M7)
8043     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8044     data = build_wsc_attr(ATTR_E_SNONCE2, 16*'\x00')
8045     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8046     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8047     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8048     raw_m7_attrs = attrs
8049     send_wsc_msg(hapd, addr, m7)
8050
8051     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8052
8053 def test_wps_ext_m1_pubkey_oom(dev, apdev):
8054     """WPS proto: M1 PubKey OOM"""
8055     pin = "12345670"
8056     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8057     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8058     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8059
8060     logger.debug("Receive WSC/Start from AP")
8061     msg = get_wsc_msg(hapd)
8062     if msg['wsc_opcode'] != WSC_Start:
8063         raise Exception("Unexpected Op-Code for WSC/Start")
8064
8065     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8066     uuid_e = 16*'\x11'
8067     e_nonce = 16*'\x22'
8068     own_private, e_pk = wsc_dh_init()
8069
8070     logger.debug("Send M1 to AP")
8071     with alloc_fail(hapd, 1, "wpabuf_alloc_copy;wps_process_pubkey"):
8072         m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8073                                     e_nonce, e_pk)
8074         send_wsc_msg(hapd, addr, m1)
8075         wps_wait_eap_failure(hapd, dev[0])
8076
8077 def wps_wait_eap_failure(hapd, dev):
8078     ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8079     if ev is None:
8080         raise Exception("EAP-Failure not reported")
8081     dev.wait_disconnected()
8082
8083 def test_wps_ext_m3_m1(dev, apdev):
8084     """WPS proto: M3 replaced with M1"""
8085     pin = "12345670"
8086     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8087     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8088     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8089
8090     logger.debug("Receive WSC/Start from AP")
8091     msg = get_wsc_msg(hapd)
8092     if msg['wsc_opcode'] != WSC_Start:
8093         raise Exception("Unexpected Op-Code for WSC/Start")
8094
8095     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8096     uuid_e = 16*'\x11'
8097     e_nonce = 16*'\x22'
8098     own_private, e_pk = wsc_dh_init()
8099
8100     logger.debug("Send M1 to AP")
8101     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8102                                 e_nonce, e_pk)
8103     send_wsc_msg(hapd, addr, m1)
8104
8105     logger.debug("Receive M2 from AP")
8106     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8107     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8108     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8109
8110     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8111                                     r_nonce)
8112     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8113
8114     logger.debug("Send M3(M1) to AP")
8115     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8116     attrs += build_attr_msg_type(WPS_M1)
8117     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8118     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8119     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8120     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8121     raw_m3_attrs = attrs
8122     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8123     send_wsc_msg(hapd, addr, m3)
8124
8125     wps_wait_eap_failure(hapd, dev[0])
8126
8127 def test_wps_ext_m5_m3(dev, apdev):
8128     """WPS proto: M5 replaced with M3"""
8129     pin = "12345670"
8130     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8131     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8132     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8133
8134     logger.debug("Receive WSC/Start from AP")
8135     msg = get_wsc_msg(hapd)
8136     if msg['wsc_opcode'] != WSC_Start:
8137         raise Exception("Unexpected Op-Code for WSC/Start")
8138
8139     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8140     uuid_e = 16*'\x11'
8141     e_nonce = 16*'\x22'
8142     own_private, e_pk = wsc_dh_init()
8143
8144     logger.debug("Send M1 to AP")
8145     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8146                                 e_nonce, e_pk)
8147     send_wsc_msg(hapd, addr, m1)
8148
8149     logger.debug("Receive M2 from AP")
8150     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8151     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8152     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8153
8154     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8155                                     r_nonce)
8156     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8157
8158     logger.debug("Send M3 to AP")
8159     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8160     attrs += build_attr_msg_type(WPS_M3)
8161     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8162     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8163     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8164     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8165     raw_m3_attrs = attrs
8166     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8167     send_wsc_msg(hapd, addr, m3)
8168
8169     logger.debug("Receive M4 from AP")
8170     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8171
8172     logger.debug("Send M5(M3) to AP")
8173     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8174     attrs += build_attr_msg_type(WPS_M3)
8175     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8176     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8177     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8178     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8179     raw_m5_attrs = attrs
8180     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8181     send_wsc_msg(hapd, addr, m5)
8182
8183     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8184
8185 def test_wps_ext_m3_m2(dev, apdev):
8186     """WPS proto: M3 replaced with M2"""
8187     pin = "12345670"
8188     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8189     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8190     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8191
8192     logger.debug("Receive WSC/Start from AP")
8193     msg = get_wsc_msg(hapd)
8194     if msg['wsc_opcode'] != WSC_Start:
8195         raise Exception("Unexpected Op-Code for WSC/Start")
8196
8197     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8198     uuid_e = 16*'\x11'
8199     e_nonce = 16*'\x22'
8200     own_private, e_pk = wsc_dh_init()
8201
8202     logger.debug("Send M1 to AP")
8203     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8204                                 e_nonce, e_pk)
8205     send_wsc_msg(hapd, addr, m1)
8206
8207     logger.debug("Receive M2 from AP")
8208     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8209     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8210     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8211
8212     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8213                                     r_nonce)
8214     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8215
8216     logger.debug("Send M3(M2) to AP")
8217     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8218     attrs += build_attr_msg_type(WPS_M2)
8219     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8220     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8221     raw_m3_attrs = attrs
8222     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8223     send_wsc_msg(hapd, addr, m3)
8224
8225     wps_wait_eap_failure(hapd, dev[0])
8226
8227 def test_wps_ext_m3_m5(dev, apdev):
8228     """WPS proto: M3 replaced with M5"""
8229     pin = "12345670"
8230     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8231     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8232     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8233
8234     logger.debug("Receive WSC/Start from AP")
8235     msg = get_wsc_msg(hapd)
8236     if msg['wsc_opcode'] != WSC_Start:
8237         raise Exception("Unexpected Op-Code for WSC/Start")
8238
8239     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8240     uuid_e = 16*'\x11'
8241     e_nonce = 16*'\x22'
8242     own_private, e_pk = wsc_dh_init()
8243
8244     logger.debug("Send M1 to AP")
8245     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8246                                 e_nonce, e_pk)
8247     send_wsc_msg(hapd, addr, m1)
8248
8249     logger.debug("Receive M2 from AP")
8250     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8251     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8252     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8253
8254     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8255                                     r_nonce)
8256     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8257
8258     logger.debug("Send M3(M5) to AP")
8259     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8260     attrs += build_attr_msg_type(WPS_M5)
8261     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8262     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8263     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8264     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8265     raw_m3_attrs = attrs
8266     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8267     send_wsc_msg(hapd, addr, m3)
8268
8269     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8270
8271 def test_wps_ext_m3_m7(dev, apdev):
8272     """WPS proto: M3 replaced with M7"""
8273     pin = "12345670"
8274     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8275     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8276     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8277
8278     logger.debug("Receive WSC/Start from AP")
8279     msg = get_wsc_msg(hapd)
8280     if msg['wsc_opcode'] != WSC_Start:
8281         raise Exception("Unexpected Op-Code for WSC/Start")
8282
8283     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8284     uuid_e = 16*'\x11'
8285     e_nonce = 16*'\x22'
8286     own_private, e_pk = wsc_dh_init()
8287
8288     logger.debug("Send M1 to AP")
8289     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8290                                 e_nonce, e_pk)
8291     send_wsc_msg(hapd, addr, m1)
8292
8293     logger.debug("Receive M2 from AP")
8294     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8295     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8296     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8297
8298     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8299                                     r_nonce)
8300     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8301
8302     logger.debug("Send M3(M7) to AP")
8303     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8304     attrs += build_attr_msg_type(WPS_M7)
8305     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8306     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8307     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8308     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8309     raw_m3_attrs = attrs
8310     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8311     send_wsc_msg(hapd, addr, m3)
8312
8313     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8314
8315 def test_wps_ext_m3_done(dev, apdev):
8316     """WPS proto: M3 replaced with WSC_Done"""
8317     pin = "12345670"
8318     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8319     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8320     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8321
8322     logger.debug("Receive WSC/Start from AP")
8323     msg = get_wsc_msg(hapd)
8324     if msg['wsc_opcode'] != WSC_Start:
8325         raise Exception("Unexpected Op-Code for WSC/Start")
8326
8327     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8328     uuid_e = 16*'\x11'
8329     e_nonce = 16*'\x22'
8330     own_private, e_pk = wsc_dh_init()
8331
8332     logger.debug("Send M1 to AP")
8333     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8334                                 e_nonce, e_pk)
8335     send_wsc_msg(hapd, addr, m1)
8336
8337     logger.debug("Receive M2 from AP")
8338     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8339     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8340     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8341
8342     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8343                                     r_nonce)
8344     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8345
8346     logger.debug("Send M3(WSC_Done) to AP")
8347     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8348     attrs += build_attr_msg_type(WPS_WSC_DONE)
8349     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8350     raw_m3_attrs = attrs
8351     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8352     send_wsc_msg(hapd, addr, m3)
8353
8354     wps_wait_eap_failure(hapd, dev[0])
8355
8356 def test_wps_ext_m2_nack_invalid(dev, apdev):
8357     """WPS proto: M2 followed by invalid NACK"""
8358     pin = "12345670"
8359     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8360     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8361     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8362
8363     logger.debug("Receive WSC/Start from AP")
8364     msg = get_wsc_msg(hapd)
8365     if msg['wsc_opcode'] != WSC_Start:
8366         raise Exception("Unexpected Op-Code for WSC/Start")
8367
8368     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8369     uuid_e = 16*'\x11'
8370     e_nonce = 16*'\x22'
8371     own_private, e_pk = wsc_dh_init()
8372
8373     logger.debug("Send M1 to AP")
8374     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8375                                 e_nonce, e_pk)
8376     send_wsc_msg(hapd, addr, m1)
8377
8378     logger.debug("Receive M2 from AP")
8379     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8380     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8381     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8382
8383     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8384                                     r_nonce)
8385     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8386
8387     logger.debug("Send WSC_NACK to AP")
8388     attrs = '\x10\x00\x00'
8389     nack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_NACK)
8390     send_wsc_msg(hapd, addr, nack)
8391
8392     wps_wait_eap_failure(hapd, dev[0])
8393
8394 def test_wps_ext_m2_nack_no_msg_type(dev, apdev):
8395     """WPS proto: M2 followed by NACK without Msg Type"""
8396     pin = "12345670"
8397     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8398     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8399     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8400
8401     logger.debug("Receive WSC/Start from AP")
8402     msg = get_wsc_msg(hapd)
8403     if msg['wsc_opcode'] != WSC_Start:
8404         raise Exception("Unexpected Op-Code for WSC/Start")
8405
8406     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8407     uuid_e = 16*'\x11'
8408     e_nonce = 16*'\x22'
8409     own_private, e_pk = wsc_dh_init()
8410
8411     logger.debug("Send M1 to AP")
8412     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8413                                 e_nonce, e_pk)
8414     send_wsc_msg(hapd, addr, m1)
8415
8416     logger.debug("Receive M2 from AP")
8417     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8418     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8419     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8420
8421     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8422                                     r_nonce)
8423     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8424
8425     logger.debug("Send WSC_NACK to AP")
8426     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8427                             msg_type=None, eap_code=2)
8428     send_wsc_msg(hapd, addr, nack)
8429
8430     wps_wait_eap_failure(hapd, dev[0])
8431
8432 def test_wps_ext_m2_nack_invalid_msg_type(dev, apdev):
8433     """WPS proto: M2 followed by NACK with invalid Msg Type"""
8434     pin = "12345670"
8435     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8436     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8437     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8438
8439     logger.debug("Receive WSC/Start from AP")
8440     msg = get_wsc_msg(hapd)
8441     if msg['wsc_opcode'] != WSC_Start:
8442         raise Exception("Unexpected Op-Code for WSC/Start")
8443
8444     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8445     uuid_e = 16*'\x11'
8446     e_nonce = 16*'\x22'
8447     own_private, e_pk = wsc_dh_init()
8448
8449     logger.debug("Send M1 to AP")
8450     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8451                                 e_nonce, e_pk)
8452     send_wsc_msg(hapd, addr, m1)
8453
8454     logger.debug("Receive M2 from AP")
8455     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8456     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8457     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8458
8459     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8460                                     r_nonce)
8461     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8462
8463     logger.debug("Send WSC_NACK to AP")
8464     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8465                             msg_type=WPS_WSC_ACK, eap_code=2)
8466     send_wsc_msg(hapd, addr, nack)
8467
8468     wps_wait_eap_failure(hapd, dev[0])
8469
8470 def test_wps_ext_m2_nack_e_nonce_mismatch(dev, apdev):
8471     """WPS proto: M2 followed by NACK with e-nonce mismatch"""
8472     pin = "12345670"
8473     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8474     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8475     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8476
8477     logger.debug("Receive WSC/Start from AP")
8478     msg = get_wsc_msg(hapd)
8479     if msg['wsc_opcode'] != WSC_Start:
8480         raise Exception("Unexpected Op-Code for WSC/Start")
8481
8482     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8483     uuid_e = 16*'\x11'
8484     e_nonce = 16*'\x22'
8485     own_private, e_pk = wsc_dh_init()
8486
8487     logger.debug("Send M1 to AP")
8488     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8489                                 e_nonce, e_pk)
8490     send_wsc_msg(hapd, addr, m1)
8491
8492     logger.debug("Receive M2 from AP")
8493     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8494     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8495     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8496
8497     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8498                                     r_nonce)
8499     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8500
8501     logger.debug("Send WSC_NACK to AP")
8502     nack,attrs = build_nack(msg['eap_identifier'], 16*'\x00', r_nonce,
8503                             eap_code=2)
8504     send_wsc_msg(hapd, addr, nack)
8505
8506     wps_wait_eap_failure(hapd, dev[0])
8507
8508 def test_wps_ext_m2_nack_no_config_error(dev, apdev):
8509     """WPS proto: M2 followed by NACK without Config Error"""
8510     pin = "12345670"
8511     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8512     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8513     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8514
8515     logger.debug("Receive WSC/Start from AP")
8516     msg = get_wsc_msg(hapd)
8517     if msg['wsc_opcode'] != WSC_Start:
8518         raise Exception("Unexpected Op-Code for WSC/Start")
8519
8520     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8521     uuid_e = 16*'\x11'
8522     e_nonce = 16*'\x22'
8523     own_private, e_pk = wsc_dh_init()
8524
8525     logger.debug("Send M1 to AP")
8526     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8527                                 e_nonce, e_pk)
8528     send_wsc_msg(hapd, addr, m1)
8529
8530     logger.debug("Receive M2 from AP")
8531     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8532     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8533     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8534
8535     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8536                                     r_nonce)
8537     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8538
8539     logger.debug("Send WSC_NACK to AP")
8540     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8541                             config_error=None, eap_code=2)
8542     send_wsc_msg(hapd, addr, nack)
8543
8544     wps_wait_eap_failure(hapd, dev[0])
8545
8546 def test_wps_ext_m2_ack_invalid(dev, apdev):
8547     """WPS proto: M2 followed by invalid ACK"""
8548     pin = "12345670"
8549     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8550     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8551     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8552
8553     logger.debug("Receive WSC/Start from AP")
8554     msg = get_wsc_msg(hapd)
8555     if msg['wsc_opcode'] != WSC_Start:
8556         raise Exception("Unexpected Op-Code for WSC/Start")
8557
8558     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8559     uuid_e = 16*'\x11'
8560     e_nonce = 16*'\x22'
8561     own_private, e_pk = wsc_dh_init()
8562
8563     logger.debug("Send M1 to AP")
8564     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8565                                 e_nonce, e_pk)
8566     send_wsc_msg(hapd, addr, m1)
8567
8568     logger.debug("Receive M2 from AP")
8569     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8570     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8571     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8572
8573     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8574                                     r_nonce)
8575     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8576
8577     logger.debug("Send WSC_ACK to AP")
8578     attrs = '\x10\x00\x00'
8579     ack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_ACK)
8580     send_wsc_msg(hapd, addr, ack)
8581
8582     wps_wait_eap_failure(hapd, dev[0])
8583
8584 def test_wps_ext_m2_ack(dev, apdev):
8585     """WPS proto: M2 followed by ACK"""
8586     pin = "12345670"
8587     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8588     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8589     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8590
8591     logger.debug("Receive WSC/Start from AP")
8592     msg = get_wsc_msg(hapd)
8593     if msg['wsc_opcode'] != WSC_Start:
8594         raise Exception("Unexpected Op-Code for WSC/Start")
8595
8596     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8597     uuid_e = 16*'\x11'
8598     e_nonce = 16*'\x22'
8599     own_private, e_pk = wsc_dh_init()
8600
8601     logger.debug("Send M1 to AP")
8602     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8603                                 e_nonce, e_pk)
8604     send_wsc_msg(hapd, addr, m1)
8605
8606     logger.debug("Receive M2 from AP")
8607     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8608     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8609     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8610
8611     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8612                                     r_nonce)
8613     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8614
8615     logger.debug("Send WSC_ACK to AP")
8616     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce, eap_code=2)
8617     send_wsc_msg(hapd, addr, ack)
8618
8619     wps_wait_eap_failure(hapd, dev[0])
8620
8621 def test_wps_ext_m2_ack_no_msg_type(dev, apdev):
8622     """WPS proto: M2 followed by ACK missing Msg Type"""
8623     pin = "12345670"
8624     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8625     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8626     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8627
8628     logger.debug("Receive WSC/Start from AP")
8629     msg = get_wsc_msg(hapd)
8630     if msg['wsc_opcode'] != WSC_Start:
8631         raise Exception("Unexpected Op-Code for WSC/Start")
8632
8633     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8634     uuid_e = 16*'\x11'
8635     e_nonce = 16*'\x22'
8636     own_private, e_pk = wsc_dh_init()
8637
8638     logger.debug("Send M1 to AP")
8639     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8640                                 e_nonce, e_pk)
8641     send_wsc_msg(hapd, addr, m1)
8642
8643     logger.debug("Receive M2 from AP")
8644     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8645     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8646     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8647
8648     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8649                                     r_nonce)
8650     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8651
8652     logger.debug("Send WSC_ACK to AP")
8653     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8654                           msg_type=None, eap_code=2)
8655     send_wsc_msg(hapd, addr, ack)
8656
8657     wps_wait_eap_failure(hapd, dev[0])
8658
8659 def test_wps_ext_m2_ack_invalid_msg_type(dev, apdev):
8660     """WPS proto: M2 followed by ACK with invalid Msg Type"""
8661     pin = "12345670"
8662     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8663     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8664     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8665
8666     logger.debug("Receive WSC/Start from AP")
8667     msg = get_wsc_msg(hapd)
8668     if msg['wsc_opcode'] != WSC_Start:
8669         raise Exception("Unexpected Op-Code for WSC/Start")
8670
8671     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8672     uuid_e = 16*'\x11'
8673     e_nonce = 16*'\x22'
8674     own_private, e_pk = wsc_dh_init()
8675
8676     logger.debug("Send M1 to AP")
8677     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8678                                 e_nonce, e_pk)
8679     send_wsc_msg(hapd, addr, m1)
8680
8681     logger.debug("Receive M2 from AP")
8682     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8683     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8684     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8685
8686     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8687                                     r_nonce)
8688     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8689
8690     logger.debug("Send WSC_ACK to AP")
8691     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8692                           msg_type=WPS_WSC_NACK, eap_code=2)
8693     send_wsc_msg(hapd, addr, ack)
8694
8695     wps_wait_eap_failure(hapd, dev[0])
8696
8697 def test_wps_ext_m2_ack_e_nonce_mismatch(dev, apdev):
8698     """WPS proto: M2 followed by ACK with e-nonce mismatch"""
8699     pin = "12345670"
8700     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8701     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8702     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8703
8704     logger.debug("Receive WSC/Start from AP")
8705     msg = get_wsc_msg(hapd)
8706     if msg['wsc_opcode'] != WSC_Start:
8707         raise Exception("Unexpected Op-Code for WSC/Start")
8708
8709     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8710     uuid_e = 16*'\x11'
8711     e_nonce = 16*'\x22'
8712     own_private, e_pk = wsc_dh_init()
8713
8714     logger.debug("Send M1 to AP")
8715     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8716                                 e_nonce, e_pk)
8717     send_wsc_msg(hapd, addr, m1)
8718
8719     logger.debug("Receive M2 from AP")
8720     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8721     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8722     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8723
8724     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8725                                     r_nonce)
8726     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8727
8728     logger.debug("Send WSC_ACK to AP")
8729     ack,attrs = build_ack(msg['eap_identifier'], 16*'\x00', r_nonce,
8730                           eap_code=2)
8731     send_wsc_msg(hapd, addr, ack)
8732
8733     wps_wait_eap_failure(hapd, dev[0])
8734
8735 def test_wps_ext_m1_invalid(dev, apdev):
8736     """WPS proto: M1 failing parsing"""
8737     pin = "12345670"
8738     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8739     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8740     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8741
8742     logger.debug("Receive WSC/Start from AP")
8743     msg = get_wsc_msg(hapd)
8744     if msg['wsc_opcode'] != WSC_Start:
8745         raise Exception("Unexpected Op-Code for WSC/Start")
8746
8747     logger.debug("Send M1 to AP")
8748     attrs = '\x10\x00\x00'
8749     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8750     send_wsc_msg(hapd, addr, m1)
8751
8752     wps_wait_eap_failure(hapd, dev[0])
8753
8754 def test_wps_ext_m1_missing_msg_type(dev, apdev):
8755     """WPS proto: M1 missing Msg Type"""
8756     pin = "12345670"
8757     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8758     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8759     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8760
8761     logger.debug("Receive WSC/Start from AP")
8762     msg = get_wsc_msg(hapd)
8763     if msg['wsc_opcode'] != WSC_Start:
8764         raise Exception("Unexpected Op-Code for WSC/Start")
8765
8766     logger.debug("Send M1 to AP")
8767     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8768     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8769     send_wsc_msg(hapd, addr, m1)
8770
8771     wps_wait_ap_nack(hapd, dev[0], 16*'\x00', 16*'\x00')
8772
8773 def wps_ext_wsc_done(dev, apdev):
8774     pin = "12345670"
8775     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8776     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8777     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8778
8779     logger.debug("Receive WSC/Start from AP")
8780     msg = get_wsc_msg(hapd)
8781     if msg['wsc_opcode'] != WSC_Start:
8782         raise Exception("Unexpected Op-Code for WSC/Start")
8783
8784     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8785     uuid_e = 16*'\x11'
8786     e_nonce = 16*'\x22'
8787     own_private, e_pk = wsc_dh_init()
8788
8789     logger.debug("Send M1 to AP")
8790     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8791                                 e_nonce, e_pk)
8792     send_wsc_msg(hapd, addr, m1)
8793
8794     logger.debug("Receive M2 from AP")
8795     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8796     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8797     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8798
8799     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8800                                     r_nonce)
8801     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8802
8803     logger.debug("Send M3 to AP")
8804     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8805     attrs += build_attr_msg_type(WPS_M3)
8806     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8807     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8808     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8809     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8810     raw_m3_attrs = attrs
8811     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8812     send_wsc_msg(hapd, addr, m3)
8813
8814     logger.debug("Receive M4 from AP")
8815     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8816
8817     logger.debug("Send M5 to AP")
8818     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8819     attrs += build_attr_msg_type(WPS_M5)
8820     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8821     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8822     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8823     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8824     raw_m5_attrs = attrs
8825     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8826     send_wsc_msg(hapd, addr, m5)
8827
8828     logger.debug("Receive M6 from AP")
8829     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8830
8831     logger.debug("Send M7 to AP")
8832     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8833     attrs += build_attr_msg_type(WPS_M7)
8834     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8835     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8836     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8837     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8838     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8839     raw_m7_attrs = attrs
8840     send_wsc_msg(hapd, addr, m7)
8841
8842     logger.debug("Receive M8 from AP")
8843     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
8844     return hapd, msg, e_nonce, r_nonce
8845
8846 def test_wps_ext_wsc_done_invalid(dev, apdev):
8847     """WPS proto: invalid WSC_Done"""
8848     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8849
8850     logger.debug("Send WSC_Done to AP")
8851     attrs = '\x10\x00\x00'
8852     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8853     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8854
8855     wps_wait_eap_failure(hapd, dev[0])
8856
8857 def test_wps_ext_wsc_done_no_msg_type(dev, apdev):
8858     """WPS proto: invalid WSC_Done"""
8859     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8860
8861     logger.debug("Send WSC_Done to AP")
8862     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8863     #attrs += build_attr_msg_type(WPS_WSC_DONE)
8864     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8865     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8866     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8867     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8868
8869     wps_wait_eap_failure(hapd, dev[0])
8870
8871 def test_wps_ext_wsc_done_wrong_msg_type(dev, apdev):
8872     """WPS proto: WSC_Done with wrong Msg Type"""
8873     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8874
8875     logger.debug("Send WSC_Done to AP")
8876     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8877     attrs += build_attr_msg_type(WPS_WSC_ACK)
8878     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8879     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8880     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8881     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8882
8883     wps_wait_eap_failure(hapd, dev[0])
8884
8885 def test_wps_ext_wsc_done_no_e_nonce(dev, apdev):
8886     """WPS proto: WSC_Done without e_nonce"""
8887     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8888
8889     logger.debug("Send WSC_Done to AP")
8890     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8891     attrs += build_attr_msg_type(WPS_WSC_DONE)
8892     #attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8893     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8894     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8895     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8896
8897     wps_wait_eap_failure(hapd, dev[0])
8898
8899 def test_wps_ext_wsc_done_no_r_nonce(dev, apdev):
8900     """WPS proto: WSC_Done without r_nonce"""
8901     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8902
8903     logger.debug("Send WSC_Done to AP")
8904     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8905     attrs += build_attr_msg_type(WPS_WSC_DONE)
8906     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8907     #attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8908     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8909     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8910
8911     wps_wait_eap_failure(hapd, dev[0])
8912
8913 def test_wps_ext_m7_no_encr_settings(dev, apdev):
8914     """WPS proto: M7 without Encr Settings"""
8915     pin = "12345670"
8916     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8917     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8918     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8919
8920     logger.debug("Receive WSC/Start from AP")
8921     msg = get_wsc_msg(hapd)
8922     if msg['wsc_opcode'] != WSC_Start:
8923         raise Exception("Unexpected Op-Code for WSC/Start")
8924
8925     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8926     uuid_e = 16*'\x11'
8927     e_nonce = 16*'\x22'
8928     own_private, e_pk = wsc_dh_init()
8929
8930     logger.debug("Send M1 to AP")
8931     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8932                                 e_nonce, e_pk)
8933     send_wsc_msg(hapd, addr, m1)
8934
8935     logger.debug("Receive M2 from AP")
8936     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8937     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8938     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8939
8940     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8941                                     r_nonce)
8942     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8943
8944     logger.debug("Send M3 to AP")
8945     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8946     attrs += build_attr_msg_type(WPS_M3)
8947     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8948     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8949     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8950     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8951     raw_m3_attrs = attrs
8952     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8953     send_wsc_msg(hapd, addr, m3)
8954
8955     logger.debug("Receive M4 from AP")
8956     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8957
8958     logger.debug("Send M5 to AP")
8959     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8960     attrs += build_attr_msg_type(WPS_M5)
8961     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8962     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8963     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8964     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8965     raw_m5_attrs = attrs
8966     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8967     send_wsc_msg(hapd, addr, m5)
8968
8969     logger.debug("Receive M6 from AP")
8970     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8971
8972     logger.debug("Send M7 to AP")
8973     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8974     attrs += build_attr_msg_type(WPS_M7)
8975     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8976     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8977     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8978     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8979     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8980     raw_m7_attrs = attrs
8981     send_wsc_msg(hapd, addr, m7)
8982
8983     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8984
8985 def test_wps_ext_m1_workaround(dev, apdev):
8986     """WPS proto: M1 Manufacturer/Model workaround"""
8987     pin = "12345670"
8988     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8989     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8990     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8991
8992     logger.debug("Receive WSC/Start from AP")
8993     msg = get_wsc_msg(hapd)
8994     if msg['wsc_opcode'] != WSC_Start:
8995         raise Exception("Unexpected Op-Code for WSC/Start")
8996
8997     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8998     uuid_e = 16*'\x11'
8999     e_nonce = 16*'\x22'
9000     own_private, e_pk = wsc_dh_init()
9001
9002     logger.debug("Send M1 to AP")
9003     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
9004                                 e_nonce, e_pk, manufacturer='Apple TEST',
9005                                 model_name='AirPort', config_methods='\xff\xff')
9006     send_wsc_msg(hapd, addr, m1)
9007
9008     logger.debug("Receive M2 from AP")
9009     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)