bfef895be1419407c02a3d4f24e76a53c3513cc3
[mech_eap.git] / tests / hwsim / test_ap_wps.py
1 # WPS tests
2 # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
3 #
4 # This software may be distributed under the terms of the BSD license.
5 # See README for more details.
6
7 import base64
8 import binascii
9 from Crypto.Cipher import AES
10 import hashlib
11 import hmac
12 import os
13 import time
14 import stat
15 import subprocess
16 import logging
17 logger = logging.getLogger()
18 import re
19 import socket
20 import struct
21 import httplib
22 import urlparse
23 import urllib
24 import xml.etree.ElementTree as ET
25 import StringIO
26 import SocketServer
27
28 import hwsim_utils
29 import hostapd
30 from wpasupplicant import WpaSupplicant
31 from utils import HwsimSkip, alloc_fail, fail_test, skip_with_fips
32
33 def wps_start_ap(apdev, ssid="test-wps-conf"):
34     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
35                "wpa_passphrase": "12345678", "wpa": "2",
36                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
37     return hostapd.add_ap(apdev['ifname'], params)
38
39 def test_ap_wps_init(dev, apdev):
40     """Initial AP configuration with first WPS Enrollee"""
41     ssid = "test-wps"
42     hostapd.add_ap(apdev[0]['ifname'],
43                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
44     hapd = hostapd.Hostapd(apdev[0]['ifname'])
45     logger.info("WPS provisioning step")
46     hapd.request("WPS_PBC")
47     if "PBC Status: Active" not in hapd.request("WPS_GET_STATUS"):
48         raise Exception("PBC status not shown correctly")
49
50     id = dev[0].add_network()
51     dev[0].set_network_quoted(id, "ssid", "home")
52     dev[0].set_network_quoted(id, "psk", "12345678")
53     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
54
55     id = dev[0].add_network()
56     dev[0].set_network_quoted(id, "ssid", "home2")
57     dev[0].set_network(id, "bssid", "00:11:22:33:44:55")
58     dev[0].set_network(id, "key_mgmt", "NONE")
59     dev[0].request("ENABLE_NETWORK %s no-connect" % id)
60
61     dev[0].request("WPS_PBC")
62     dev[0].wait_connected(timeout=30)
63     status = dev[0].get_status()
64     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
65         raise Exception("Not fully connected")
66     if status['ssid'] != ssid:
67         raise Exception("Unexpected SSID")
68     if status['pairwise_cipher'] != 'CCMP':
69         raise Exception("Unexpected encryption configuration")
70     if status['key_mgmt'] != 'WPA2-PSK':
71         raise Exception("Unexpected key_mgmt")
72
73     status = hapd.request("WPS_GET_STATUS")
74     if "PBC Status: Disabled" not in status:
75         raise Exception("PBC status not shown correctly")
76     if "Last WPS result: Success" not in status:
77         raise Exception("Last WPS result not shown correctly")
78     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
79         raise Exception("Peer address not shown correctly")
80     conf = hapd.request("GET_CONFIG")
81     if "wps_state=configured" not in conf:
82         raise Exception("AP not in WPS configured state")
83     if "wpa=3" not in conf:
84         raise Exception("AP not in WPA+WPA2 configuration")
85     if "rsn_pairwise_cipher=CCMP TKIP" not in conf:
86         raise Exception("Unexpected rsn_pairwise_cipher")
87     if "wpa_pairwise_cipher=CCMP TKIP" not in conf:
88         raise Exception("Unexpected wpa_pairwise_cipher")
89     if "group_cipher=TKIP" not in conf:
90         raise Exception("Unexpected group_cipher")
91
92     if len(dev[0].list_networks()) != 3:
93         raise Exception("Unexpected number of network blocks")
94
95 def test_ap_wps_init_2ap_pbc(dev, apdev):
96     """Initial two-radio AP configuration with first WPS PBC Enrollee"""
97     ssid = "test-wps"
98     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
99     hostapd.add_ap(apdev[0]['ifname'], params)
100     hostapd.add_ap(apdev[1]['ifname'], params)
101     hapd = hostapd.Hostapd(apdev[0]['ifname'])
102     logger.info("WPS provisioning step")
103     hapd.request("WPS_PBC")
104     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
105     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
106     bss = dev[0].get_bss(apdev[0]['bssid'])
107     if "[WPS-PBC]" not in bss['flags']:
108         raise Exception("WPS-PBC flag missing from AP1")
109     bss = dev[0].get_bss(apdev[1]['bssid'])
110     if "[WPS-PBC]" not in bss['flags']:
111         raise Exception("WPS-PBC flag missing from AP2")
112     dev[0].dump_monitor()
113     dev[0].request("SET wps_cred_processing 2")
114     dev[0].request("WPS_PBC")
115     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=30)
116     dev[0].request("SET wps_cred_processing 0")
117     if ev is None:
118         raise Exception("WPS cred event not seen")
119     if "100e" not in ev:
120         raise Exception("WPS attributes not included in the cred event")
121     dev[0].wait_connected(timeout=30)
122
123     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
124     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
125     bss = dev[1].get_bss(apdev[0]['bssid'])
126     if "[WPS-PBC]" in bss['flags']:
127         raise Exception("WPS-PBC flag not cleared from AP1")
128     bss = dev[1].get_bss(apdev[1]['bssid'])
129     if "[WPS-PBC]" in bss['flags']:
130         raise Exception("WPS-PBC flag not cleared from AP2")
131
132 def test_ap_wps_init_2ap_pin(dev, apdev):
133     """Initial two-radio AP configuration with first WPS PIN Enrollee"""
134     ssid = "test-wps"
135     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
136     hostapd.add_ap(apdev[0]['ifname'], params)
137     hostapd.add_ap(apdev[1]['ifname'], params)
138     hapd = hostapd.Hostapd(apdev[0]['ifname'])
139     logger.info("WPS provisioning step")
140     pin = dev[0].wps_read_pin()
141     hapd.request("WPS_PIN any " + pin)
142     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
143     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
144     bss = dev[0].get_bss(apdev[0]['bssid'])
145     if "[WPS-AUTH]" not in bss['flags']:
146         raise Exception("WPS-AUTH flag missing from AP1")
147     bss = dev[0].get_bss(apdev[1]['bssid'])
148     if "[WPS-AUTH]" not in bss['flags']:
149         raise Exception("WPS-AUTH flag missing from AP2")
150     dev[0].dump_monitor()
151     dev[0].request("WPS_PIN any " + pin)
152     dev[0].wait_connected(timeout=30)
153
154     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
155     dev[1].scan_for_bss(apdev[1]['bssid'], freq="2412")
156     bss = dev[1].get_bss(apdev[0]['bssid'])
157     if "[WPS-AUTH]" in bss['flags']:
158         raise Exception("WPS-AUTH flag not cleared from AP1")
159     bss = dev[1].get_bss(apdev[1]['bssid'])
160     if "[WPS-AUTH]" in bss['flags']:
161         raise Exception("WPS-AUTH flag not cleared from AP2")
162
163 def test_ap_wps_init_through_wps_config(dev, apdev):
164     """Initial AP configuration using wps_config command"""
165     ssid = "test-wps-init-config"
166     hostapd.add_ap(apdev[0]['ifname'],
167                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
168     hapd = hostapd.Hostapd(apdev[0]['ifname'])
169     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
170         raise Exception("WPS_CONFIG command failed")
171     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
172     if ev is None:
173         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
174     # It takes some time for the AP to update Beacon and Probe Response frames,
175     # so wait here before requesting the scan to be started to avoid adding
176     # extra five second wait to the test due to fetching obsolete scan results.
177     hapd.ping()
178     time.sleep(0.2)
179     dev[0].connect(ssid, psk="12345678", scan_freq="2412", proto="WPA2",
180                    pairwise="CCMP", group="CCMP")
181
182 def test_ap_wps_init_through_wps_config_2(dev, apdev):
183     """AP configuration using wps_config and wps_cred_processing=2"""
184     ssid = "test-wps-init-config"
185     hostapd.add_ap(apdev[0]['ifname'],
186                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
187                      "wps_cred_processing": "2" })
188     hapd = hostapd.Hostapd(apdev[0]['ifname'])
189     if "FAIL" in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "12345678".encode("hex")):
190         raise Exception("WPS_CONFIG command failed")
191     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
192     if ev is None:
193         raise Exception("Timeout on WPS-NEW-AP-SETTINGS events")
194     if "100e" not in ev:
195         raise Exception("WPS-NEW-AP-SETTINGS did not include Credential")
196
197 def test_ap_wps_invalid_wps_config_passphrase(dev, apdev):
198     """AP configuration using wps_config command with invalid passphrase"""
199     ssid = "test-wps-init-config"
200     hostapd.add_ap(apdev[0]['ifname'],
201                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
202     hapd = hostapd.Hostapd(apdev[0]['ifname'])
203     if "FAIL" not in hapd.request("WPS_CONFIG " + ssid.encode("hex") + " WPA2PSK CCMP " + "1234567".encode("hex")):
204         raise Exception("Invalid WPS_CONFIG command accepted")
205
206 def test_ap_wps_conf(dev, apdev):
207     """WPS PBC provisioning with configured AP"""
208     ssid = "test-wps-conf"
209     hostapd.add_ap(apdev[0]['ifname'],
210                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
211                      "wpa_passphrase": "12345678", "wpa": "2",
212                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
213     hapd = hostapd.Hostapd(apdev[0]['ifname'])
214     logger.info("WPS provisioning step")
215     hapd.request("WPS_PBC")
216     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
217     dev[0].dump_monitor()
218     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
219     dev[0].wait_connected(timeout=30)
220     status = dev[0].get_status()
221     if status['wpa_state'] != 'COMPLETED':
222         raise Exception("Not fully connected")
223     if status['bssid'] != apdev[0]['bssid']:
224         raise Exception("Unexpected BSSID")
225     if status['ssid'] != ssid:
226         raise Exception("Unexpected SSID")
227     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
228         raise Exception("Unexpected encryption configuration")
229     if status['key_mgmt'] != 'WPA2-PSK':
230         raise Exception("Unexpected key_mgmt")
231
232     sta = hapd.get_sta(dev[0].p2p_interface_addr())
233     if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
234         raise Exception("Device name not available in STA command")
235
236 def test_ap_wps_conf_5ghz(dev, apdev):
237     """WPS PBC provisioning with configured AP on 5 GHz band"""
238     try:
239         hapd = None
240         ssid = "test-wps-conf"
241         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
242                    "wpa_passphrase": "12345678", "wpa": "2",
243                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
244                    "country_code": "FI", "hw_mode": "a", "channel": "36" }
245         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
246         logger.info("WPS provisioning step")
247         hapd.request("WPS_PBC")
248         dev[0].scan_for_bss(apdev[0]['bssid'], freq="5180")
249         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
250         dev[0].wait_connected(timeout=30)
251
252         sta = hapd.get_sta(dev[0].p2p_interface_addr())
253         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
254             raise Exception("Device name not available in STA command")
255     finally:
256         dev[0].request("DISCONNECT")
257         if hapd:
258             hapd.request("DISABLE")
259         subprocess.call(['iw', 'reg', 'set', '00'])
260         dev[0].flush_scan_cache()
261
262 def test_ap_wps_conf_chan14(dev, apdev):
263     """WPS PBC provisioning with configured AP on channel 14"""
264     try:
265         hapd = None
266         ssid = "test-wps-conf"
267         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
268                    "wpa_passphrase": "12345678", "wpa": "2",
269                    "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
270                    "country_code": "JP", "hw_mode": "b", "channel": "14" }
271         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
272         logger.info("WPS provisioning step")
273         hapd.request("WPS_PBC")
274         dev[0].request("WPS_PBC")
275         dev[0].wait_connected(timeout=30)
276
277         sta = hapd.get_sta(dev[0].p2p_interface_addr())
278         if 'wpsDeviceName' not in sta or sta['wpsDeviceName'] != "Device A":
279             raise Exception("Device name not available in STA command")
280     finally:
281         dev[0].request("DISCONNECT")
282         if hapd:
283             hapd.request("DISABLE")
284         subprocess.call(['iw', 'reg', 'set', '00'])
285         dev[0].flush_scan_cache()
286
287 def test_ap_wps_twice(dev, apdev):
288     """WPS provisioning with twice to change passphrase"""
289     ssid = "test-wps-twice"
290     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
291                "wpa_passphrase": "12345678", "wpa": "2",
292                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" }
293     hostapd.add_ap(apdev[0]['ifname'], params)
294     hapd = hostapd.Hostapd(apdev[0]['ifname'])
295     logger.info("WPS provisioning step")
296     hapd.request("WPS_PBC")
297     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
298     dev[0].dump_monitor()
299     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
300     dev[0].wait_connected(timeout=30)
301     dev[0].request("DISCONNECT")
302
303     logger.info("Restart AP with different passphrase and re-run WPS")
304     hapd_global = hostapd.HostapdGlobal()
305     hapd_global.remove(apdev[0]['ifname'])
306     params['wpa_passphrase'] = 'another passphrase'
307     hostapd.add_ap(apdev[0]['ifname'], params)
308     hapd = hostapd.Hostapd(apdev[0]['ifname'])
309     logger.info("WPS provisioning step")
310     hapd.request("WPS_PBC")
311     dev[0].dump_monitor()
312     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
313     dev[0].wait_connected(timeout=30)
314     networks = dev[0].list_networks()
315     if len(networks) > 1:
316         raise Exception("Unexpected duplicated network block present")
317
318 def test_ap_wps_incorrect_pin(dev, apdev):
319     """WPS PIN provisioning with incorrect PIN"""
320     ssid = "test-wps-incorrect-pin"
321     hostapd.add_ap(apdev[0]['ifname'],
322                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
323                      "wpa_passphrase": "12345678", "wpa": "2",
324                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
325     hapd = hostapd.Hostapd(apdev[0]['ifname'])
326
327     logger.info("WPS provisioning attempt 1")
328     hapd.request("WPS_PIN any 12345670")
329     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
330     dev[0].dump_monitor()
331     dev[0].request("WPS_PIN %s 55554444" % apdev[0]['bssid'])
332     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
333     if ev is None:
334         raise Exception("WPS operation timed out")
335     if "config_error=18" not in ev:
336         raise Exception("Incorrect config_error reported")
337     if "msg=8" not in ev:
338         raise Exception("PIN error detected on incorrect message")
339     dev[0].wait_disconnected(timeout=10)
340     dev[0].request("WPS_CANCEL")
341     # if a scan was in progress, wait for it to complete before trying WPS again
342     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
343
344     status = hapd.request("WPS_GET_STATUS")
345     if "Last WPS result: Failed" not in status:
346         raise Exception("WPS failure result not shown correctly")
347
348     logger.info("WPS provisioning attempt 2")
349     hapd.request("WPS_PIN any 12345670")
350     dev[0].dump_monitor()
351     dev[0].request("WPS_PIN %s 12344444" % apdev[0]['bssid'])
352     ev = dev[0].wait_event(["WPS-FAIL"], timeout=30)
353     if ev is None:
354         raise Exception("WPS operation timed out")
355     if "config_error=18" not in ev:
356         raise Exception("Incorrect config_error reported")
357     if "msg=10" not in ev:
358         raise Exception("PIN error detected on incorrect message")
359     dev[0].wait_disconnected(timeout=10)
360
361 def test_ap_wps_conf_pin(dev, apdev):
362     """WPS PIN provisioning with configured AP"""
363     ssid = "test-wps-conf-pin"
364     hostapd.add_ap(apdev[0]['ifname'],
365                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
366                      "wpa_passphrase": "12345678", "wpa": "2",
367                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
368     hapd = hostapd.Hostapd(apdev[0]['ifname'])
369     logger.info("WPS provisioning step")
370     pin = dev[0].wps_read_pin()
371     hapd.request("WPS_PIN any " + pin)
372     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
373     dev[0].dump_monitor()
374     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
375     dev[0].wait_connected(timeout=30)
376     status = dev[0].get_status()
377     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
378         raise Exception("Not fully connected")
379     if status['ssid'] != ssid:
380         raise Exception("Unexpected SSID")
381     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
382         raise Exception("Unexpected encryption configuration")
383     if status['key_mgmt'] != 'WPA2-PSK':
384         raise Exception("Unexpected key_mgmt")
385
386     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
387     bss = dev[1].get_bss(apdev[0]['bssid'])
388     if "[WPS-AUTH]" in bss['flags']:
389         raise Exception("WPS-AUTH flag not cleared")
390     logger.info("Try to connect from another station using the same PIN")
391     pin = dev[1].request("WPS_PIN " + apdev[0]['bssid'])
392     ev = dev[1].wait_event(["WPS-M2D","CTRL-EVENT-CONNECTED"], timeout=30)
393     if ev is None:
394         raise Exception("Operation timed out")
395     if "WPS-M2D" not in ev:
396         raise Exception("Unexpected WPS operation started")
397     hapd.request("WPS_PIN any " + pin)
398     dev[1].wait_connected(timeout=30)
399
400 def test_ap_wps_conf_pin_v1(dev, apdev):
401     """WPS PIN provisioning with configured WPS v1.0 AP"""
402     ssid = "test-wps-conf-pin-v1"
403     hostapd.add_ap(apdev[0]['ifname'],
404                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
405                      "wpa_passphrase": "12345678", "wpa": "2",
406                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
407     hapd = hostapd.Hostapd(apdev[0]['ifname'])
408     logger.info("WPS provisioning step")
409     pin = dev[0].wps_read_pin()
410     hapd.request("SET wps_version_number 0x10")
411     hapd.request("WPS_PIN any " + pin)
412     found = False
413     for i in range(0, 10):
414         dev[0].scan(freq="2412")
415         if "[WPS-PIN]" in dev[0].request("SCAN_RESULTS"):
416             found = True
417             break
418     if not found:
419         hapd.request("SET wps_version_number 0x20")
420         raise Exception("WPS-PIN flag not seen in scan results")
421     dev[0].dump_monitor()
422     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
423     dev[0].wait_connected(timeout=30)
424     hapd.request("SET wps_version_number 0x20")
425
426 def test_ap_wps_conf_pin_2sta(dev, apdev):
427     """Two stations trying to use WPS PIN at the same time"""
428     ssid = "test-wps-conf-pin2"
429     hostapd.add_ap(apdev[0]['ifname'],
430                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
431                      "wpa_passphrase": "12345678", "wpa": "2",
432                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
433     hapd = hostapd.Hostapd(apdev[0]['ifname'])
434     logger.info("WPS provisioning step")
435     pin = "12345670"
436     pin2 = "55554444"
437     hapd.request("WPS_PIN " + dev[0].get_status_field("uuid") + " " + pin)
438     hapd.request("WPS_PIN " + dev[1].get_status_field("uuid") + " " + pin)
439     dev[0].dump_monitor()
440     dev[1].dump_monitor()
441     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
442     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
443     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
444     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
445     dev[0].wait_connected(timeout=30)
446     dev[1].wait_connected(timeout=30)
447
448 def test_ap_wps_conf_pin_timeout(dev, apdev):
449     """WPS PIN provisioning with configured AP timing out PIN"""
450     ssid = "test-wps-conf-pin"
451     hostapd.add_ap(apdev[0]['ifname'],
452                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
453                      "wpa_passphrase": "12345678", "wpa": "2",
454                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
455     hapd = hostapd.Hostapd(apdev[0]['ifname'])
456     addr = dev[0].p2p_interface_addr()
457     pin = dev[0].wps_read_pin()
458     if "FAIL" not in hapd.request("WPS_PIN "):
459         raise Exception("Unexpected success on invalid WPS_PIN")
460     hapd.request("WPS_PIN any " + pin + " 1")
461     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
462     time.sleep(1.1)
463     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
464     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=20)
465     if ev is None:
466         raise Exception("WPS-PIN-NEEDED event timed out")
467     ev = dev[0].wait_event(["WPS-M2D"])
468     if ev is None:
469         raise Exception("M2D not reported")
470     dev[0].request("WPS_CANCEL")
471
472     hapd.request("WPS_PIN any " + pin + " 20 " + addr)
473     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
474     dev[0].wait_connected(timeout=30)
475
476 def test_ap_wps_reg_connect(dev, apdev):
477     """WPS registrar using AP PIN to connect"""
478     ssid = "test-wps-reg-ap-pin"
479     appin = "12345670"
480     hostapd.add_ap(apdev[0]['ifname'],
481                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
482                      "wpa_passphrase": "12345678", "wpa": "2",
483                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
484                      "ap_pin": appin})
485     logger.info("WPS provisioning step")
486     dev[0].dump_monitor()
487     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
488     dev[0].wps_reg(apdev[0]['bssid'], appin)
489     status = dev[0].get_status()
490     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
491         raise Exception("Not fully connected")
492     if status['ssid'] != ssid:
493         raise Exception("Unexpected SSID")
494     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
495         raise Exception("Unexpected encryption configuration")
496     if status['key_mgmt'] != 'WPA2-PSK':
497         raise Exception("Unexpected key_mgmt")
498
499 def test_ap_wps_reg_connect_mixed_mode(dev, apdev):
500     """WPS registrar using AP PIN to connect (WPA+WPA2)"""
501     ssid = "test-wps-reg-ap-pin"
502     appin = "12345670"
503     hostapd.add_ap(apdev[0]['ifname'],
504                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
505                      "wpa_passphrase": "12345678", "wpa": "3",
506                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
507                      "wpa_pairwise": "TKIP", "ap_pin": appin})
508     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
509     dev[0].wps_reg(apdev[0]['bssid'], appin)
510     status = dev[0].get_status()
511     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
512         raise Exception("Not fully connected")
513     if status['ssid'] != ssid:
514         raise Exception("Unexpected SSID")
515     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
516         raise Exception("Unexpected encryption configuration")
517     if status['key_mgmt'] != 'WPA2-PSK':
518         raise Exception("Unexpected key_mgmt")
519
520 def test_ap_wps_reg_override_ap_settings(dev, apdev):
521     """WPS registrar and ap_settings override"""
522     ap_settings = "/tmp/ap_wps_reg_override_ap_settings"
523     try:
524         os.remove(ap_settings)
525     except:
526         pass
527     # Override AP Settings with values that point to another AP
528     data = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
529     data += build_wsc_attr(ATTR_SSID, "test")
530     data += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
531     data += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
532     data += build_wsc_attr(ATTR_NETWORK_KEY, '')
533     data += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[1]['bssid'].replace(':', '')))
534     with open(ap_settings, "w") as f:
535         f.write(data)
536     ssid = "test-wps-reg-ap-pin"
537     appin = "12345670"
538     hostapd.add_ap(apdev[0]['ifname'],
539                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
540                      "wpa_passphrase": "12345678", "wpa": "2",
541                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
542                      "ap_pin": appin, "ap_settings": ap_settings })
543     hapd2 = hostapd.add_ap(apdev[1]['ifname'], { "ssid": "test" })
544     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
545     dev[0].scan_for_bss(apdev[1]['bssid'], freq=2412)
546     dev[0].wps_reg(apdev[0]['bssid'], appin)
547     ev = hapd2.wait_event(['AP-STA-CONNECTED'], timeout=10)
548     os.remove(ap_settings)
549     if ev is None:
550         raise Exception("No connection with the other AP")
551
552 def check_wps_reg_failure(dev, ap, appin):
553     dev.request("WPS_REG " + ap['bssid'] + " " + appin)
554     ev = dev.wait_event(["WPS-SUCCESS", "WPS-FAIL"], timeout=15)
555     if ev is None:
556         raise Exception("WPS operation timed out")
557     if "WPS-SUCCESS" in ev:
558         raise Exception("WPS operation succeeded unexpectedly")
559     if "config_error=15" not in ev:
560         raise Exception("WPS setup locked state was not reported correctly")
561
562 def test_ap_wps_random_ap_pin(dev, apdev):
563     """WPS registrar using random AP PIN"""
564     ssid = "test-wps-reg-random-ap-pin"
565     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
566     hostapd.add_ap(apdev[0]['ifname'],
567                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
568                      "wpa_passphrase": "12345678", "wpa": "2",
569                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
570                      "device_name": "Wireless AP", "manufacturer": "Company",
571                      "model_name": "WAP", "model_number": "123",
572                      "serial_number": "12345", "device_type": "6-0050F204-1",
573                      "os_version": "01020300",
574                      "config_methods": "label push_button",
575                      "uuid": ap_uuid, "upnp_iface": "lo" })
576     hapd = hostapd.Hostapd(apdev[0]['ifname'])
577     appin = hapd.request("WPS_AP_PIN random")
578     if "FAIL" in appin:
579         raise Exception("Could not generate random AP PIN")
580     if appin not in hapd.request("WPS_AP_PIN get"):
581         raise Exception("Could not fetch current AP PIN")
582     logger.info("WPS provisioning step")
583     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
584     dev[0].wps_reg(apdev[0]['bssid'], appin)
585
586     hapd.request("WPS_AP_PIN disable")
587     logger.info("WPS provisioning step with AP PIN disabled")
588     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
589     check_wps_reg_failure(dev[1], apdev[0], appin)
590
591     logger.info("WPS provisioning step with AP PIN reset")
592     appin = "12345670"
593     hapd.request("WPS_AP_PIN set " + appin)
594     dev[1].wps_reg(apdev[0]['bssid'], appin)
595     dev[0].request("REMOVE_NETWORK all")
596     dev[1].request("REMOVE_NETWORK all")
597     dev[0].wait_disconnected(timeout=10)
598     dev[1].wait_disconnected(timeout=10)
599
600     logger.info("WPS provisioning step after AP PIN timeout")
601     hapd.request("WPS_AP_PIN disable")
602     appin = hapd.request("WPS_AP_PIN random 1")
603     time.sleep(1.1)
604     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
605         raise Exception("AP PIN unexpectedly still enabled")
606     check_wps_reg_failure(dev[0], apdev[0], appin)
607
608     logger.info("WPS provisioning step after AP PIN timeout(2)")
609     hapd.request("WPS_AP_PIN disable")
610     appin = "12345670"
611     hapd.request("WPS_AP_PIN set " + appin + " 1")
612     time.sleep(1.1)
613     if "FAIL" not in hapd.request("WPS_AP_PIN get"):
614         raise Exception("AP PIN unexpectedly still enabled")
615     check_wps_reg_failure(dev[1], apdev[0], appin)
616
617     with fail_test(hapd, 1, "os_get_random;wps_generate_pin"):
618         if "FAIL" in hapd.request("WPS_AP_PIN random 1"):
619             raise Exception("Failed to generate PIN during OOM")
620         hapd.request("WPS_AP_PIN disable")
621
622     with alloc_fail(hapd, 1, "upnp_wps_set_ap_pin"):
623         hapd.request("WPS_AP_PIN set 12345670")
624         hapd.request("WPS_AP_PIN disable")
625
626 def test_ap_wps_reg_config(dev, apdev):
627     """WPS registrar configuring an AP using AP PIN"""
628     ssid = "test-wps-init-ap-pin"
629     appin = "12345670"
630     hostapd.add_ap(apdev[0]['ifname'],
631                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
632                      "ap_pin": appin})
633     logger.info("WPS configuration step")
634     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
635     dev[0].dump_monitor()
636     new_ssid = "wps-new-ssid"
637     new_passphrase = "1234567890"
638     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
639                    new_passphrase)
640     status = dev[0].get_status()
641     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
642         raise Exception("Not fully connected")
643     if status['ssid'] != new_ssid:
644         raise Exception("Unexpected SSID")
645     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
646         raise Exception("Unexpected encryption configuration")
647     if status['key_mgmt'] != 'WPA2-PSK':
648         raise Exception("Unexpected key_mgmt")
649
650     logger.info("Re-configure back to open")
651     dev[0].request("REMOVE_NETWORK all")
652     dev[0].flush_scan_cache()
653     dev[0].dump_monitor()
654     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-open", "OPEN", "NONE", "")
655     status = dev[0].get_status()
656     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
657         raise Exception("Not fully connected")
658     if status['ssid'] != "wps-open":
659         raise Exception("Unexpected SSID")
660     if status['key_mgmt'] != 'NONE':
661         raise Exception("Unexpected key_mgmt")
662
663 def test_ap_wps_reg_config_ext_processing(dev, apdev):
664     """WPS registrar configuring an AP with external config processing"""
665     ssid = "test-wps-init-ap-pin"
666     appin = "12345670"
667     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
668                "wps_cred_processing": "1", "ap_pin": appin}
669     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
670     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
671     new_ssid = "wps-new-ssid"
672     new_passphrase = "1234567890"
673     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
674                    new_passphrase, no_wait=True)
675     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
676     if ev is None:
677         raise Exception("WPS registrar operation timed out")
678     ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=15)
679     if ev is None:
680         raise Exception("WPS configuration timed out")
681     if "1026" not in ev:
682         raise Exception("AP Settings missing from event")
683     hapd.request("SET wps_cred_processing 0")
684     if "FAIL" in hapd.request("WPS_CONFIG " + new_ssid.encode("hex") + " WPA2PSK CCMP " + new_passphrase.encode("hex")):
685         raise Exception("WPS_CONFIG command failed")
686     dev[0].wait_connected(timeout=15)
687
688 def test_ap_wps_reg_config_tkip(dev, apdev):
689     """WPS registrar configuring AP to use TKIP and AP upgrading to TKIP+CCMP"""
690     skip_with_fips(dev[0])
691     ssid = "test-wps-init-ap"
692     appin = "12345670"
693     hostapd.add_ap(apdev[0]['ifname'],
694                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
695                      "ap_pin": appin})
696     logger.info("WPS configuration step")
697     dev[0].request("SET wps_version_number 0x10")
698     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
699     dev[0].dump_monitor()
700     new_ssid = "wps-new-ssid-with-tkip"
701     new_passphrase = "1234567890"
702     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPAPSK", "TKIP",
703                    new_passphrase)
704     logger.info("Re-connect to verify WPA2 mixed mode")
705     dev[0].request("DISCONNECT")
706     id = 0
707     dev[0].set_network(id, "pairwise", "CCMP")
708     dev[0].set_network(id, "proto", "RSN")
709     dev[0].connect_network(id)
710     status = dev[0].get_status()
711     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
712         raise Exception("Not fully connected: wpa_state={} bssid={}".format(status['wpa_state'], status['bssid']))
713     if status['ssid'] != new_ssid:
714         raise Exception("Unexpected SSID")
715     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
716         raise Exception("Unexpected encryption configuration")
717     if status['key_mgmt'] != 'WPA2-PSK':
718         raise Exception("Unexpected key_mgmt")
719
720 def test_ap_wps_setup_locked(dev, apdev):
721     """WPS registrar locking up AP setup on AP PIN failures"""
722     ssid = "test-wps-incorrect-ap-pin"
723     appin = "12345670"
724     hostapd.add_ap(apdev[0]['ifname'],
725                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
726                      "wpa_passphrase": "12345678", "wpa": "2",
727                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
728                      "ap_pin": appin})
729     new_ssid = "wps-new-ssid-test"
730     new_passphrase = "1234567890"
731
732     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
733     ap_setup_locked=False
734     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
735         dev[0].dump_monitor()
736         logger.info("Try incorrect AP PIN - attempt " + pin)
737         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
738                        "CCMP", new_passphrase, no_wait=True)
739         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
740         if ev is None:
741             raise Exception("Timeout on receiving WPS operation failure event")
742         if "CTRL-EVENT-CONNECTED" in ev:
743             raise Exception("Unexpected connection")
744         if "config_error=15" in ev:
745             logger.info("AP Setup Locked")
746             ap_setup_locked=True
747         elif "config_error=18" not in ev:
748             raise Exception("config_error=18 not reported")
749         dev[0].wait_disconnected(timeout=10)
750         time.sleep(0.1)
751     if not ap_setup_locked:
752         raise Exception("AP setup was not locked")
753     dev[0].request("WPS_CANCEL")
754     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True,
755                         only_new=True)
756     bss = dev[0].get_bss(apdev[0]['bssid'])
757     if 'wps_ap_setup_locked' not in bss or bss['wps_ap_setup_locked'] != '1':
758         logger.info("BSS: " + str(bss))
759         raise Exception("AP Setup Locked not indicated in scan results")
760
761     hapd = hostapd.Hostapd(apdev[0]['ifname'])
762     status = hapd.request("WPS_GET_STATUS")
763     if "Last WPS result: Failed" not in status:
764         raise Exception("WPS failure result not shown correctly")
765     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
766         raise Exception("Peer address not shown correctly")
767
768     time.sleep(0.5)
769     dev[0].dump_monitor()
770     logger.info("WPS provisioning step")
771     pin = dev[0].wps_read_pin()
772     hapd = hostapd.Hostapd(apdev[0]['ifname'])
773     hapd.request("WPS_PIN any " + pin)
774     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
775     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
776     if ev is None:
777         raise Exception("WPS success was not reported")
778     dev[0].wait_connected(timeout=30)
779
780     appin = hapd.request("WPS_AP_PIN random")
781     if "FAIL" in appin:
782         raise Exception("Could not generate random AP PIN")
783     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=10)
784     if ev is None:
785         raise Exception("Failed to unlock AP PIN")
786
787 def test_ap_wps_setup_locked_timeout(dev, apdev):
788     """WPS re-enabling AP PIN after timeout"""
789     ssid = "test-wps-incorrect-ap-pin"
790     appin = "12345670"
791     hostapd.add_ap(apdev[0]['ifname'],
792                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
793                      "wpa_passphrase": "12345678", "wpa": "2",
794                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
795                      "ap_pin": appin})
796     new_ssid = "wps-new-ssid-test"
797     new_passphrase = "1234567890"
798
799     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
800     ap_setup_locked=False
801     for pin in ["55554444", "1234", "12345678", "00000000", "11111111"]:
802         dev[0].dump_monitor()
803         logger.info("Try incorrect AP PIN - attempt " + pin)
804         dev[0].wps_reg(apdev[0]['bssid'], pin, new_ssid, "WPA2PSK",
805                        "CCMP", new_passphrase, no_wait=True)
806         ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"], timeout=15)
807         if ev is None:
808             raise Exception("Timeout on receiving WPS operation failure event")
809         if "CTRL-EVENT-CONNECTED" in ev:
810             raise Exception("Unexpected connection")
811         if "config_error=15" in ev:
812             logger.info("AP Setup Locked")
813             ap_setup_locked=True
814             break
815         elif "config_error=18" not in ev:
816             raise Exception("config_error=18 not reported")
817         dev[0].wait_disconnected(timeout=10)
818         time.sleep(0.1)
819     if not ap_setup_locked:
820         raise Exception("AP setup was not locked")
821     hapd = hostapd.Hostapd(apdev[0]['ifname'])
822     ev = hapd.wait_event(["WPS-AP-SETUP-UNLOCKED"], timeout=80)
823     if ev is None:
824         raise Exception("AP PIN did not get unlocked on 60 second timeout")
825
826 def test_ap_wps_setup_locked_2(dev, apdev):
827     """WPS AP configured for special ap_setup_locked=2 mode"""
828     ssid = "test-wps-ap-pin"
829     appin = "12345670"
830     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
831                "wpa_passphrase": "12345678", "wpa": "2",
832                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
833                "ap_pin": appin, "ap_setup_locked": "2" }
834     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
835     new_ssid = "wps-new-ssid-test"
836     new_passphrase = "1234567890"
837
838     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
839     dev[0].wps_reg(apdev[0]['bssid'], appin)
840     dev[0].request("REMOVE_NETWORK all")
841     dev[0].wait_disconnected()
842
843     hapd.dump_monitor()
844     dev[0].dump_monitor()
845     dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK",
846                    "CCMP", new_passphrase, no_wait=True)
847
848     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
849     if ev is None:
850         raise Exception("hostapd did not report WPS failure")
851     if "msg=12 config_error=15" not in ev:
852         raise Exception("Unexpected failure reason (AP): " + ev)
853
854     ev = dev[0].wait_event(["WPS-FAIL", "CTRL-EVENT-CONNECTED"])
855     if ev is None:
856         raise Exception("Timeout on receiving WPS operation failure event")
857     if "CTRL-EVENT-CONNECTED" in ev:
858         raise Exception("Unexpected connection")
859     if "config_error=15" not in ev:
860         raise Exception("Unexpected failure reason (STA): " + ev)
861     dev[0].request("WPS_CANCEL")
862     dev[0].wait_disconnected()
863
864 def test_ap_wps_pbc_overlap_2ap(dev, apdev):
865     """WPS PBC session overlap with two active APs"""
866     hostapd.add_ap(apdev[0]['ifname'],
867                    { "ssid": "wps1", "eap_server": "1", "wps_state": "2",
868                      "wpa_passphrase": "12345678", "wpa": "2",
869                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
870                      "wps_independent": "1"})
871     hostapd.add_ap(apdev[1]['ifname'],
872                    { "ssid": "wps2", "eap_server": "1", "wps_state": "2",
873                      "wpa_passphrase": "123456789", "wpa": "2",
874                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
875                      "wps_independent": "1"})
876     hapd = hostapd.Hostapd(apdev[0]['ifname'])
877     hapd.request("WPS_PBC")
878     hapd2 = hostapd.Hostapd(apdev[1]['ifname'])
879     hapd2.request("WPS_PBC")
880     logger.info("WPS provisioning step")
881     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True)
882     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
883     dev[0].request("WPS_PBC")
884     ev = dev[0].wait_event(["WPS-OVERLAP-DETECTED"], timeout=15)
885     if ev is None:
886         raise Exception("PBC session overlap not detected")
887     hapd.request("DISABLE")
888     hapd2.request("DISABLE")
889     dev[0].flush_scan_cache()
890
891 def test_ap_wps_pbc_overlap_2sta(dev, apdev):
892     """WPS PBC session overlap with two active STAs"""
893     ssid = "test-wps-pbc-overlap"
894     hostapd.add_ap(apdev[0]['ifname'],
895                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
896                      "wpa_passphrase": "12345678", "wpa": "2",
897                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
898     hapd = hostapd.Hostapd(apdev[0]['ifname'])
899     logger.info("WPS provisioning step")
900     hapd.request("WPS_PBC")
901     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
902     dev[0].dump_monitor()
903     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
904     dev[1].dump_monitor()
905     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
906     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
907     ev = dev[0].wait_event(["WPS-M2D"], timeout=15)
908     if ev is None:
909         raise Exception("PBC session overlap not detected (dev0)")
910     if "config_error=12" not in ev:
911         raise Exception("PBC session overlap not correctly reported (dev0)")
912     dev[0].request("WPS_CANCEL")
913     dev[0].request("DISCONNECT")
914     ev = dev[1].wait_event(["WPS-M2D"], timeout=15)
915     if ev is None:
916         raise Exception("PBC session overlap not detected (dev1)")
917     if "config_error=12" not in ev:
918         raise Exception("PBC session overlap not correctly reported (dev1)")
919     dev[1].request("WPS_CANCEL")
920     dev[1].request("DISCONNECT")
921     hapd.request("WPS_CANCEL")
922     ret = hapd.request("WPS_PBC")
923     if "FAIL" not in ret:
924         raise Exception("PBC mode allowed to be started while PBC overlap still active")
925     hapd.request("DISABLE")
926     dev[0].flush_scan_cache()
927     dev[1].flush_scan_cache()
928
929 def test_ap_wps_cancel(dev, apdev):
930     """WPS AP cancelling enabled config method"""
931     ssid = "test-wps-ap-cancel"
932     hostapd.add_ap(apdev[0]['ifname'],
933                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
934                      "wpa_passphrase": "12345678", "wpa": "2",
935                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
936     bssid = apdev[0]['bssid']
937     hapd = hostapd.Hostapd(apdev[0]['ifname'])
938
939     logger.info("Verify PBC enable/cancel")
940     hapd.request("WPS_PBC")
941     dev[0].scan(freq="2412")
942     dev[0].scan(freq="2412")
943     bss = dev[0].get_bss(apdev[0]['bssid'])
944     if "[WPS-PBC]" not in bss['flags']:
945         raise Exception("WPS-PBC flag missing")
946     if "FAIL" in hapd.request("WPS_CANCEL"):
947         raise Exception("WPS_CANCEL failed")
948     dev[0].scan(freq="2412")
949     dev[0].scan(freq="2412")
950     bss = dev[0].get_bss(apdev[0]['bssid'])
951     if "[WPS-PBC]" in bss['flags']:
952         raise Exception("WPS-PBC flag not cleared")
953
954     logger.info("Verify PIN enable/cancel")
955     hapd.request("WPS_PIN any 12345670")
956     dev[0].scan(freq="2412")
957     dev[0].scan(freq="2412")
958     bss = dev[0].get_bss(apdev[0]['bssid'])
959     if "[WPS-AUTH]" not in bss['flags']:
960         raise Exception("WPS-AUTH flag missing")
961     if "FAIL" in hapd.request("WPS_CANCEL"):
962         raise Exception("WPS_CANCEL failed")
963     dev[0].scan(freq="2412")
964     dev[0].scan(freq="2412")
965     bss = dev[0].get_bss(apdev[0]['bssid'])
966     if "[WPS-AUTH]" in bss['flags']:
967         raise Exception("WPS-AUTH flag not cleared")
968
969 def test_ap_wps_er_add_enrollee(dev, apdev):
970     """WPS ER configuring AP and adding a new enrollee using PIN"""
971     try:
972         _test_ap_wps_er_add_enrollee(dev, apdev)
973     finally:
974         dev[0].request("WPS_ER_STOP")
975
976 def _test_ap_wps_er_add_enrollee(dev, apdev):
977     ssid = "wps-er-add-enrollee"
978     ap_pin = "12345670"
979     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
980     hostapd.add_ap(apdev[0]['ifname'],
981                    { "ssid": ssid, "eap_server": "1", "wps_state": "1",
982                      "device_name": "Wireless AP", "manufacturer": "Company",
983                      "model_name": "WAP", "model_number": "123",
984                      "serial_number": "12345", "device_type": "6-0050F204-1",
985                      "os_version": "01020300",
986                      'friendly_name': "WPS AP - <>&'\" - TEST",
987                      "config_methods": "label push_button",
988                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
989     logger.info("WPS configuration step")
990     new_passphrase = "1234567890"
991     dev[0].dump_monitor()
992     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
993     dev[0].wps_reg(apdev[0]['bssid'], ap_pin, ssid, "WPA2PSK", "CCMP",
994                    new_passphrase)
995     status = dev[0].get_status()
996     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
997         raise Exception("Not fully connected")
998     if status['ssid'] != ssid:
999         raise Exception("Unexpected SSID")
1000     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'CCMP':
1001         raise Exception("Unexpected encryption configuration")
1002     if status['key_mgmt'] != 'WPA2-PSK':
1003         raise Exception("Unexpected key_mgmt")
1004
1005     logger.info("Start ER")
1006     dev[0].request("WPS_ER_START ifname=lo")
1007     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1008     if ev is None:
1009         raise Exception("AP discovery timed out")
1010     if ap_uuid not in ev:
1011         raise Exception("Expected AP UUID not found")
1012     if "|WPS AP - &lt;&gt;&amp;&apos;&quot; - TEST|Company|" not in ev:
1013         raise Exception("Expected friendly name not found")
1014
1015     logger.info("Learn AP configuration through UPnP")
1016     dev[0].dump_monitor()
1017     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1018     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1019     if ev is None:
1020         raise Exception("AP learn timed out")
1021     if ap_uuid not in ev:
1022         raise Exception("Expected AP UUID not in settings")
1023     if "ssid=" + ssid not in ev:
1024         raise Exception("Expected SSID not in settings")
1025     if "key=" + new_passphrase not in ev:
1026         raise Exception("Expected passphrase not in settings")
1027     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1028     if ev is None:
1029         raise Exception("WPS-FAIL after AP learn timed out")
1030     time.sleep(0.1)
1031
1032     logger.info("Add Enrollee using ER")
1033     pin = dev[1].wps_read_pin()
1034     dev[0].dump_monitor()
1035     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1036     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1037     dev[1].dump_monitor()
1038     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1039     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1040     if ev is None:
1041         raise Exception("Enrollee did not report success")
1042     dev[1].wait_connected(timeout=15)
1043     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1044     if ev is None:
1045         raise Exception("WPS ER did not report success")
1046     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1047
1048     logger.info("Add a specific Enrollee using ER")
1049     pin = dev[2].wps_read_pin()
1050     addr2 = dev[2].p2p_interface_addr()
1051     dev[0].dump_monitor()
1052     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1053     dev[2].dump_monitor()
1054     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1055     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1056     if ev is None:
1057         raise Exception("Enrollee not seen")
1058     if addr2 not in ev:
1059         raise Exception("Unexpected Enrollee MAC address")
1060     dev[0].request("WPS_ER_PIN " + addr2 + " " + pin + " " + addr2)
1061     dev[2].wait_connected(timeout=30)
1062     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1063     if ev is None:
1064         raise Exception("WPS ER did not report success")
1065
1066     logger.info("Verify registrar selection behavior")
1067     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1068     dev[1].request("DISCONNECT")
1069     dev[1].wait_disconnected(timeout=10)
1070     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1071     dev[1].scan(freq="2412")
1072     bss = dev[1].get_bss(apdev[0]['bssid'])
1073     if "[WPS-AUTH]" not in bss['flags']:
1074         # It is possible for scan to miss an update especially when running
1075         # tests under load with multiple VMs, so allow another attempt.
1076         dev[1].scan(freq="2412")
1077         bss = dev[1].get_bss(apdev[0]['bssid'])
1078         if "[WPS-AUTH]" not in bss['flags']:
1079             raise Exception("WPS-AUTH flag missing")
1080
1081     logger.info("Stop ER")
1082     dev[0].dump_monitor()
1083     dev[0].request("WPS_ER_STOP")
1084     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"])
1085     if ev is None:
1086         raise Exception("WPS ER unsubscription timed out")
1087     # It takes some time for the UPnP UNSUBSCRIBE command to go through, so wait
1088     # a bit before verifying that the scan results have changed.
1089     time.sleep(0.2)
1090
1091     for i in range(0, 10):
1092         dev[1].request("BSS_FLUSH 0")
1093         dev[1].scan(freq="2412", only_new=True)
1094         bss = dev[1].get_bss(apdev[0]['bssid'])
1095         if bss and 'flags' in bss and "[WPS-AUTH]" not in bss['flags']:
1096             break
1097         logger.debug("WPS-AUTH flag was still in place - wait a bit longer")
1098         time.sleep(0.1)
1099     if "[WPS-AUTH]" in bss['flags']:
1100         raise Exception("WPS-AUTH flag not removed")
1101
1102 def test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1103     """WPS ER adding a new enrollee identified by UUID"""
1104     try:
1105         _test_ap_wps_er_add_enrollee_uuid(dev, apdev)
1106     finally:
1107         dev[0].request("WPS_ER_STOP")
1108
1109 def _test_ap_wps_er_add_enrollee_uuid(dev, apdev):
1110     ssid = "wps-er-add-enrollee"
1111     ap_pin = "12345670"
1112     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1113     hostapd.add_ap(apdev[0]['ifname'],
1114                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1115                      "wpa_passphrase": "12345678", "wpa": "2",
1116                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1117                      "device_name": "Wireless AP", "manufacturer": "Company",
1118                      "model_name": "WAP", "model_number": "123",
1119                      "serial_number": "12345", "device_type": "6-0050F204-1",
1120                      "os_version": "01020300",
1121                      "config_methods": "label push_button",
1122                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1123     logger.info("WPS configuration step")
1124     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1125     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1126
1127     logger.info("Start ER")
1128     dev[0].request("WPS_ER_START ifname=lo")
1129     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1130     if ev is None:
1131         raise Exception("AP discovery timed out")
1132     if ap_uuid not in ev:
1133         raise Exception("Expected AP UUID not found")
1134
1135     logger.info("Learn AP configuration through UPnP")
1136     dev[0].dump_monitor()
1137     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1138     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1139     if ev is None:
1140         raise Exception("AP learn timed out")
1141     if ap_uuid not in ev:
1142         raise Exception("Expected AP UUID not in settings")
1143     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1144     if ev is None:
1145         raise Exception("WPS-FAIL after AP learn timed out")
1146     time.sleep(0.1)
1147
1148     logger.info("Add a specific Enrollee using ER (PBC/UUID)")
1149     addr1 = dev[1].p2p_interface_addr()
1150     dev[0].dump_monitor()
1151     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1152     dev[1].dump_monitor()
1153     dev[1].request("WPS_PBC %s" % apdev[0]['bssid'])
1154     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1155     if ev is None:
1156         raise Exception("Enrollee not seen")
1157     if addr1 not in ev:
1158         raise Exception("Unexpected Enrollee MAC address")
1159     uuid = ev.split(' ')[1]
1160     dev[0].request("WPS_ER_PBC " + uuid)
1161     dev[1].wait_connected(timeout=30)
1162     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1163     if ev is None:
1164         raise Exception("WPS ER did not report success")
1165
1166     logger.info("Add a specific Enrollee using ER (PIN/UUID)")
1167     pin = dev[2].wps_read_pin()
1168     addr2 = dev[2].p2p_interface_addr()
1169     dev[0].dump_monitor()
1170     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1171     dev[2].dump_monitor()
1172     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1173     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=10)
1174     if ev is None:
1175         raise Exception("Enrollee not seen")
1176     if addr2 not in ev:
1177         raise Exception("Unexpected Enrollee MAC address")
1178     uuid = ev.split(' ')[1]
1179     dev[0].request("WPS_ER_PIN " + uuid + " " + pin)
1180     dev[2].wait_connected(timeout=30)
1181     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1182     if ev is None:
1183         raise Exception("WPS ER did not report success")
1184
1185     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-REMOVE"], timeout=15)
1186     if ev is None:
1187         raise Exception("No Enrollee STA entry timeout seen")
1188
1189     logger.info("Stop ER")
1190     dev[0].dump_monitor()
1191     dev[0].request("WPS_ER_STOP")
1192
1193 def test_ap_wps_er_multi_add_enrollee(dev, apdev):
1194     """Multiple WPS ERs adding a new enrollee using PIN"""
1195     try:
1196         _test_ap_wps_er_multi_add_enrollee(dev, apdev)
1197     finally:
1198         dev[0].request("WPS_ER_STOP")
1199
1200 def _test_ap_wps_er_multi_add_enrollee(dev, apdev):
1201     ssid = "wps-er-add-enrollee"
1202     ap_pin = "12345670"
1203     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1204     hostapd.add_ap(apdev[0]['ifname'],
1205                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1206                      "wpa_passphrase": "12345678", "wpa": "2",
1207                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1208                      "device_name": "Wireless AP", "manufacturer": "Company",
1209                      "model_name": "WAP", "model_number": "123",
1210                      "serial_number": "12345", "device_type": "6-0050F204-1",
1211                      "os_version": "01020300",
1212                      'friendly_name': "WPS AP",
1213                      "config_methods": "label push_button",
1214                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1215
1216     for i in range(2):
1217         dev[i].scan_for_bss(apdev[0]['bssid'], freq=2412)
1218         dev[i].wps_reg(apdev[0]['bssid'], ap_pin)
1219         dev[i].request("WPS_ER_START ifname=lo")
1220     for i in range(2):
1221         ev = dev[i].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1222         if ev is None:
1223             raise Exception("AP discovery timed out")
1224         dev[i].dump_monitor()
1225         dev[i].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1226         ev = dev[i].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1227         if ev is None:
1228             raise Exception("AP learn timed out")
1229         ev = dev[i].wait_event(["WPS-FAIL"], timeout=15)
1230         if ev is None:
1231             raise Exception("WPS-FAIL after AP learn timed out")
1232
1233     time.sleep(0.1)
1234
1235     pin = dev[2].wps_read_pin()
1236     addr = dev[2].own_addr()
1237     dev[0].dump_monitor()
1238     dev[0].request("WPS_ER_PIN any " + pin + " " + addr)
1239     dev[1].dump_monitor()
1240     dev[1].request("WPS_ER_PIN any " + pin + " " + addr)
1241
1242     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1243     dev[2].dump_monitor()
1244     dev[2].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1245     ev = dev[2].wait_event(["WPS-SUCCESS"], timeout=30)
1246     if ev is None:
1247         raise Exception("Enrollee did not report success")
1248     dev[2].wait_connected(timeout=15)
1249
1250 def test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1251     """WPS ER connected to AP and adding a new enrollee using PBC"""
1252     try:
1253         _test_ap_wps_er_add_enrollee_pbc(dev, apdev)
1254     finally:
1255         dev[0].request("WPS_ER_STOP")
1256
1257 def _test_ap_wps_er_add_enrollee_pbc(dev, apdev):
1258     ssid = "wps-er-add-enrollee-pbc"
1259     ap_pin = "12345670"
1260     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1261     hostapd.add_ap(apdev[0]['ifname'],
1262                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1263                      "wpa_passphrase": "12345678", "wpa": "2",
1264                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1265                      "device_name": "Wireless AP", "manufacturer": "Company",
1266                      "model_name": "WAP", "model_number": "123",
1267                      "serial_number": "12345", "device_type": "6-0050F204-1",
1268                      "os_version": "01020300",
1269                      "config_methods": "label push_button",
1270                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1271     logger.info("Learn AP configuration")
1272     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1273     dev[0].dump_monitor()
1274     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1275     status = dev[0].get_status()
1276     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1277         raise Exception("Not fully connected")
1278
1279     logger.info("Start ER")
1280     dev[0].request("WPS_ER_START ifname=lo")
1281     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1282     if ev is None:
1283         raise Exception("AP discovery timed out")
1284     if ap_uuid not in ev:
1285         raise Exception("Expected AP UUID not found")
1286
1287     enrollee = dev[1].p2p_interface_addr()
1288
1289     if "FAIL-UNKNOWN-UUID" not in dev[0].request("WPS_ER_PBC " + enrollee):
1290         raise Exception("Unknown UUID not reported")
1291
1292     logger.info("Add Enrollee using ER and PBC")
1293     dev[0].dump_monitor()
1294     dev[1].dump_monitor()
1295     dev[1].request("WPS_PBC")
1296
1297     for i in range(0, 2):
1298         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1299         if ev is None:
1300             raise Exception("Enrollee discovery timed out")
1301         if enrollee in ev:
1302             break
1303         if i == 1:
1304             raise Exception("Expected Enrollee not found")
1305     if "FAIL-NO-AP-SETTINGS" not in dev[0].request("WPS_ER_PBC " + enrollee):
1306         raise Exception("Unknown UUID not reported")
1307     logger.info("Use learned network configuration on ER")
1308     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1309     if "OK" not in dev[0].request("WPS_ER_PBC " + enrollee):
1310         raise Exception("WPS_ER_PBC failed")
1311
1312     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=15)
1313     if ev is None:
1314         raise Exception("Enrollee did not report success")
1315     dev[1].wait_connected(timeout=15)
1316     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1317     if ev is None:
1318         raise Exception("WPS ER did not report success")
1319     hwsim_utils.test_connectivity_sta(dev[0], dev[1])
1320
1321 def test_ap_wps_er_pbc_overlap(dev, apdev):
1322     """WPS ER connected to AP and PBC session overlap"""
1323     try:
1324         _test_ap_wps_er_pbc_overlap(dev, apdev)
1325     finally:
1326         dev[0].request("WPS_ER_STOP")
1327
1328 def _test_ap_wps_er_pbc_overlap(dev, apdev):
1329     ssid = "wps-er-add-enrollee-pbc"
1330     ap_pin = "12345670"
1331     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1332     hostapd.add_ap(apdev[0]['ifname'],
1333                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1334                      "wpa_passphrase": "12345678", "wpa": "2",
1335                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1336                      "device_name": "Wireless AP", "manufacturer": "Company",
1337                      "model_name": "WAP", "model_number": "123",
1338                      "serial_number": "12345", "device_type": "6-0050F204-1",
1339                      "os_version": "01020300",
1340                      "config_methods": "label push_button",
1341                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1342     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1343     dev[0].dump_monitor()
1344     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1345
1346     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412")
1347     dev[2].scan_for_bss(apdev[0]['bssid'], freq="2412")
1348     # avoid leaving dev 1 or 2 as the last Probe Request to the AP
1349     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412, force_scan=True)
1350
1351     dev[0].dump_monitor()
1352     dev[0].request("WPS_ER_START ifname=lo")
1353
1354     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1355     if ev is None:
1356         raise Exception("AP discovery timed out")
1357     if ap_uuid not in ev:
1358         raise Exception("Expected AP UUID not found")
1359
1360     # verify BSSID selection of the AP instead of UUID
1361     if "FAIL" in dev[0].request("WPS_ER_SET_CONFIG " + apdev[0]['bssid'] + " 0"):
1362         raise Exception("Could not select AP based on BSSID")
1363
1364     dev[0].dump_monitor()
1365     dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1366     dev[2].request("WPS_PBC " + apdev[0]['bssid'])
1367     ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1368     if ev is None:
1369         raise Exception("PBC scan failed")
1370     ev = dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
1371     if ev is None:
1372         raise Exception("PBC scan failed")
1373     found1 = False
1374     found2 = False
1375     addr1 = dev[1].own_addr()
1376     addr2 = dev[2].own_addr()
1377     for i in range(3):
1378         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
1379         if ev is None:
1380             raise Exception("Enrollee discovery timed out")
1381         if addr1 in ev:
1382             found1 = True
1383             if found2:
1384                 break
1385         if addr2 in ev:
1386             found2 = True
1387             if found1:
1388                 break
1389     if dev[0].request("WPS_ER_PBC " + ap_uuid) != "FAIL-PBC-OVERLAP\n":
1390         raise Exception("PBC overlap not reported")
1391     dev[1].request("WPS_CANCEL")
1392     dev[2].request("WPS_CANCEL")
1393     if dev[0].request("WPS_ER_PBC foo") != "FAIL\n":
1394         raise Exception("Invalid WPS_ER_PBC accepted")
1395
1396 def test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1397     """WPS v1.0 ER connected to AP and adding a new enrollee using PIN"""
1398     try:
1399         _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev)
1400     finally:
1401         dev[0].request("WPS_ER_STOP")
1402
1403 def _test_ap_wps_er_v10_add_enrollee_pin(dev, apdev):
1404     ssid = "wps-er-add-enrollee-pbc"
1405     ap_pin = "12345670"
1406     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1407     hostapd.add_ap(apdev[0]['ifname'],
1408                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1409                      "wpa_passphrase": "12345678", "wpa": "2",
1410                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1411                      "device_name": "Wireless AP", "manufacturer": "Company",
1412                      "model_name": "WAP", "model_number": "123",
1413                      "serial_number": "12345", "device_type": "6-0050F204-1",
1414                      "os_version": "01020300",
1415                      "config_methods": "label push_button",
1416                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1417     logger.info("Learn AP configuration")
1418     dev[0].request("SET wps_version_number 0x10")
1419     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1420     dev[0].dump_monitor()
1421     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1422     status = dev[0].get_status()
1423     if status['wpa_state'] != 'COMPLETED' or status['bssid'] != apdev[0]['bssid']:
1424         raise Exception("Not fully connected")
1425
1426     logger.info("Start ER")
1427     dev[0].request("WPS_ER_START ifname=lo")
1428     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1429     if ev is None:
1430         raise Exception("AP discovery timed out")
1431     if ap_uuid not in ev:
1432         raise Exception("Expected AP UUID not found")
1433
1434     logger.info("Use learned network configuration on ER")
1435     dev[0].request("WPS_ER_SET_CONFIG " + ap_uuid + " 0")
1436
1437     logger.info("Add Enrollee using ER and PIN")
1438     enrollee = dev[1].p2p_interface_addr()
1439     pin = dev[1].wps_read_pin()
1440     dev[0].dump_monitor()
1441     dev[0].request("WPS_ER_PIN any " + pin + " " + enrollee)
1442     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1443     dev[1].dump_monitor()
1444     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1445     dev[1].wait_connected(timeout=30)
1446     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1447     if ev is None:
1448         raise Exception("WPS ER did not report success")
1449
1450 def test_ap_wps_er_config_ap(dev, apdev):
1451     """WPS ER configuring AP over UPnP"""
1452     try:
1453         _test_ap_wps_er_config_ap(dev, apdev)
1454     finally:
1455         dev[0].request("WPS_ER_STOP")
1456
1457 def _test_ap_wps_er_config_ap(dev, apdev):
1458     ssid = "wps-er-ap-config"
1459     ap_pin = "12345670"
1460     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1461     hostapd.add_ap(apdev[0]['ifname'],
1462                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1463                      "wpa_passphrase": "12345678", "wpa": "2",
1464                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1465                      "device_name": "Wireless AP", "manufacturer": "Company",
1466                      "model_name": "WAP", "model_number": "123",
1467                      "serial_number": "12345", "device_type": "6-0050F204-1",
1468                      "os_version": "01020300",
1469                      "config_methods": "label push_button",
1470                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
1471
1472     logger.info("Connect ER to the AP")
1473     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
1474
1475     logger.info("WPS configuration step")
1476     dev[0].request("WPS_ER_START ifname=lo")
1477     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1478     if ev is None:
1479         raise Exception("AP discovery timed out")
1480     if ap_uuid not in ev:
1481         raise Exception("Expected AP UUID not found")
1482     new_passphrase = "1234567890"
1483     dev[0].request("WPS_ER_CONFIG " + apdev[0]['bssid'] + " " + ap_pin + " " +
1484                    ssid.encode("hex") + " WPA2PSK CCMP " +
1485                    new_passphrase.encode("hex"))
1486     ev = dev[0].wait_event(["WPS-SUCCESS"])
1487     if ev is None:
1488         raise Exception("WPS ER configuration operation timed out")
1489     dev[0].wait_disconnected(timeout=10)
1490     dev[0].connect(ssid, psk="1234567890", scan_freq="2412")
1491
1492     logger.info("WPS ER restart")
1493     dev[0].request("WPS_ER_START")
1494     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1495     if ev is None:
1496         raise Exception("AP discovery timed out on ER restart")
1497     if ap_uuid not in ev:
1498         raise Exception("Expected AP UUID not found on ER restart")
1499     if "OK" not in dev[0].request("WPS_ER_STOP"):
1500         raise Exception("WPS_ER_STOP failed")
1501     if "OK" not in dev[0].request("WPS_ER_STOP"):
1502         raise Exception("WPS_ER_STOP failed")
1503
1504 def test_ap_wps_er_cache_ap_settings(dev, apdev):
1505     """WPS ER caching AP settings"""
1506     try:
1507         _test_ap_wps_er_cache_ap_settings(dev, apdev)
1508     finally:
1509         dev[0].request("WPS_ER_STOP")
1510
1511 def _test_ap_wps_er_cache_ap_settings(dev, apdev):
1512     ssid = "wps-er-add-enrollee"
1513     ap_pin = "12345670"
1514     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1515     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1516                "wpa_passphrase": "12345678", "wpa": "2",
1517                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1518                "device_name": "Wireless AP", "manufacturer": "Company",
1519                "model_name": "WAP", "model_number": "123",
1520                "serial_number": "12345", "device_type": "6-0050F204-1",
1521                "os_version": "01020300",
1522                "config_methods": "label push_button",
1523                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1524     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1525     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1526     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1527     id = int(dev[0].list_networks()[0]['id'])
1528     dev[0].set_network(id, "scan_freq", "2412")
1529
1530     dev[0].request("WPS_ER_START ifname=lo")
1531     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1532     if ev is None:
1533         raise Exception("AP discovery timed out")
1534     if ap_uuid not in ev:
1535         raise Exception("Expected AP UUID not found")
1536
1537     dev[0].dump_monitor()
1538     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1539     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1540     if ev is None:
1541         raise Exception("AP learn timed out")
1542     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1543     if ev is None:
1544         raise Exception("WPS-FAIL after AP learn timed out")
1545     time.sleep(0.1)
1546
1547     hapd.disable()
1548
1549     for i in range(2):
1550         ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1551                                  "CTRL-EVENT-DISCONNECTED" ],
1552                                timeout=15)
1553         if ev is None:
1554             raise Exception("AP removal or disconnection timed out")
1555
1556     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1557     for i in range(2):
1558         ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1559                                timeout=15)
1560         if ev is None:
1561             raise Exception("AP discovery or connection timed out")
1562
1563     pin = dev[1].wps_read_pin()
1564     dev[0].dump_monitor()
1565     dev[0].request("WPS_ER_PIN any " + pin + " " + dev[1].p2p_interface_addr())
1566
1567     time.sleep(0.2)
1568
1569     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1570     dev[1].dump_monitor()
1571     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1572     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=30)
1573     if ev is None:
1574         raise Exception("Enrollee did not report success")
1575     dev[1].wait_connected(timeout=15)
1576     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=15)
1577     if ev is None:
1578         raise Exception("WPS ER did not report success")
1579
1580     dev[0].dump_monitor()
1581     dev[0].request("WPS_ER_STOP")
1582
1583 def test_ap_wps_er_cache_ap_settings_oom(dev, apdev):
1584     """WPS ER caching AP settings (OOM)"""
1585     try:
1586         _test_ap_wps_er_cache_ap_settings_oom(dev, apdev)
1587     finally:
1588         dev[0].request("WPS_ER_STOP")
1589
1590 def _test_ap_wps_er_cache_ap_settings_oom(dev, apdev):
1591     ssid = "wps-er-add-enrollee"
1592     ap_pin = "12345670"
1593     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1594     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1595                "wpa_passphrase": "12345678", "wpa": "2",
1596                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1597                "device_name": "Wireless AP", "manufacturer": "Company",
1598                "model_name": "WAP", "model_number": "123",
1599                "serial_number": "12345", "device_type": "6-0050F204-1",
1600                "os_version": "01020300",
1601                "config_methods": "label push_button",
1602                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1603     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1604     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1605     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1606     id = int(dev[0].list_networks()[0]['id'])
1607     dev[0].set_network(id, "scan_freq", "2412")
1608
1609     dev[0].request("WPS_ER_START ifname=lo")
1610     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1611     if ev is None:
1612         raise Exception("AP discovery timed out")
1613     if ap_uuid not in ev:
1614         raise Exception("Expected AP UUID not found")
1615
1616     dev[0].dump_monitor()
1617     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1618     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1619     if ev is None:
1620         raise Exception("AP learn timed out")
1621     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1622     if ev is None:
1623         raise Exception("WPS-FAIL after AP learn timed out")
1624     time.sleep(0.1)
1625
1626     with alloc_fail(dev[0], 1, "=wps_er_ap_use_cached_settings"):
1627         hapd.disable()
1628
1629         for i in range(2):
1630             ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1631                                      "CTRL-EVENT-DISCONNECTED" ],
1632                                    timeout=15)
1633             if ev is None:
1634                 raise Exception("AP removal or disconnection timed out")
1635
1636         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1637         for i in range(2):
1638             ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1639                                    timeout=15)
1640             if ev is None:
1641                 raise Exception("AP discovery or connection timed out")
1642
1643     dev[0].request("WPS_ER_STOP")
1644
1645 def test_ap_wps_er_cache_ap_settings_oom2(dev, apdev):
1646     """WPS ER caching AP settings (OOM 2)"""
1647     try:
1648         _test_ap_wps_er_cache_ap_settings_oom2(dev, apdev)
1649     finally:
1650         dev[0].request("WPS_ER_STOP")
1651
1652 def _test_ap_wps_er_cache_ap_settings_oom2(dev, apdev):
1653     ssid = "wps-er-add-enrollee"
1654     ap_pin = "12345670"
1655     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1656     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1657                "wpa_passphrase": "12345678", "wpa": "2",
1658                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1659                "device_name": "Wireless AP", "manufacturer": "Company",
1660                "model_name": "WAP", "model_number": "123",
1661                "serial_number": "12345", "device_type": "6-0050F204-1",
1662                "os_version": "01020300",
1663                "config_methods": "label push_button",
1664                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1665     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1666     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1667     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1668     id = int(dev[0].list_networks()[0]['id'])
1669     dev[0].set_network(id, "scan_freq", "2412")
1670
1671     dev[0].request("WPS_ER_START ifname=lo")
1672     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=15)
1673     if ev is None:
1674         raise Exception("AP discovery timed out")
1675     if ap_uuid not in ev:
1676         raise Exception("Expected AP UUID not found")
1677
1678     dev[0].dump_monitor()
1679     dev[0].request("WPS_ER_LEARN " + ap_uuid + " " + ap_pin)
1680     ev = dev[0].wait_event(["WPS-ER-AP-SETTINGS"], timeout=15)
1681     if ev is None:
1682         raise Exception("AP learn timed out")
1683     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1684     if ev is None:
1685         raise Exception("WPS-FAIL after AP learn timed out")
1686     time.sleep(0.1)
1687
1688     with alloc_fail(dev[0], 1, "=wps_er_ap_cache_settings"):
1689         hapd.disable()
1690
1691         for i in range(2):
1692             ev = dev[0].wait_event([ "WPS-ER-AP-REMOVE",
1693                                      "CTRL-EVENT-DISCONNECTED" ],
1694                                    timeout=15)
1695             if ev is None:
1696                 raise Exception("AP removal or disconnection timed out")
1697
1698         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1699         for i in range(2):
1700             ev = dev[0].wait_event([ "WPS-ER-AP-ADD", "CTRL-EVENT-CONNECTED" ],
1701                                    timeout=15)
1702             if ev is None:
1703                 raise Exception("AP discovery or connection timed out")
1704
1705     dev[0].request("WPS_ER_STOP")
1706
1707 def test_ap_wps_er_subscribe_oom(dev, apdev):
1708     """WPS ER subscribe OOM"""
1709     try:
1710         _test_ap_wps_er_subscribe_oom(dev, apdev)
1711     finally:
1712         dev[0].request("WPS_ER_STOP")
1713
1714 def _test_ap_wps_er_subscribe_oom(dev, apdev):
1715     ssid = "wps-er-add-enrollee"
1716     ap_pin = "12345670"
1717     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
1718     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1719                "wpa_passphrase": "12345678", "wpa": "2",
1720                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1721                "device_name": "Wireless AP", "manufacturer": "Company",
1722                "model_name": "WAP", "model_number": "123",
1723                "serial_number": "12345", "device_type": "6-0050F204-1",
1724                "os_version": "01020300",
1725                "config_methods": "label push_button",
1726                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo" }
1727     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1728     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1729     dev[0].wps_reg(apdev[0]['bssid'], ap_pin)
1730     id = int(dev[0].list_networks()[0]['id'])
1731     dev[0].set_network(id, "scan_freq", "2412")
1732
1733     with alloc_fail(dev[0], 1, "http_client_addr;wps_er_subscribe"):
1734         dev[0].request("WPS_ER_START ifname=lo")
1735         for i in range(50):
1736             res = dev[0].request("GET_ALLOC_FAIL")
1737             if res.startswith("0:"):
1738                 break
1739             time.sleep(0.1)
1740         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=0)
1741         if ev:
1742             raise Exception("Unexpected AP discovery during OOM")
1743
1744     dev[0].request("WPS_ER_STOP")
1745
1746 def test_ap_wps_fragmentation(dev, apdev):
1747     """WPS with fragmentation in EAP-WSC and mixed mode WPA+WPA2"""
1748     ssid = "test-wps-fragmentation"
1749     appin = "12345670"
1750     hostapd.add_ap(apdev[0]['ifname'],
1751                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1752                      "wpa_passphrase": "12345678", "wpa": "3",
1753                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1754                      "wpa_pairwise": "TKIP", "ap_pin": appin,
1755                      "fragment_size": "50" })
1756     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1757     logger.info("WPS provisioning step (PBC)")
1758     hapd.request("WPS_PBC")
1759     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1760     dev[0].dump_monitor()
1761     dev[0].request("SET wps_fragment_size 50")
1762     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1763     dev[0].wait_connected(timeout=30)
1764     status = dev[0].get_status()
1765     if status['wpa_state'] != 'COMPLETED':
1766         raise Exception("Not fully connected")
1767     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1768         raise Exception("Unexpected encryption configuration")
1769     if status['key_mgmt'] != 'WPA2-PSK':
1770         raise Exception("Unexpected key_mgmt")
1771
1772     logger.info("WPS provisioning step (PIN)")
1773     pin = dev[1].wps_read_pin()
1774     hapd.request("WPS_PIN any " + pin)
1775     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1776     dev[1].request("SET wps_fragment_size 50")
1777     dev[1].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
1778     dev[1].wait_connected(timeout=30)
1779     status = dev[1].get_status()
1780     if status['wpa_state'] != 'COMPLETED':
1781         raise Exception("Not fully connected")
1782     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1783         raise Exception("Unexpected encryption configuration")
1784     if status['key_mgmt'] != 'WPA2-PSK':
1785         raise Exception("Unexpected key_mgmt")
1786
1787     logger.info("WPS connection as registrar")
1788     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1789     dev[2].request("SET wps_fragment_size 50")
1790     dev[2].wps_reg(apdev[0]['bssid'], appin)
1791     status = dev[2].get_status()
1792     if status['wpa_state'] != 'COMPLETED':
1793         raise Exception("Not fully connected")
1794     if status['pairwise_cipher'] != 'CCMP' or status['group_cipher'] != 'TKIP':
1795         raise Exception("Unexpected encryption configuration")
1796     if status['key_mgmt'] != 'WPA2-PSK':
1797         raise Exception("Unexpected key_mgmt")
1798
1799 def test_ap_wps_new_version_sta(dev, apdev):
1800     """WPS compatibility with new version number on the station"""
1801     ssid = "test-wps-ver"
1802     hostapd.add_ap(apdev[0]['ifname'],
1803                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1804                      "wpa_passphrase": "12345678", "wpa": "2",
1805                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1806     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1807     logger.info("WPS provisioning step")
1808     hapd.request("WPS_PBC")
1809     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1810     dev[0].dump_monitor()
1811     dev[0].request("SET wps_version_number 0x43")
1812     dev[0].request("SET wps_vendor_ext_m1 000137100100020001")
1813     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1814     dev[0].wait_connected(timeout=30)
1815
1816 def test_ap_wps_new_version_ap(dev, apdev):
1817     """WPS compatibility with new version number on the AP"""
1818     ssid = "test-wps-ver"
1819     hostapd.add_ap(apdev[0]['ifname'],
1820                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1821                      "wpa_passphrase": "12345678", "wpa": "2",
1822                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1823     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1824     logger.info("WPS provisioning step")
1825     if "FAIL" in hapd.request("SET wps_version_number 0x43"):
1826         raise Exception("Failed to enable test functionality")
1827     hapd.request("WPS_PBC")
1828     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1829     dev[0].dump_monitor()
1830     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1831     dev[0].wait_connected(timeout=30)
1832     hapd.request("SET wps_version_number 0x20")
1833
1834 def test_ap_wps_check_pin(dev, apdev):
1835     """Verify PIN checking through control interface"""
1836     hostapd.add_ap(apdev[0]['ifname'],
1837                    { "ssid": "wps", "eap_server": "1", "wps_state": "2",
1838                      "wpa_passphrase": "12345678", "wpa": "2",
1839                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP" })
1840     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1841     for t in [ ("12345670", "12345670"),
1842                ("12345678", "FAIL-CHECKSUM"),
1843                ("12345", "FAIL"),
1844                ("123456789", "FAIL"),
1845                ("1234-5670", "12345670"),
1846                ("1234 5670", "12345670"),
1847                ("1-2.3:4 5670", "12345670") ]:
1848         res = hapd.request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1849         res2 = dev[0].request("WPS_CHECK_PIN " + t[0]).rstrip('\n')
1850         if res != res2:
1851             raise Exception("Unexpected difference in WPS_CHECK_PIN responses")
1852         if res != t[1]:
1853             raise Exception("Incorrect WPS_CHECK_PIN response {} (expected {})".format(res, t[1]))
1854
1855     if "FAIL" not in hapd.request("WPS_CHECK_PIN 12345"):
1856         raise Exception("Unexpected WPS_CHECK_PIN success")
1857     if "FAIL" not in hapd.request("WPS_CHECK_PIN 123456789"):
1858         raise Exception("Unexpected WPS_CHECK_PIN success")
1859
1860     for i in range(0, 10):
1861         pin = dev[0].request("WPS_PIN get")
1862         rpin = dev[0].request("WPS_CHECK_PIN " + pin).rstrip('\n')
1863         if pin != rpin:
1864             raise Exception("Random PIN validation failed for " + pin)
1865
1866 def test_ap_wps_wep_config(dev, apdev):
1867     """WPS 2.0 AP rejecting WEP configuration"""
1868     ssid = "test-wps-config"
1869     appin = "12345670"
1870     hostapd.add_ap(apdev[0]['ifname'],
1871                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1872                      "ap_pin": appin})
1873     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1874     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1875     dev[0].wps_reg(apdev[0]['bssid'], appin, "wps-new-ssid-wep", "OPEN", "WEP",
1876                    "hello", no_wait=True)
1877     ev = hapd.wait_event(["WPS-FAIL"], timeout=15)
1878     if ev is None:
1879         raise Exception("WPS-FAIL timed out")
1880     if "reason=2" not in ev:
1881         raise Exception("Unexpected reason code in WPS-FAIL")
1882     status = hapd.request("WPS_GET_STATUS")
1883     if "Last WPS result: Failed" not in status:
1884         raise Exception("WPS failure result not shown correctly")
1885     if "Failure Reason: WEP Prohibited" not in status:
1886         raise Exception("Failure reason not reported correctly")
1887     if "Peer Address: " + dev[0].p2p_interface_addr() not in status:
1888         raise Exception("Peer address not shown correctly")
1889
1890 def test_ap_wps_wep_enroll(dev, apdev):
1891     """WPS 2.0 STA rejecting WEP configuration"""
1892     ssid = "test-wps-wep"
1893     hostapd.add_ap(apdev[0]['ifname'],
1894                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1895                      "skip_cred_build": "1", "extra_cred": "wps-wep-cred" })
1896     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1897     hapd.request("WPS_PBC")
1898     dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1899     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1900     ev = dev[0].wait_event(["WPS-FAIL"], timeout=15)
1901     if ev is None:
1902         raise Exception("WPS-FAIL event timed out")
1903     if "msg=12" not in ev or "reason=2 (WEP Prohibited)" not in ev:
1904         raise Exception("Unexpected WPS-FAIL event: " + ev)
1905
1906 def test_ap_wps_ie_fragmentation(dev, apdev):
1907     """WPS AP using fragmented WPS IE"""
1908     ssid = "test-wps-ie-fragmentation"
1909     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1910                "wpa_passphrase": "12345678", "wpa": "2",
1911                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
1912                "device_name": "1234567890abcdef1234567890abcdef",
1913                "manufacturer": "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
1914                "model_name": "1234567890abcdef1234567890abcdef",
1915                "model_number": "1234567890abcdef1234567890abcdef",
1916                "serial_number": "1234567890abcdef1234567890abcdef" }
1917     hostapd.add_ap(apdev[0]['ifname'], params)
1918     hapd = hostapd.Hostapd(apdev[0]['ifname'])
1919     hapd.request("WPS_PBC")
1920     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
1921     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1922     dev[0].wait_connected(timeout=30)
1923     bss = dev[0].get_bss(apdev[0]['bssid'])
1924     if "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1925         logger.info("Device Name not received correctly")
1926         logger.info(bss)
1927         # This can fail if Probe Response frame is missed and Beacon frame was
1928         # used to fill in the BSS entry. This can happen, e.g., during heavy
1929         # load every now and then and is not really an error, so try to
1930         # workaround by runnign another scan.
1931         dev[0].scan(freq="2412", only_new=True)
1932         bss = dev[0].get_bss(apdev[0]['bssid'])
1933         if not bss or "wps_device_name" not in bss or bss['wps_device_name'] != "1234567890abcdef1234567890abcdef":
1934             logger.info(bss)
1935             raise Exception("Device Name not received correctly")
1936     if len(re.findall("dd..0050f204", bss['ie'])) != 2:
1937         raise Exception("Unexpected number of WPS IEs")
1938
1939 def get_psk(pskfile):
1940     psks = {}
1941     with open(pskfile, "r") as f:
1942         lines = f.read().splitlines()
1943         for l in lines:
1944             if l == "# WPA PSKs":
1945                 continue
1946             (addr,psk) = l.split(' ')
1947             psks[addr] = psk
1948     return psks
1949
1950 def test_ap_wps_per_station_psk(dev, apdev):
1951     """WPS PBC provisioning with per-station PSK"""
1952     addr0 = dev[0].own_addr()
1953     addr1 = dev[1].own_addr()
1954     addr2 = dev[2].own_addr()
1955     ssid = "wps"
1956     appin = "12345670"
1957     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
1958     try:
1959         os.remove(pskfile)
1960     except:
1961         pass
1962
1963     try:
1964         with open(pskfile, "w") as f:
1965             f.write("# WPA PSKs\n")
1966
1967         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
1968                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
1969                    "rsn_pairwise": "CCMP", "ap_pin": appin,
1970                    "wpa_psk_file": pskfile }
1971         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
1972
1973         logger.info("First enrollee")
1974         hapd.request("WPS_PBC")
1975         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
1976         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
1977         dev[0].wait_connected(timeout=30)
1978
1979         logger.info("Second enrollee")
1980         hapd.request("WPS_PBC")
1981         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
1982         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
1983         dev[1].wait_connected(timeout=30)
1984
1985         logger.info("External registrar")
1986         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
1987         dev[2].wps_reg(apdev[0]['bssid'], appin)
1988
1989         logger.info("Verifying PSK results")
1990         psks = get_psk(pskfile)
1991         if addr0 not in psks:
1992             raise Exception("No PSK recorded for sta0")
1993         if addr1 not in psks:
1994             raise Exception("No PSK recorded for sta1")
1995         if addr2 not in psks:
1996             raise Exception("No PSK recorded for sta2")
1997         if psks[addr0] == psks[addr1]:
1998             raise Exception("Same PSK recorded for sta0 and sta1")
1999         if psks[addr0] == psks[addr2]:
2000             raise Exception("Same PSK recorded for sta0 and sta2")
2001         if psks[addr1] == psks[addr2]:
2002             raise Exception("Same PSK recorded for sta1 and sta2")
2003
2004         dev[0].request("REMOVE_NETWORK all")
2005         logger.info("Second external registrar")
2006         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2007         dev[0].wps_reg(apdev[0]['bssid'], appin)
2008         psks2 = get_psk(pskfile)
2009         if addr0 not in psks2:
2010             raise Exception("No PSK recorded for sta0(reg)")
2011         if psks[addr0] == psks2[addr0]:
2012             raise Exception("Same PSK recorded for sta0(enrollee) and sta0(reg)")
2013     finally:
2014         os.remove(pskfile)
2015
2016 def test_ap_wps_per_station_psk_failure(dev, apdev):
2017     """WPS PBC provisioning with per-station PSK (file not writable)"""
2018     addr0 = dev[0].p2p_dev_addr()
2019     addr1 = dev[1].p2p_dev_addr()
2020     addr2 = dev[2].p2p_dev_addr()
2021     ssid = "wps"
2022     appin = "12345670"
2023     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
2024     try:
2025         os.remove(pskfile)
2026     except:
2027         pass
2028
2029     try:
2030         with open(pskfile, "w") as f:
2031             f.write("# WPA PSKs\n")
2032
2033         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2034                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
2035                    "rsn_pairwise": "CCMP", "ap_pin": appin,
2036                    "wpa_psk_file": pskfile }
2037         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
2038         if "FAIL" in hapd.request("SET wpa_psk_file /tmp/does/not/exists/ap_wps_per_enrollee_psk_failure.psk_file"):
2039             raise Exception("Failed to set wpa_psk_file")
2040
2041         logger.info("First enrollee")
2042         hapd.request("WPS_PBC")
2043         dev[0].scan_for_bss(apdev[0]['bssid'], freq=2412)
2044         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2045         dev[0].wait_connected(timeout=30)
2046
2047         logger.info("Second enrollee")
2048         hapd.request("WPS_PBC")
2049         dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2050         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
2051         dev[1].wait_connected(timeout=30)
2052
2053         logger.info("External registrar")
2054         dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2055         dev[2].wps_reg(apdev[0]['bssid'], appin)
2056
2057         logger.info("Verifying PSK results")
2058         psks = get_psk(pskfile)
2059         if len(psks) > 0:
2060             raise Exception("PSK recorded unexpectedly")
2061     finally:
2062         os.remove(pskfile)
2063
2064 def test_ap_wps_pin_request_file(dev, apdev):
2065     """WPS PIN provisioning with configured AP"""
2066     ssid = "wps"
2067     pinfile = "/tmp/ap_wps_pin_request_file.log"
2068     if os.path.exists(pinfile):
2069         os.remove(pinfile)
2070     hostapd.add_ap(apdev[0]['ifname'],
2071                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2072                      "wps_pin_requests": pinfile,
2073                      "wpa_passphrase": "12345678", "wpa": "2",
2074                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
2075     hapd = hostapd.Hostapd(apdev[0]['ifname'])
2076     uuid = dev[0].get_status_field("uuid")
2077     pin = dev[0].wps_read_pin()
2078     try:
2079         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2080         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
2081         ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=15)
2082         if ev is None:
2083             raise Exception("PIN needed event not shown")
2084         if uuid not in ev:
2085             raise Exception("UUID mismatch")
2086         dev[0].request("WPS_CANCEL")
2087         success = False
2088         with open(pinfile, "r") as f:
2089             lines = f.readlines()
2090             for l in lines:
2091                 if uuid in l:
2092                     success = True
2093                     break
2094         if not success:
2095             raise Exception("PIN request entry not in the log file")
2096     finally:
2097         try:
2098             os.remove(pinfile)
2099         except:
2100             pass
2101
2102 def test_ap_wps_auto_setup_with_config_file(dev, apdev):
2103     """WPS auto-setup with configuration file"""
2104     conffile = "/tmp/ap_wps_auto_setup_with_config_file.conf"
2105     ifname = apdev[0]['ifname']
2106     try:
2107         with open(conffile, "w") as f:
2108             f.write("driver=nl80211\n")
2109             f.write("hw_mode=g\n")
2110             f.write("channel=1\n")
2111             f.write("ieee80211n=1\n")
2112             f.write("interface=%s\n" % ifname)
2113             f.write("ctrl_interface=/var/run/hostapd\n")
2114             f.write("ssid=wps\n")
2115             f.write("eap_server=1\n")
2116             f.write("wps_state=1\n")
2117         hostapd.add_bss('phy3', ifname, conffile)
2118         hapd = hostapd.Hostapd(ifname)
2119         hapd.request("WPS_PBC")
2120         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
2121         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
2122         dev[0].wait_connected(timeout=30)
2123         with open(conffile, "r") as f:
2124             lines = f.read().splitlines()
2125             vals = dict()
2126             for l in lines:
2127                 try:
2128                     [name,value] = l.split('=', 1)
2129                     vals[name] = value
2130                 except ValueError, e:
2131                     if "# WPS configuration" in l:
2132                         pass
2133                     else:
2134                         raise Exception("Unexpected configuration line: " + l)
2135         if vals['ieee80211n'] != '1' or vals['wps_state'] != '2' or "WPA-PSK" not in vals['wpa_key_mgmt']:
2136             raise Exception("Incorrect configuration: " + str(vals))
2137     finally:
2138         try:
2139             os.remove(conffile)
2140         except:
2141             pass
2142
2143 def test_ap_wps_pbc_timeout(dev, apdev, params):
2144     """wpa_supplicant PBC walk time and WPS ER SelReg timeout [long]"""
2145     if not params['long']:
2146         raise HwsimSkip("Skip test case with long duration due to --long not specified")
2147     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2148     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2149
2150     location = ssdp_get_location(ap_uuid)
2151     urls = upnp_get_urls(location)
2152     eventurl = urlparse.urlparse(urls['event_sub_url'])
2153     ctrlurl = urlparse.urlparse(urls['control_url'])
2154
2155     url = urlparse.urlparse(location)
2156     conn = httplib.HTTPConnection(url.netloc)
2157
2158     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
2159         def handle(self):
2160             data = self.rfile.readline().strip()
2161             logger.debug(data)
2162             self.wfile.write(gen_wps_event())
2163
2164     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
2165     server.timeout = 1
2166
2167     headers = { "callback": '<http://127.0.0.1:12345/event>',
2168                 "NT": "upnp:event",
2169                 "timeout": "Second-1234" }
2170     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2171     resp = conn.getresponse()
2172     if resp.status != 200:
2173         raise Exception("Unexpected HTTP response: %d" % resp.status)
2174     sid = resp.getheader("sid")
2175     logger.debug("Subscription SID " + sid)
2176
2177     msg = '''<?xml version="1.0"?>
2178 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
2179 <s:Body>
2180 <u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
2181 <NewMessage>EEoAARAQQQABARASAAIAABBTAAIxSBBJAA4ANyoAASABBv///////xBIABA2LbR7pTpRkYj7
2182 VFi5hrLk
2183 </NewMessage>
2184 </u:SetSelectedRegistrar>
2185 </s:Body>
2186 </s:Envelope>'''
2187     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2188     headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
2189     conn.request("POST", ctrlurl.path, msg, headers)
2190     resp = conn.getresponse()
2191     if resp.status != 200:
2192         raise Exception("Unexpected HTTP response: %d" % resp.status)
2193
2194     server.handle_request()
2195
2196     logger.info("Start WPS_PBC and wait for PBC walk time expiration")
2197     if "OK" not in dev[0].request("WPS_PBC"):
2198         raise Exception("WPS_PBC failed")
2199
2200     start = os.times()[4]
2201
2202     server.handle_request()
2203     dev[1].request("BSS_FLUSH 0")
2204     dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2205                         only_new=True)
2206     bss = dev[1].get_bss(apdev[0]['bssid'])
2207     logger.debug("BSS: " + str(bss))
2208     if '[WPS-AUTH]' not in bss['flags']:
2209         raise Exception("WPS not indicated authorized")
2210
2211     server.handle_request()
2212
2213     wps_timeout_seen = False
2214
2215     while True:
2216         hapd.dump_monitor()
2217         dev[1].dump_monitor()
2218         if not wps_timeout_seen:
2219             ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=0)
2220             if ev is not None:
2221                 logger.info("PBC timeout seen")
2222                 wps_timeout_seen = True
2223         else:
2224             dev[0].dump_monitor()
2225         now = os.times()[4]
2226         if now - start > 130:
2227             raise Exception("Selected registration information not removed")
2228         dev[1].request("BSS_FLUSH 0")
2229         dev[1].scan_for_bss(apdev[0]['bssid'], freq="2412", force_scan=True,
2230                             only_new=True)
2231         bss = dev[1].get_bss(apdev[0]['bssid'])
2232         logger.debug("BSS: " + str(bss))
2233         if '[WPS-AUTH]' not in bss['flags']:
2234             break
2235         server.handle_request()
2236
2237     server.server_close()
2238
2239     if wps_timeout_seen:
2240         return
2241
2242     now = os.times()[4]
2243     if now < start + 150:
2244         dur = start + 150 - now
2245     else:
2246         dur = 1
2247     logger.info("Continue waiting for PBC timeout (%d sec)" % dur)
2248     ev = dev[0].wait_event(["WPS-TIMEOUT"], timeout=dur)
2249     if ev is None:
2250         raise Exception("WPS-TIMEOUT not reported")
2251
2252 def add_ssdp_ap(ifname, ap_uuid):
2253     ssid = "wps-ssdp"
2254     ap_pin = "12345670"
2255     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
2256                "wpa_passphrase": "12345678", "wpa": "2",
2257                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
2258                "device_name": "Wireless AP", "manufacturer": "Company",
2259                "model_name": "WAP", "model_number": "123",
2260                "serial_number": "12345", "device_type": "6-0050F204-1",
2261                "os_version": "01020300",
2262                "config_methods": "label push_button",
2263                "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo",
2264                "friendly_name": "WPS Access Point",
2265                "manufacturer_url": "http://www.example.com/",
2266                "model_description": "Wireless Access Point",
2267                "model_url": "http://www.example.com/model/",
2268                "upc": "123456789012" }
2269     return hostapd.add_ap(ifname, params)
2270
2271 def ssdp_send(msg, no_recv=False):
2272     socket.setdefaulttimeout(1)
2273     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2274     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2275     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2276     sock.bind(("127.0.0.1", 0))
2277     sock.sendto(msg, ("239.255.255.250", 1900))
2278     if no_recv:
2279         return None
2280     return sock.recv(1000)
2281
2282 def ssdp_send_msearch(st, no_recv=False):
2283     msg = '\r\n'.join([
2284             'M-SEARCH * HTTP/1.1',
2285             'HOST: 239.255.255.250:1900',
2286             'MX: 1',
2287             'MAN: "ssdp:discover"',
2288             'ST: ' + st,
2289             '', ''])
2290     return ssdp_send(msg, no_recv=no_recv)
2291
2292 def test_ap_wps_ssdp_msearch(dev, apdev):
2293     """WPS AP and SSDP M-SEARCH messages"""
2294     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2295     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2296
2297     msg = '\r\n'.join([
2298             'M-SEARCH * HTTP/1.1',
2299             'Host: 239.255.255.250:1900',
2300             'Mx: 1',
2301             'Man: "ssdp:discover"',
2302             'St: urn:schemas-wifialliance-org:device:WFADevice:1',
2303             '', ''])
2304     ssdp_send(msg)
2305
2306     msg = '\r\n'.join([
2307             'M-SEARCH * HTTP/1.1',
2308             'host:\t239.255.255.250:1900\t\t\t\t \t\t',
2309             'mx: \t1\t\t   ',
2310             'man: \t \t "ssdp:discover"   ',
2311             'st: urn:schemas-wifialliance-org:device:WFADevice:1\t\t',
2312             '', ''])
2313     ssdp_send(msg)
2314
2315     ssdp_send_msearch("ssdp:all")
2316     ssdp_send_msearch("upnp:rootdevice")
2317     ssdp_send_msearch("uuid:" + ap_uuid)
2318     ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1")
2319     ssdp_send_msearch("urn:schemas-wifialliance-org:device:WFADevice:1");
2320
2321     msg = '\r\n'.join([
2322             'M-SEARCH * HTTP/1.1',
2323             'HOST:\t239.255.255.250:1900',
2324             'MAN: "ssdp:discover"',
2325             'MX: 130',
2326             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2327             '', ''])
2328     ssdp_send(msg, no_recv=True)
2329
2330 def test_ap_wps_ssdp_invalid_msearch(dev, apdev):
2331     """WPS AP and invalid SSDP M-SEARCH messages"""
2332     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2333     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2334
2335     socket.setdefaulttimeout(1)
2336     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2337     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2338     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2339     sock.bind(("127.0.0.1", 0))
2340
2341     logger.debug("Missing MX")
2342     msg = '\r\n'.join([
2343             'M-SEARCH * HTTP/1.1',
2344             'HOST: 239.255.255.250:1900',
2345             'MAN: "ssdp:discover"',
2346             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2347             '', ''])
2348     sock.sendto(msg, ("239.255.255.250", 1900))
2349
2350     logger.debug("Negative MX")
2351     msg = '\r\n'.join([
2352             'M-SEARCH * HTTP/1.1',
2353             'HOST: 239.255.255.250:1900',
2354             'MX: -1',
2355             'MAN: "ssdp:discover"',
2356             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2357             '', ''])
2358     sock.sendto(msg, ("239.255.255.250", 1900))
2359
2360     logger.debug("Invalid MX")
2361     msg = '\r\n'.join([
2362             'M-SEARCH * HTTP/1.1',
2363             'HOST: 239.255.255.250:1900',
2364             'MX; 1',
2365             'MAN: "ssdp:discover"',
2366             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2367             '', ''])
2368     sock.sendto(msg, ("239.255.255.250", 1900))
2369
2370     logger.debug("Missing MAN")
2371     msg = '\r\n'.join([
2372             'M-SEARCH * HTTP/1.1',
2373             'HOST: 239.255.255.250:1900',
2374             'MX: 1',
2375             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2376             '', ''])
2377     sock.sendto(msg, ("239.255.255.250", 1900))
2378
2379     logger.debug("Invalid MAN")
2380     msg = '\r\n'.join([
2381             'M-SEARCH * HTTP/1.1',
2382             'HOST: 239.255.255.250:1900',
2383             'MX: 1',
2384             'MAN: foo',
2385             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2386             '', ''])
2387     sock.sendto(msg, ("239.255.255.250", 1900))
2388     msg = '\r\n'.join([
2389             'M-SEARCH * HTTP/1.1',
2390             'HOST: 239.255.255.250:1900',
2391             'MX: 1',
2392             'MAN; "ssdp:discover"',
2393             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2394             '', ''])
2395     sock.sendto(msg, ("239.255.255.250", 1900))
2396
2397     logger.debug("Missing HOST")
2398     msg = '\r\n'.join([
2399             'M-SEARCH * HTTP/1.1',
2400             'MAN: "ssdp:discover"',
2401             'MX: 1',
2402             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2403             '', ''])
2404     sock.sendto(msg, ("239.255.255.250", 1900))
2405
2406     logger.debug("Missing ST")
2407     msg = '\r\n'.join([
2408             'M-SEARCH * HTTP/1.1',
2409             'HOST: 239.255.255.250:1900',
2410             'MAN: "ssdp:discover"',
2411             'MX: 1',
2412             '', ''])
2413     sock.sendto(msg, ("239.255.255.250", 1900))
2414
2415     logger.debug("Mismatching ST")
2416     msg = '\r\n'.join([
2417             'M-SEARCH * HTTP/1.1',
2418             'HOST: 239.255.255.250:1900',
2419             'MAN: "ssdp:discover"',
2420             'MX: 1',
2421             'ST: uuid:16d5f8a9-4ee4-4f5e-81f9-cc6e2f47f42d',
2422             '', ''])
2423     sock.sendto(msg, ("239.255.255.250", 1900))
2424     msg = '\r\n'.join([
2425             'M-SEARCH * HTTP/1.1',
2426             'HOST: 239.255.255.250:1900',
2427             'MAN: "ssdp:discover"',
2428             'MX: 1',
2429             'ST: foo:bar',
2430             '', ''])
2431     sock.sendto(msg, ("239.255.255.250", 1900))
2432     msg = '\r\n'.join([
2433             'M-SEARCH * HTTP/1.1',
2434             'HOST: 239.255.255.250:1900',
2435             'MAN: "ssdp:discover"',
2436             'MX: 1',
2437             'ST: foobar',
2438             '', ''])
2439     sock.sendto(msg, ("239.255.255.250", 1900))
2440
2441     logger.debug("Invalid ST")
2442     msg = '\r\n'.join([
2443             'M-SEARCH * HTTP/1.1',
2444             'HOST: 239.255.255.250:1900',
2445             'MAN: "ssdp:discover"',
2446             'MX: 1',
2447             'ST; urn:schemas-wifialliance-org:device:WFADevice:1',
2448             '', ''])
2449     sock.sendto(msg, ("239.255.255.250", 1900))
2450
2451     logger.debug("Invalid M-SEARCH")
2452     msg = '\r\n'.join([
2453             'M+SEARCH * HTTP/1.1',
2454             'HOST: 239.255.255.250:1900',
2455             'MAN: "ssdp:discover"',
2456             'MX: 1',
2457             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2458             '', ''])
2459     sock.sendto(msg, ("239.255.255.250", 1900))
2460     msg = '\r\n'.join([
2461             'M-SEARCH-* HTTP/1.1',
2462             'HOST: 239.255.255.250:1900',
2463             'MAN: "ssdp:discover"',
2464             'MX: 1',
2465             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2466             '', ''])
2467     sock.sendto(msg, ("239.255.255.250", 1900))
2468
2469     logger.debug("Invalid message format")
2470     sock.sendto("NOTIFY * HTTP/1.1", ("239.255.255.250", 1900))
2471     msg = '\r'.join([
2472             'M-SEARCH * HTTP/1.1',
2473             'HOST: 239.255.255.250:1900',
2474             'MAN: "ssdp:discover"',
2475             'MX: 1',
2476             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2477             '', ''])
2478     sock.sendto(msg, ("239.255.255.250", 1900))
2479
2480     try:
2481         r = sock.recv(1000)
2482         raise Exception("Unexpected M-SEARCH response: " + r)
2483     except socket.timeout:
2484         pass
2485
2486     logger.debug("Valid M-SEARCH")
2487     msg = '\r\n'.join([
2488             'M-SEARCH * HTTP/1.1',
2489             'HOST: 239.255.255.250:1900',
2490             'MAN: "ssdp:discover"',
2491             'MX: 1',
2492             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2493             '', ''])
2494     sock.sendto(msg, ("239.255.255.250", 1900))
2495
2496     try:
2497         r = sock.recv(1000)
2498         pass
2499     except socket.timeout:
2500         raise Exception("No SSDP response")
2501
2502 def test_ap_wps_ssdp_burst(dev, apdev):
2503     """WPS AP and SSDP burst"""
2504     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2505     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2506
2507     msg = '\r\n'.join([
2508             'M-SEARCH * HTTP/1.1',
2509             'HOST: 239.255.255.250:1900',
2510             'MAN: "ssdp:discover"',
2511             'MX: 1',
2512             'ST: urn:schemas-wifialliance-org:device:WFADevice:1',
2513             '', ''])
2514     socket.setdefaulttimeout(1)
2515     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2516     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2517     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2518     sock.bind(("127.0.0.1", 0))
2519     for i in range(0, 25):
2520         sock.sendto(msg, ("239.255.255.250", 1900))
2521     resp = 0
2522     while True:
2523         try:
2524             r = sock.recv(1000)
2525             if not r.startswith("HTTP/1.1 200 OK\r\n"):
2526                 raise Exception("Unexpected message: " + r)
2527             resp += 1
2528         except socket.timeout:
2529             break
2530     if resp < 20:
2531         raise Exception("Too few SSDP responses")
2532
2533     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
2534     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
2535     sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)
2536     sock.bind(("127.0.0.1", 0))
2537     for i in range(0, 25):
2538         sock.sendto(msg, ("239.255.255.250", 1900))
2539     while True:
2540         try:
2541             r = sock.recv(1000)
2542             if ap_uuid in r:
2543                 break
2544         except socket.timeout:
2545             raise Exception("No SSDP response")
2546
2547 def ssdp_get_location(uuid):
2548     res = ssdp_send_msearch("uuid:" + uuid)
2549     location = None
2550     for l in res.splitlines():
2551         if l.lower().startswith("location:"):
2552             location = l.split(':', 1)[1].strip()
2553             break
2554     if location is None:
2555         raise Exception("No UPnP location found")
2556     return location
2557
2558 def upnp_get_urls(location):
2559     conn = urllib.urlopen(location)
2560     tree = ET.parse(conn)
2561     root = tree.getroot()
2562     urn = '{urn:schemas-upnp-org:device-1-0}'
2563     service = root.find("./" + urn + "device/" + urn + "serviceList/" + urn + "service")
2564     res = {}
2565     res['scpd_url'] = urlparse.urljoin(location, service.find(urn + 'SCPDURL').text)
2566     res['control_url'] = urlparse.urljoin(location, service.find(urn + 'controlURL').text)
2567     res['event_sub_url'] = urlparse.urljoin(location, service.find(urn + 'eventSubURL').text)
2568     return res
2569
2570 def upnp_soap_action(conn, path, action, include_soap_action=True, soap_action_override=None):
2571     soapns = 'http://schemas.xmlsoap.org/soap/envelope/'
2572     wpsns = 'urn:schemas-wifialliance-org:service:WFAWLANConfig:1'
2573     ET.register_namespace('soapenv', soapns)
2574     ET.register_namespace('wfa', wpsns)
2575     attrib = {}
2576     attrib['{%s}encodingStyle' % soapns] = 'http://schemas.xmlsoap.org/soap/encoding/'
2577     root = ET.Element("{%s}Envelope" % soapns, attrib=attrib)
2578     body = ET.SubElement(root, "{%s}Body" % soapns)
2579     act = ET.SubElement(body, "{%s}%s" % (wpsns, action))
2580     tree = ET.ElementTree(root)
2581     soap = StringIO.StringIO()
2582     tree.write(soap, xml_declaration=True, encoding='utf-8')
2583
2584     headers = { "Content-type": 'text/xml; charset="utf-8"' }
2585     if include_soap_action:
2586         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % action
2587     elif soap_action_override:
2588         headers["SOAPAction"] = soap_action_override
2589     conn.request("POST", path, soap.getvalue(), headers)
2590     return conn.getresponse()
2591
2592 def test_ap_wps_upnp(dev, apdev):
2593     """WPS AP and UPnP operations"""
2594     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2595     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2596
2597     location = ssdp_get_location(ap_uuid)
2598     urls = upnp_get_urls(location)
2599
2600     conn = urllib.urlopen(urls['scpd_url'])
2601     scpd = conn.read()
2602
2603     conn = urllib.urlopen(urlparse.urljoin(location, "unknown.html"))
2604     if conn.getcode() != 404:
2605         raise Exception("Unexpected HTTP response to GET unknown URL")
2606
2607     url = urlparse.urlparse(location)
2608     conn = httplib.HTTPConnection(url.netloc)
2609     #conn.set_debuglevel(1)
2610     headers = { "Content-type": 'text/xml; charset="utf-8"',
2611                 "SOAPAction": '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo"' }
2612     conn.request("POST", "hello", "\r\n\r\n", headers)
2613     resp = conn.getresponse()
2614     if resp.status != 404:
2615         raise Exception("Unexpected HTTP response: %d" % resp.status)
2616
2617     conn.request("UNKNOWN", "hello", "\r\n\r\n", headers)
2618     resp = conn.getresponse()
2619     if resp.status != 501:
2620         raise Exception("Unexpected HTTP response: %d" % resp.status)
2621
2622     headers = { "Content-type": 'text/xml; charset="utf-8"',
2623                 "SOAPAction": '"urn:some-unknown-action#GetDeviceInfo"' }
2624     ctrlurl = urlparse.urlparse(urls['control_url'])
2625     conn.request("POST", ctrlurl.path, "\r\n\r\n", headers)
2626     resp = conn.getresponse()
2627     if resp.status != 401:
2628         raise Exception("Unexpected HTTP response: %d" % resp.status)
2629
2630     logger.debug("GetDeviceInfo without SOAPAction header")
2631     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2632                             include_soap_action=False)
2633     if resp.status != 401:
2634         raise Exception("Unexpected HTTP response: %d" % resp.status)
2635
2636     logger.debug("GetDeviceInfo with invalid SOAPAction header")
2637     for act in [ "foo",
2638                  "urn:schemas-wifialliance-org:service:WFAWLANConfig:1#GetDeviceInfo",
2639                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1"',
2640                  '"urn:schemas-wifialliance-org:service:WFAWLANConfig:123#GetDevice']:
2641         resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo",
2642                                 include_soap_action=False,
2643                                 soap_action_override=act)
2644         if resp.status != 401:
2645             raise Exception("Unexpected HTTP response: %d" % resp.status)
2646
2647     resp = upnp_soap_action(conn, ctrlurl.path, "GetDeviceInfo")
2648     if resp.status != 200:
2649         raise Exception("Unexpected HTTP response: %d" % resp.status)
2650     dev = resp.read()
2651     if "NewDeviceInfo" not in dev:
2652         raise Exception("Unexpected GetDeviceInfo response")
2653
2654     logger.debug("PutMessage without required parameters")
2655     resp = upnp_soap_action(conn, ctrlurl.path, "PutMessage")
2656     if resp.status != 600:
2657         raise Exception("Unexpected HTTP response: %d" % resp.status)
2658
2659     logger.debug("PutWLANResponse without required parameters")
2660     resp = upnp_soap_action(conn, ctrlurl.path, "PutWLANResponse")
2661     if resp.status != 600:
2662         raise Exception("Unexpected HTTP response: %d" % resp.status)
2663
2664     logger.debug("SetSelectedRegistrar from unregistered ER")
2665     resp = upnp_soap_action(conn, ctrlurl.path, "SetSelectedRegistrar")
2666     if resp.status != 501:
2667         raise Exception("Unexpected HTTP response: %d" % resp.status)
2668
2669     logger.debug("Unknown action")
2670     resp = upnp_soap_action(conn, ctrlurl.path, "Unknown")
2671     if resp.status != 401:
2672         raise Exception("Unexpected HTTP response: %d" % resp.status)
2673
2674 def test_ap_wps_upnp_subscribe(dev, apdev):
2675     """WPS AP and UPnP event subscription"""
2676     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
2677     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
2678
2679     location = ssdp_get_location(ap_uuid)
2680     urls = upnp_get_urls(location)
2681     eventurl = urlparse.urlparse(urls['event_sub_url'])
2682
2683     url = urlparse.urlparse(location)
2684     conn = httplib.HTTPConnection(url.netloc)
2685     #conn.set_debuglevel(1)
2686     headers = { "callback": '<http://127.0.0.1:12345/event>',
2687                 "timeout": "Second-1234" }
2688     conn.request("SUBSCRIBE", "hello", "\r\n\r\n", headers)
2689     resp = conn.getresponse()
2690     if resp.status != 412:
2691         raise Exception("Unexpected HTTP response: %d" % resp.status)
2692
2693     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2694     resp = conn.getresponse()
2695     if resp.status != 412:
2696         raise Exception("Unexpected HTTP response: %d" % resp.status)
2697
2698     headers = { "NT": "upnp:event",
2699                 "timeout": "Second-1234" }
2700     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2701     resp = conn.getresponse()
2702     if resp.status != 412:
2703         raise Exception("Unexpected HTTP response: %d" % resp.status)
2704
2705     headers = { "callback": '<http://127.0.0.1:12345/event>',
2706                 "NT": "upnp:foobar",
2707                 "timeout": "Second-1234" }
2708     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2709     resp = conn.getresponse()
2710     if resp.status != 400:
2711         raise Exception("Unexpected HTTP response: %d" % resp.status)
2712
2713     logger.debug("Valid subscription")
2714     headers = { "callback": '<http://127.0.0.1:12345/event>',
2715                 "NT": "upnp:event",
2716                 "timeout": "Second-1234" }
2717     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2718     resp = conn.getresponse()
2719     if resp.status != 200:
2720         raise Exception("Unexpected HTTP response: %d" % resp.status)
2721     sid = resp.getheader("sid")
2722     logger.debug("Subscription SID " + sid)
2723
2724     logger.debug("Invalid re-subscription")
2725     headers = { "NT": "upnp:event",
2726                 "sid": "123456734567854",
2727                 "timeout": "Second-1234" }
2728     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2729     resp = conn.getresponse()
2730     if resp.status != 400:
2731         raise Exception("Unexpected HTTP response: %d" % resp.status)
2732
2733     logger.debug("Invalid re-subscription")
2734     headers = { "NT": "upnp:event",
2735                 "sid": "uuid:123456734567854",
2736                 "timeout": "Second-1234" }
2737     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2738     resp = conn.getresponse()
2739     if resp.status != 400:
2740         raise Exception("Unexpected HTTP response: %d" % resp.status)
2741
2742     logger.debug("Invalid re-subscription")
2743     headers = { "callback": '<http://127.0.0.1:12345/event>',
2744                 "NT": "upnp:event",
2745                 "sid": sid,
2746                 "timeout": "Second-1234" }
2747     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2748     resp = conn.getresponse()
2749     if resp.status != 400:
2750         raise Exception("Unexpected HTTP response: %d" % resp.status)
2751
2752     logger.debug("SID mismatch in re-subscription")
2753     headers = { "NT": "upnp:event",
2754                 "sid": "uuid:4c2bca79-1ff4-4e43-85d4-952a2b8a51fb",
2755                 "timeout": "Second-1234" }
2756     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2757     resp = conn.getresponse()
2758     if resp.status != 412:
2759         raise Exception("Unexpected HTTP response: %d" % resp.status)
2760
2761     logger.debug("Valid re-subscription")
2762     headers = { "NT": "upnp:event",
2763                 "sid": sid,
2764                 "timeout": "Second-1234" }
2765     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2766     resp = conn.getresponse()
2767     if resp.status != 200:
2768         raise Exception("Unexpected HTTP response: %d" % resp.status)
2769     sid2 = resp.getheader("sid")
2770     logger.debug("Subscription SID " + sid2)
2771
2772     if sid != sid2:
2773         raise Exception("Unexpected SID change")
2774
2775     logger.debug("Valid re-subscription")
2776     headers = { "NT": "upnp:event",
2777                 "sid": "uuid: \t \t" + sid.split(':')[1],
2778                 "timeout": "Second-1234" }
2779     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2780     resp = conn.getresponse()
2781     if resp.status != 200:
2782         raise Exception("Unexpected HTTP response: %d" % resp.status)
2783
2784     logger.debug("Invalid unsubscription")
2785     headers = { "sid": sid }
2786     conn.request("UNSUBSCRIBE", "/hello", "\r\n\r\n", headers)
2787     resp = conn.getresponse()
2788     if resp.status != 412:
2789         raise Exception("Unexpected HTTP response: %d" % resp.status)
2790     headers = { "foo": "bar" }
2791     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2792     resp = conn.getresponse()
2793     if resp.status != 412:
2794         raise Exception("Unexpected HTTP response: %d" % resp.status)
2795
2796     logger.debug("Valid unsubscription")
2797     headers = { "sid": sid }
2798     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2799     resp = conn.getresponse()
2800     if resp.status != 200:
2801         raise Exception("Unexpected HTTP response: %d" % resp.status)
2802
2803     logger.debug("Unsubscription for not existing SID")
2804     headers = { "sid": sid }
2805     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2806     resp = conn.getresponse()
2807     if resp.status != 412:
2808         raise Exception("Unexpected HTTP response: %d" % resp.status)
2809
2810     logger.debug("Invalid unsubscription")
2811     headers = { "sid": " \t \tfoo" }
2812     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2813     resp = conn.getresponse()
2814     if resp.status != 400:
2815         raise Exception("Unexpected HTTP response: %d" % resp.status)
2816
2817     logger.debug("Invalid unsubscription")
2818     headers = { "sid": "uuid:\t \tfoo" }
2819     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2820     resp = conn.getresponse()
2821     if resp.status != 400:
2822         raise Exception("Unexpected HTTP response: %d" % resp.status)
2823
2824     logger.debug("Invalid unsubscription")
2825     headers = { "NT": "upnp:event",
2826                 "sid": sid }
2827     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2828     resp = conn.getresponse()
2829     if resp.status != 400:
2830         raise Exception("Unexpected HTTP response: %d" % resp.status)
2831     headers = { "callback": '<http://127.0.0.1:12345/event>',
2832                 "sid": sid }
2833     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2834     resp = conn.getresponse()
2835     if resp.status != 400:
2836         raise Exception("Unexpected HTTP response: %d" % resp.status)
2837
2838     logger.debug("Valid subscription with multiple callbacks")
2839     headers = { "callback": '<http://127.0.0.1:12345/event> <http://127.0.0.1:12345/event>\t<http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event><http://127.0.0.1:12345/event>',
2840                 "NT": "upnp:event",
2841                 "timeout": "Second-1234" }
2842     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2843     resp = conn.getresponse()
2844     if resp.status != 200:
2845         raise Exception("Unexpected HTTP response: %d" % resp.status)
2846     sid = resp.getheader("sid")
2847     logger.debug("Subscription SID " + sid)
2848
2849     # Force subscription to be deleted due to errors
2850     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
2851     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
2852     with alloc_fail(hapd, 1, "event_build_message"):
2853         for i in range(10):
2854             dev[1].dump_monitor()
2855             dev[2].dump_monitor()
2856             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2857             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2858             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2859             dev[1].request("WPS_CANCEL")
2860             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2861             dev[2].request("WPS_CANCEL")
2862             if i % 4 == 1:
2863                 time.sleep(1)
2864             else:
2865                 time.sleep(0.1)
2866     time.sleep(0.2)
2867
2868     headers = { "sid": sid }
2869     conn.request("UNSUBSCRIBE", eventurl.path, "", headers)
2870     resp = conn.getresponse()
2871     if resp.status != 200 and resp.status != 412:
2872         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2873
2874     headers = { "callback": '<http://127.0.0.1:12345/event>',
2875                 "NT": "upnp:event",
2876                 "timeout": "Second-1234" }
2877     with alloc_fail(hapd, 1, "http_client_addr;event_send_start"):
2878         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2879         resp = conn.getresponse()
2880         if resp.status != 200:
2881             raise Exception("Unexpected HTTP response for SUBSCRIBE: %d" % resp.status)
2882         sid = resp.getheader("sid")
2883         logger.debug("Subscription SID " + sid)
2884
2885     headers = { "sid": sid }
2886     conn.request("UNSUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2887     resp = conn.getresponse()
2888     if resp.status != 200:
2889         raise Exception("Unexpected HTTP response for UNSUBSCRIBE: %d" % resp.status)
2890
2891     headers = { "callback": '<http://127.0.0.1:12345/event>',
2892                 "NT": "upnp:event",
2893                 "timeout": "Second-1234" }
2894     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2895     resp = conn.getresponse()
2896     if resp.status != 200:
2897         raise Exception("Unexpected HTTP response: %d" % resp.status)
2898     sid = resp.getheader("sid")
2899     logger.debug("Subscription SID " + sid)
2900
2901     with alloc_fail(hapd, 1, "=event_add"):
2902         for i in range(2):
2903             dev[1].dump_monitor()
2904             dev[2].dump_monitor()
2905             dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2906             dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2907             dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2908             dev[1].request("WPS_CANCEL")
2909             dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2910             dev[2].request("WPS_CANCEL")
2911             if i == 0:
2912                 time.sleep(1)
2913             else:
2914                 time.sleep(0.1)
2915
2916     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2917     resp = conn.getresponse()
2918     if resp.status != 200:
2919         raise Exception("Unexpected HTTP response: %d" % resp.status)
2920
2921     with alloc_fail(hapd, 1, "wpabuf_dup;event_add"):
2922         dev[1].dump_monitor()
2923         dev[2].dump_monitor()
2924         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2925         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2926         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2927         dev[1].request("WPS_CANCEL")
2928         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
2929         dev[2].request("WPS_CANCEL")
2930         time.sleep(0.1)
2931
2932     with fail_test(hapd, 1, "os_get_random;uuid_make;subscription_start"):
2933         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2934         resp = conn.getresponse()
2935         if resp.status != 500:
2936             raise Exception("Unexpected HTTP response: %d" % resp.status)
2937
2938     with alloc_fail(hapd, 1, "=subscription_start"):
2939         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2940         resp = conn.getresponse()
2941         if resp.status != 500:
2942             raise Exception("Unexpected HTTP response: %d" % resp.status)
2943
2944     headers = { "callback": '',
2945                 "NT": "upnp:event",
2946                 "timeout": "Second-1234" }
2947     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2948     resp = conn.getresponse()
2949     if resp.status != 500:
2950         raise Exception("Unexpected HTTP response: %d" % resp.status)
2951
2952     headers = { "callback": ' <',
2953                 "NT": "upnp:event",
2954                 "timeout": "Second-1234" }
2955     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2956     resp = conn.getresponse()
2957     if resp.status != 500:
2958         raise Exception("Unexpected HTTP response: %d" % resp.status)
2959
2960     headers = { "callback": '<http://127.0.0.1:12345/event>',
2961                 "NT": "upnp:event",
2962                 "timeout": "Second-1234" }
2963     with alloc_fail(hapd, 1, "wpabuf_alloc;subscription_first_event"):
2964         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2965         resp = conn.getresponse()
2966         if resp.status != 500:
2967             raise Exception("Unexpected HTTP response: %d" % resp.status)
2968
2969     with alloc_fail(hapd, 1, "event_add;subscription_first_event"):
2970         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2971         resp = conn.getresponse()
2972         if resp.status != 500:
2973             raise Exception("Unexpected HTTP response: %d" % resp.status)
2974
2975     with alloc_fail(hapd, 1, "subscr_addr_add_url"):
2976         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2977         resp = conn.getresponse()
2978         if resp.status != 500:
2979             raise Exception("Unexpected HTTP response: %d" % resp.status)
2980
2981     with alloc_fail(hapd, 2, "subscr_addr_add_url"):
2982         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2983         resp = conn.getresponse()
2984         if resp.status != 500:
2985             raise Exception("Unexpected HTTP response: %d" % resp.status)
2986
2987     for i in range(6):
2988         headers = { "callback": '<http://127.0.0.1:%d/event>' % (12345 + i),
2989                     "NT": "upnp:event",
2990                     "timeout": "Second-1234" }
2991         conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
2992         resp = conn.getresponse()
2993         if resp.status != 200:
2994             raise Exception("Unexpected HTTP response: %d" % resp.status)
2995
2996     with alloc_fail(hapd, 1, "=upnp_wps_device_send_wlan_event"):
2997         dev[1].dump_monitor()
2998         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
2999         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3000         dev[1].request("WPS_CANCEL")
3001         time.sleep(0.1)
3002
3003     with alloc_fail(hapd, 1, "wpabuf_alloc;upnp_wps_device_send_event"):
3004         dev[1].dump_monitor()
3005         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3006         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3007         dev[1].request("WPS_CANCEL")
3008         time.sleep(0.1)
3009
3010     with alloc_fail(hapd, 1, "base64_encode;upnp_wps_device_send_wlan_event"):
3011         dev[1].dump_monitor()
3012         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3013         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3014         dev[1].request("WPS_CANCEL")
3015         time.sleep(0.1)
3016
3017     hapd.disable()
3018     with alloc_fail(hapd, 1, "get_netif_info"):
3019         if "FAIL" not in hapd.request("ENABLE"):
3020             raise Exception("ENABLE succeeded during OOM")
3021
3022 def test_ap_wps_upnp_subscribe_events(dev, apdev):
3023     """WPS AP and UPnP event subscription and many events"""
3024     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3025     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3026
3027     location = ssdp_get_location(ap_uuid)
3028     urls = upnp_get_urls(location)
3029     eventurl = urlparse.urlparse(urls['event_sub_url'])
3030
3031     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
3032         def handle(self):
3033             data = self.rfile.readline().strip()
3034             logger.debug(data)
3035             self.wfile.write(gen_wps_event())
3036
3037     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
3038     server.timeout = 1
3039
3040     url = urlparse.urlparse(location)
3041     conn = httplib.HTTPConnection(url.netloc)
3042
3043     headers = { "callback": '<http://127.0.0.1:12345/event>',
3044                 "NT": "upnp:event",
3045                 "timeout": "Second-1234" }
3046     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
3047     resp = conn.getresponse()
3048     if resp.status != 200:
3049         raise Exception("Unexpected HTTP response: %d" % resp.status)
3050     sid = resp.getheader("sid")
3051     logger.debug("Subscription SID " + sid)
3052
3053     # Fetch the first event message
3054     server.handle_request()
3055
3056     # Force subscription event queue to reach the maximum length by generating
3057     # new proxied events without the ER fetching any of the pending events.
3058     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3059     dev[2].scan_for_bss(apdev[0]['bssid'], freq=2412)
3060     for i in range(16):
3061         dev[1].dump_monitor()
3062         dev[2].dump_monitor()
3063         dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3064         dev[2].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3065         dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3066         dev[1].request("WPS_CANCEL")
3067         dev[2].wait_event(["CTRL-EVENT-SCAN-RESULTS"], 5)
3068         dev[2].request("WPS_CANCEL")
3069         if i % 4 == 1:
3070             time.sleep(1)
3071         else:
3072             time.sleep(0.1)
3073
3074     hapd.request("WPS_PIN any 12345670")
3075     dev[1].dump_monitor()
3076     dev[1].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3077     ev = dev[1].wait_event(["WPS-SUCCESS"], timeout=10)
3078     if ev is None:
3079         raise Exception("WPS success not reported")
3080
3081     # Close the WPS ER HTTP server without fetching all the pending events.
3082     # This tests hostapd code path that clears subscription and the remaining
3083     # event queue when the interface is deinitialized.
3084     server.handle_request()
3085     server.server_close()
3086
3087     dev[1].wait_connected()
3088
3089 def test_ap_wps_upnp_http_proto(dev, apdev):
3090     """WPS AP and UPnP/HTTP protocol testing"""
3091     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3092     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3093
3094     location = ssdp_get_location(ap_uuid)
3095
3096     url = urlparse.urlparse(location)
3097     conn = httplib.HTTPConnection(url.netloc, timeout=0.2)
3098     #conn.set_debuglevel(1)
3099
3100     conn.request("HEAD", "hello")
3101     resp = conn.getresponse()
3102     if resp.status != 501:
3103         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3104     conn.close()
3105
3106     for cmd in [ "PUT", "DELETE", "TRACE", "CONNECT", "M-SEARCH", "M-POST" ]:
3107         try:
3108             conn.request(cmd, "hello")
3109             resp = conn.getresponse()
3110         except Exception, e:
3111             pass
3112         conn.close()
3113
3114     headers = { "Content-Length": 'abc' }
3115     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3116     try:
3117         resp = conn.getresponse()
3118     except Exception, e:
3119         pass
3120     conn.close()
3121
3122     headers = { "Content-Length": '-10' }
3123     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3124     try:
3125         resp = conn.getresponse()
3126     except Exception, e:
3127         pass
3128     conn.close()
3129
3130     headers = { "Content-Length": '10000000000000' }
3131     conn.request("HEAD", "hello", "\r\n\r\nhello", headers)
3132     try:
3133         resp = conn.getresponse()
3134     except Exception, e:
3135         pass
3136     conn.close()
3137
3138     headers = { "Transfer-Encoding": 'abc' }
3139     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3140     resp = conn.getresponse()
3141     if resp.status != 501:
3142         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3143     conn.close()
3144
3145     headers = { "Transfer-Encoding": 'chunked' }
3146     conn.request("HEAD", "hello", "\r\n\r\n", headers)
3147     resp = conn.getresponse()
3148     if resp.status != 501:
3149         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3150     conn.close()
3151
3152     # Too long a header
3153     conn.request("HEAD", 5000 * 'A')
3154     try:
3155         resp = conn.getresponse()
3156     except Exception, e:
3157         pass
3158     conn.close()
3159
3160     # Long URL but within header length limits
3161     conn.request("HEAD", 3000 * 'A')
3162     resp = conn.getresponse()
3163     if resp.status != 501:
3164         raise Exception("Unexpected response to HEAD: " + str(resp.status))
3165     conn.close()
3166
3167     headers = { "Content-Length": '20' }
3168     conn.request("POST", "hello", 10 * 'A' + "\r\n\r\n", headers)
3169     try:
3170         resp = conn.getresponse()
3171     except Exception, e:
3172         pass
3173     conn.close()
3174
3175     conn.request("POST", "hello", 5000 * 'A' + "\r\n\r\n")
3176     resp = conn.getresponse()
3177     if resp.status != 404:
3178         raise Exception("Unexpected HTTP response: %d" % resp.status)
3179     conn.close()
3180
3181     conn.request("POST", "hello", 60000 * 'A' + "\r\n\r\n")
3182     try:
3183         resp = conn.getresponse()
3184     except Exception, e:
3185         pass
3186     conn.close()
3187
3188 def test_ap_wps_upnp_http_proto_chunked(dev, apdev):
3189     """WPS AP and UPnP/HTTP protocol testing for chunked encoding"""
3190     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3191     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
3192
3193     location = ssdp_get_location(ap_uuid)
3194
3195     url = urlparse.urlparse(location)
3196     conn = httplib.HTTPConnection(url.netloc)
3197     #conn.set_debuglevel(1)
3198
3199     headers = { "Transfer-Encoding": 'chunked' }
3200     conn.request("POST", "hello",
3201                  "a\r\nabcdefghij\r\n" + "2\r\nkl\r\n" + "0\r\n\r\n",
3202                  headers)
3203     resp = conn.getresponse()
3204     if resp.status != 404:
3205         raise Exception("Unexpected HTTP response: %d" % resp.status)
3206     conn.close()
3207
3208     conn.putrequest("POST", "hello")
3209     conn.putheader('Transfer-Encoding', 'chunked')
3210     conn.endheaders()
3211     conn.send("a\r\nabcdefghij\r\n")
3212     time.sleep(0.1)
3213     conn.send("2\r\nkl\r\n")
3214     conn.send("0\r\n\r\n")
3215     resp = conn.getresponse()
3216     if resp.status != 404:
3217         raise Exception("Unexpected HTTP response: %d" % resp.status)
3218     conn.close()
3219
3220     conn.putrequest("POST", "hello")
3221     conn.putheader('Transfer-Encoding', 'chunked')
3222     conn.endheaders()
3223     completed = False
3224     try:
3225         for i in range(20000):
3226             conn.send("1\r\nZ\r\n")
3227         conn.send("0\r\n\r\n")
3228         resp = conn.getresponse()
3229         completed = True
3230     except Exception, e:
3231         pass
3232     conn.close()
3233     if completed:
3234         raise Exception("Too long chunked request did not result in connection reset")
3235
3236     headers = { "Transfer-Encoding": 'chunked' }
3237     conn.request("POST", "hello", "80000000\r\na", headers)
3238     try:
3239         resp = conn.getresponse()
3240     except Exception, e:
3241         pass
3242     conn.close()
3243
3244     conn.request("POST", "hello", "10000000\r\na", headers)
3245     try:
3246         resp = conn.getresponse()
3247     except Exception, e:
3248         pass
3249     conn.close()
3250
3251 def test_ap_wps_disabled(dev, apdev):
3252     """WPS operations while WPS is disabled"""
3253     ssid = "test-wps-disabled"
3254     hostapd.add_ap(apdev[0]['ifname'], { "ssid": ssid })
3255     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3256     if "FAIL" not in hapd.request("WPS_PBC"):
3257         raise Exception("WPS_PBC succeeded unexpectedly")
3258     if "FAIL" not in hapd.request("WPS_CANCEL"):
3259         raise Exception("WPS_CANCEL succeeded unexpectedly")
3260
3261 def test_ap_wps_mixed_cred(dev, apdev):
3262     """WPS 2.0 STA merging mixed mode WPA/WPA2 credentials"""
3263     ssid = "test-wps-wep"
3264     hostapd.add_ap(apdev[0]['ifname'],
3265                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3266                      "skip_cred_build": "1", "extra_cred": "wps-mixed-cred" })
3267     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3268     hapd.request("WPS_PBC")
3269     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3270     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3271     ev = dev[0].wait_event(["WPS-SUCCESS"], timeout=30)
3272     if ev is None:
3273         raise Exception("WPS-SUCCESS event timed out")
3274     nets = dev[0].list_networks()
3275     if len(nets) != 1:
3276         raise Exception("Unexpected number of network blocks")
3277     id = nets[0]['id']
3278     proto = dev[0].get_network(id, "proto")
3279     if proto != "WPA RSN":
3280         raise Exception("Unexpected merged proto field value: " + proto)
3281     pairwise = dev[0].get_network(id, "pairwise")
3282     if pairwise != "CCMP TKIP" and pairwise != "CCMP GCMP TKIP":
3283         raise Exception("Unexpected merged pairwise field value: " + pairwise)
3284
3285 def test_ap_wps_while_connected(dev, apdev):
3286     """WPS PBC provisioning while connected to another AP"""
3287     ssid = "test-wps-conf"
3288     hostapd.add_ap(apdev[0]['ifname'],
3289                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3290                      "wpa_passphrase": "12345678", "wpa": "2",
3291                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3292     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3293
3294     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
3295     dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3296
3297     logger.info("WPS provisioning step")
3298     hapd.request("WPS_PBC")
3299     dev[0].dump_monitor()
3300     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3301     dev[0].wait_connected(timeout=30)
3302     status = dev[0].get_status()
3303     if status['bssid'] != apdev[0]['bssid']:
3304         raise Exception("Unexpected BSSID")
3305
3306 def test_ap_wps_while_connected_no_autoconnect(dev, apdev):
3307     """WPS PBC provisioning while connected to another AP and STA_AUTOCONNECT disabled"""
3308     ssid = "test-wps-conf"
3309     hostapd.add_ap(apdev[0]['ifname'],
3310                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3311                      "wpa_passphrase": "12345678", "wpa": "2",
3312                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3313     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3314
3315     hostapd.add_ap(apdev[1]['ifname'], { "ssid": "open" })
3316
3317     try:
3318         dev[0].request("STA_AUTOCONNECT 0")
3319         dev[0].connect("open", key_mgmt="NONE", scan_freq="2412")
3320
3321         logger.info("WPS provisioning step")
3322         hapd.request("WPS_PBC")
3323         dev[0].dump_monitor()
3324         dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3325         dev[0].wait_connected(timeout=30)
3326         status = dev[0].get_status()
3327         if status['bssid'] != apdev[0]['bssid']:
3328             raise Exception("Unexpected BSSID")
3329     finally:
3330         dev[0].request("STA_AUTOCONNECT 1")
3331
3332 def test_ap_wps_from_event(dev, apdev):
3333     """WPS PBC event on AP to enable PBC"""
3334     ssid = "test-wps-conf"
3335     hapd = hostapd.add_ap(apdev[0]['ifname'],
3336                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3337                             "wpa_passphrase": "12345678", "wpa": "2",
3338                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3339     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3340     dev[0].dump_monitor()
3341     hapd.dump_monitor()
3342     dev[0].request("WPS_PBC " + apdev[0]['bssid'])
3343
3344     ev = hapd.wait_event(['WPS-ENROLLEE-SEEN'], timeout=15)
3345     if ev is None:
3346         raise Exception("No WPS-ENROLLEE-SEEN event on AP")
3347     vals = ev.split(' ')
3348     if vals[1] != dev[0].p2p_interface_addr():
3349         raise Exception("Unexpected enrollee address: " + vals[1])
3350     if vals[5] != '4':
3351         raise Exception("Unexpected Device Password Id: " + vals[5])
3352     hapd.request("WPS_PBC")
3353     dev[0].wait_connected(timeout=30)
3354
3355 def test_ap_wps_ap_scan_2(dev, apdev):
3356     """AP_SCAN 2 for WPS"""
3357     ssid = "test-wps-conf"
3358     hapd = hostapd.add_ap(apdev[0]['ifname'],
3359                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3360                             "wpa_passphrase": "12345678", "wpa": "2",
3361                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3362     hapd.request("WPS_PBC")
3363
3364     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
3365     wpas.interface_add("wlan5", drv_params="force_connect_cmd=1")
3366
3367     if "OK" not in wpas.request("AP_SCAN 2"):
3368         raise Exception("Failed to set AP_SCAN 2")
3369
3370     wpas.flush_scan_cache()
3371     wpas.scan_for_bss(apdev[0]['bssid'], freq="2412")
3372     wpas.request("WPS_PBC " + apdev[0]['bssid'])
3373     ev = wpas.wait_event(["WPS-SUCCESS"], timeout=15)
3374     if ev is None:
3375         raise Exception("WPS-SUCCESS event timed out")
3376     wpas.wait_connected(timeout=30)
3377     wpas.request("DISCONNECT")
3378     wpas.request("BSS_FLUSH 0")
3379     wpas.dump_monitor()
3380     wpas.request("REASSOCIATE")
3381     wpas.wait_connected(timeout=30)
3382
3383 def test_ap_wps_eapol_workaround(dev, apdev):
3384     """EAPOL workaround code path for 802.1X header length mismatch"""
3385     ssid = "test-wps"
3386     hostapd.add_ap(apdev[0]['ifname'],
3387                    { "ssid": ssid, "eap_server": "1", "wps_state": "1" })
3388     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3389     bssid = apdev[0]['bssid']
3390     hapd.request("SET ext_eapol_frame_io 1")
3391     dev[0].request("SET ext_eapol_frame_io 1")
3392     hapd.request("WPS_PBC")
3393     dev[0].request("WPS_PBC")
3394
3395     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3396     if ev is None:
3397         raise Exception("Timeout on EAPOL-TX from hostapd")
3398
3399     res = dev[0].request("EAPOL_RX " + bssid + " 020000040193000501FFFF")
3400     if "OK" not in res:
3401         raise Exception("EAPOL_RX to wpa_supplicant failed")
3402
3403 def test_ap_wps_iteration(dev, apdev):
3404     """WPS PIN and iterate through APs without selected registrar"""
3405     ssid = "test-wps-conf"
3406     hapd = hostapd.add_ap(apdev[0]['ifname'],
3407                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3408                             "wpa_passphrase": "12345678", "wpa": "2",
3409                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3410
3411     ssid2 = "test-wps-conf2"
3412     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3413                            { "ssid": ssid2, "eap_server": "1", "wps_state": "2",
3414                              "wpa_passphrase": "12345678", "wpa": "2",
3415                              "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3416
3417     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3418     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
3419     dev[0].dump_monitor()
3420     pin = dev[0].request("WPS_PIN any")
3421
3422     # Wait for iteration through all WPS APs to happen before enabling any
3423     # Registrar.
3424     for i in range(2):
3425         ev = dev[0].wait_event(["Associated with"], timeout=30)
3426         if ev is None:
3427             raise Exception("No association seen")
3428         ev = dev[0].wait_event(["WPS-M2D"], timeout=10)
3429         if ev is None:
3430             raise Exception("No M2D from AP")
3431         dev[0].wait_disconnected()
3432
3433     # Verify that each AP requested PIN
3434     ev = hapd.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3435     if ev is None:
3436         raise Exception("No WPS-PIN-NEEDED event from AP")
3437     ev = hapd2.wait_event(["WPS-PIN-NEEDED"], timeout=1)
3438     if ev is None:
3439         raise Exception("No WPS-PIN-NEEDED event from AP2")
3440
3441     # Provide PIN to one of the APs and verify that connection gets formed
3442     hapd.request("WPS_PIN any " + pin)
3443     dev[0].wait_connected(timeout=30)
3444
3445 def test_ap_wps_iteration_error(dev, apdev):
3446     """WPS AP iteration on no Selected Registrar and error case with an AP"""
3447     ssid = "test-wps-conf-pin"
3448     hapd = hostapd.add_ap(apdev[0]['ifname'],
3449                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3450                             "wpa_passphrase": "12345678", "wpa": "2",
3451                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3452                             "wps_independent": "1" })
3453     hapd.request("SET ext_eapol_frame_io 1")
3454     bssid = apdev[0]['bssid']
3455     pin = dev[0].wps_read_pin()
3456     dev[0].request("WPS_PIN any " + pin)
3457
3458     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3459     if ev is None:
3460         raise Exception("No EAPOL-TX (EAP-Request/Identity) from hostapd")
3461     dev[0].request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
3462
3463     ev = hapd.wait_event(["EAPOL-TX"], timeout=15)
3464     if ev is None:
3465         raise Exception("No EAPOL-TX (EAP-WSC/Start) from hostapd")
3466     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
3467     if ev is None:
3468         raise Exception("No CTRL-EVENT-EAP-STARTED")
3469
3470     # Do not forward any more EAPOL frames to test wpa_supplicant behavior for
3471     # a case with an incorrectly behaving WPS AP.
3472
3473     # Start the real target AP and activate registrar on it.
3474     hapd2 = hostapd.add_ap(apdev[1]['ifname'],
3475                           { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3476                             "wpa_passphrase": "12345678", "wpa": "2",
3477                             "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3478                             "wps_independent": "1" })
3479     hapd2.request("WPS_PIN any " + pin)
3480
3481     dev[0].wait_disconnected(timeout=15)
3482     ev = dev[0].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=15)
3483     if ev is None:
3484         raise Exception("No CTRL-EVENT-EAP-STARTED for the second AP")
3485     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=15)
3486     if ev is None:
3487         raise Exception("No WPS-CRED-RECEIVED for the second AP")
3488     dev[0].wait_connected(timeout=15)
3489
3490 def test_ap_wps_priority(dev, apdev):
3491     """WPS PIN provisioning with configured AP and wps_priority"""
3492     ssid = "test-wps-conf-pin"
3493     hostapd.add_ap(apdev[0]['ifname'],
3494                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3495                      "wpa_passphrase": "12345678", "wpa": "2",
3496                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3497     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3498     logger.info("WPS provisioning step")
3499     pin = dev[0].wps_read_pin()
3500     hapd.request("WPS_PIN any " + pin)
3501     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3502     dev[0].dump_monitor()
3503     try:
3504         dev[0].request("SET wps_priority 6")
3505         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3506         dev[0].wait_connected(timeout=30)
3507         netw = dev[0].list_networks()
3508         prio = dev[0].get_network(netw[0]['id'], 'priority')
3509         if prio != '6':
3510             raise Exception("Unexpected network priority: " + prio)
3511     finally:
3512         dev[0].request("SET wps_priority 0")
3513
3514 def test_ap_wps_and_non_wps(dev, apdev):
3515     """WPS and non-WPS AP in single hostapd process"""
3516     params = { "ssid": "wps", "eap_server": "1", "wps_state": "1" }
3517     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3518
3519     params = { "ssid": "no wps" }
3520     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
3521
3522     appin = hapd.request("WPS_AP_PIN random")
3523     if "FAIL" in appin:
3524         raise Exception("Could not generate random AP PIN")
3525     if appin not in hapd.request("WPS_AP_PIN get"):
3526         raise Exception("Could not fetch current AP PIN")
3527
3528     if "FAIL" in hapd.request("WPS_PBC"):
3529         raise Exception("WPS_PBC failed")
3530     if "FAIL" in hapd.request("WPS_CANCEL"):
3531         raise Exception("WPS_CANCEL failed")
3532
3533 def test_ap_wps_init_oom(dev, apdev):
3534     """Initial AP configuration and OOM during PSK generation"""
3535     ssid = "test-wps"
3536     params = { "ssid": ssid, "eap_server": "1", "wps_state": "1" }
3537     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
3538
3539     with alloc_fail(hapd, 1, "base64_encode;wps_build_cred"):
3540         pin = dev[0].wps_read_pin()
3541         hapd.request("WPS_PIN any " + pin)
3542         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3543         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
3544         dev[0].wait_disconnected()
3545
3546     hapd.request("WPS_PIN any " + pin)
3547     dev[0].wait_connected(timeout=30)
3548
3549 def test_ap_wps_er_oom(dev, apdev):
3550     """WPS ER OOM in XML processing"""
3551     try:
3552         _test_ap_wps_er_oom(dev, apdev)
3553     finally:
3554         dev[0].request("WPS_ER_STOP")
3555         dev[1].request("WPS_CANCEL")
3556         dev[0].request("DISCONNECT")
3557
3558 def _test_ap_wps_er_oom(dev, apdev):
3559     ssid = "wps-er-ap-config"
3560     ap_pin = "12345670"
3561     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
3562     hostapd.add_ap(apdev[0]['ifname'],
3563                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3564                      "wpa_passphrase": "12345678", "wpa": "2",
3565                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
3566                      "device_name": "Wireless AP", "manufacturer": "Company",
3567                      "model_name": "WAP", "model_number": "123",
3568                      "serial_number": "12345", "device_type": "6-0050F204-1",
3569                      "os_version": "01020300",
3570                      "config_methods": "label push_button",
3571                      "ap_pin": ap_pin, "uuid": ap_uuid, "upnp_iface": "lo"})
3572
3573     dev[0].connect(ssid, psk="12345678", scan_freq="2412")
3574
3575     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3576         dev[0].request("WPS_ER_START ifname=lo")
3577         ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=3)
3578         if ev is not None:
3579             raise Exception("Unexpected AP discovery")
3580
3581     dev[0].request("WPS_ER_STOP")
3582     dev[0].request("WPS_ER_START ifname=lo")
3583     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3584     if ev is None:
3585         raise Exception("AP discovery timed out")
3586
3587     dev[1].scan_for_bss(apdev[0]['bssid'], freq=2412)
3588     with alloc_fail(dev[0], 1, "base64_decode;xml_get_base64_item"):
3589         dev[1].request("WPS_PBC " + apdev[0]['bssid'])
3590         ev = dev[1].wait_event(["CTRL-EVENT-SCAN-RESULTS"], timeout=10)
3591         if ev is None:
3592             raise Exception("PBC scan failed")
3593         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=15)
3594         if ev is None:
3595             raise Exception("Enrollee discovery timed out")
3596
3597 def test_ap_wps_er_init_oom(dev, apdev):
3598     """WPS ER and OOM during init"""
3599     try:
3600         _test_ap_wps_er_init_oom(dev, apdev)
3601     finally:
3602         dev[0].request("WPS_ER_STOP")
3603
3604 def _test_ap_wps_er_init_oom(dev, apdev):
3605     with alloc_fail(dev[0], 1, "wps_er_init"):
3606         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3607             raise Exception("WPS_ER_START succeeded during OOM")
3608     with alloc_fail(dev[0], 1, "http_server_init"):
3609         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3610             raise Exception("WPS_ER_START succeeded during OOM")
3611     with alloc_fail(dev[0], 2, "http_server_init"):
3612         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3613             raise Exception("WPS_ER_START succeeded during OOM")
3614     with alloc_fail(dev[0], 1, "eloop_register_sock;wps_er_ssdp_init"):
3615         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3616             raise Exception("WPS_ER_START succeeded during OOM")
3617     with fail_test(dev[0], 1, "os_get_random;wps_er_init"):
3618         if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo"):
3619             raise Exception("WPS_ER_START succeeded during os_get_random failure")
3620
3621 def test_ap_wps_er_init_fail(dev, apdev):
3622     """WPS ER init failure"""
3623     if "FAIL" not in dev[0].request("WPS_ER_START ifname=does-not-exist"):
3624         dev[0].request("WPS_ER_STOP")
3625         raise Exception("WPS_ER_START with non-existing ifname succeeded")
3626
3627 def test_ap_wps_wpa_cli_action(dev, apdev, test_params):
3628     """WPS events and wpa_cli action script"""
3629     logdir = os.path.abspath(test_params['logdir'])
3630     pidfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.pid')
3631     logfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.res')
3632     actionfile = os.path.join(logdir, 'ap_wps_wpa_cli_action.wpa_cli.action.sh')
3633
3634     with open(actionfile, 'w') as f:
3635         f.write('#!/bin/sh\n')
3636         f.write('echo $* >> %s\n' % logfile)
3637         # Kill the process and wait some time before returning to allow all the
3638         # pending events to be processed with some of this happening after the
3639         # eloop SIGALRM signal has been scheduled.
3640         f.write('if [ $2 = "WPS-SUCCESS" -a -r %s ]; then kill `cat %s`; sleep 1; fi\n' % (pidfile, pidfile))
3641
3642     os.chmod(actionfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC |
3643              stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)
3644
3645     ssid = "test-wps-conf"
3646     hostapd.add_ap(apdev[0]['ifname'],
3647                    { "ssid": ssid, "eap_server": "1", "wps_state": "2",
3648                      "wpa_passphrase": "12345678", "wpa": "2",
3649                      "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"})
3650     hapd = hostapd.Hostapd(apdev[0]['ifname'])
3651
3652     prg = os.path.join(test_params['logdir'],
3653                        'alt-wpa_supplicant/wpa_supplicant/wpa_cli')
3654     if not os.path.exists(prg):
3655         prg = '../../wpa_supplicant/wpa_cli'
3656     arg = [ prg, '-P', pidfile, '-B', '-i', dev[0].ifname, '-a', actionfile ]
3657     subprocess.call(arg)
3658
3659     arg = [ 'ps', 'ax' ]
3660     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3661     out = cmd.communicate()[0]
3662     cmd.wait()
3663     logger.debug("Processes:\n" + out)
3664     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) not in out:
3665         raise Exception("Did not see wpa_cli running")
3666
3667     hapd.request("WPS_PIN any 12345670")
3668     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
3669     dev[0].dump_monitor()
3670     dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " 12345670")
3671     dev[0].wait_connected(timeout=30)
3672
3673     for i in range(30):
3674         if not os.path.exists(pidfile):
3675             break
3676         time.sleep(0.1)
3677
3678     if not os.path.exists(logfile):
3679         raise Exception("wpa_cli action results file not found")
3680     with open(logfile, 'r') as f:
3681         res = f.read()
3682     if "WPS-SUCCESS" not in res:
3683         raise Exception("WPS-SUCCESS event not seen in action file")
3684
3685     arg = [ 'ps', 'ax' ]
3686     cmd = subprocess.Popen(arg, stdout=subprocess.PIPE)
3687     out = cmd.communicate()[0]
3688     cmd.wait()
3689     logger.debug("Remaining processes:\n" + out)
3690     if "wpa_cli -P %s -B -i %s" % (pidfile, dev[0].ifname) in out:
3691         raise Exception("wpa_cli still running")
3692
3693     if os.path.exists(pidfile):
3694         raise Exception("PID file not removed")
3695
3696 def test_ap_wps_er_ssdp_proto(dev, apdev):
3697     """WPS ER SSDP protocol testing"""
3698     try:
3699         _test_ap_wps_er_ssdp_proto(dev, apdev)
3700     finally:
3701         dev[0].request("WPS_ER_STOP")
3702
3703 def _test_ap_wps_er_ssdp_proto(dev, apdev):
3704     socket.setdefaulttimeout(1)
3705     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3706     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3707     sock.bind(("239.255.255.250", 1900))
3708     if "FAIL" not in dev[0].request("WPS_ER_START ifname=lo foo"):
3709         raise Exception("Invalid filter accepted")
3710     if "OK" not in dev[0].request("WPS_ER_START ifname=lo 1.2.3.4"):
3711         raise Exception("WPS_ER_START with filter failed")
3712     (msg,addr) = sock.recvfrom(1000)
3713     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3714     if "M-SEARCH" not in msg:
3715         raise Exception("Not an M-SEARCH")
3716     sock.sendto("FOO", addr)
3717     time.sleep(0.1)
3718     dev[0].request("WPS_ER_STOP")
3719
3720     dev[0].request("WPS_ER_START ifname=lo")
3721     (msg,addr) = sock.recvfrom(1000)
3722     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3723     if "M-SEARCH" not in msg:
3724         raise Exception("Not an M-SEARCH")
3725     sock.sendto("FOO", addr)
3726     sock.sendto("HTTP/1.1 200 OK\r\nFOO\r\n\r\n", addr)
3727     sock.sendto("HTTP/1.1 200 OK\r\nNTS:foo\r\n\r\n", addr)
3728     sock.sendto("HTTP/1.1 200 OK\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3729     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   foo=1\r\n\r\n", addr)
3730     sock.sendto("HTTP/1.1 200 OK\r\ncache-control:   max-age=1\r\n\r\n", addr)
3731     sock.sendto("HTTP/1.1 200 OK\r\nusn:\r\n\r\n", addr)
3732     sock.sendto("HTTP/1.1 200 OK\r\nusn:foo\r\n\r\n", addr)
3733     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:\r\n\r\n", addr)
3734     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     \r\n\r\n", addr)
3735     sock.sendto("HTTP/1.1 200 OK\r\nusn:   uuid:     foo\r\n\r\n", addr)
3736     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\n\r\n", addr)
3737     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nNTS:ssdp:byebye\r\n\r\n", addr)
3738     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\n\r\n", addr)
3739     with alloc_fail(dev[0], 1, "wps_er_ap_add"):
3740         sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\ncache-control:max-age=1\r\n\r\n", addr)
3741         time.sleep(0.1)
3742     with alloc_fail(dev[0], 2, "wps_er_ap_add"):
3743         sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\ncache-control:max-age=1\r\n\r\n", addr)
3744         time.sleep(0.1)
3745
3746     # Add an AP with bogus URL
3747     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:foo\r\ncache-control:max-age=1\r\n\r\n", addr)
3748     # Update timeout on AP without updating URL
3749     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://127.0.0.1:12345/foo.xml\r\ncache-control:max-age=1\r\n\r\n", addr)
3750     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3751     if ev is None:
3752         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3753
3754     # Add an AP with a valid URL (but no server listing to it)
3755     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:http://127.0.0.1:12345/foo.xml\r\ncache-control:max-age=1\r\n\r\n", addr)
3756     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3757     if ev is None:
3758         raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3759
3760     sock.close()
3761
3762 wps_event_url = None
3763
3764 def gen_upnp_info(eventSubURL='wps_event', controlURL='wps_control',
3765                   udn='uuid:27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'):
3766     payload = '''<?xml version="1.0"?>
3767 <root xmlns="urn:schemas-upnp-org:device-1-0">
3768 <specVersion>
3769 <major>1</major>
3770 <minor>0</minor>
3771 </specVersion>
3772 <device>
3773 <deviceType>urn:schemas-wifialliance-org:device:WFADevice:1</deviceType>
3774 <friendlyName>WPS Access Point</friendlyName>
3775 <manufacturer>Company</manufacturer>
3776 <modelName>WAP</modelName>
3777 <modelNumber>123</modelNumber>
3778 <serialNumber>12345</serialNumber>
3779 '''
3780     if udn:
3781         payload += '<UDN>' + udn + '</UDN>'
3782     payload += '''<serviceList>
3783 <service>
3784 <serviceType>urn:schemas-wifialliance-org:service:WFAWLANConfig:1</serviceType>
3785 <serviceId>urn:wifialliance-org:serviceId:WFAWLANConfig1</serviceId>
3786 <SCPDURL>wps_scpd.xml</SCPDURL>
3787 '''
3788     if controlURL:
3789         payload += '<controlURL>' + controlURL + '</controlURL>\n'
3790     if eventSubURL:
3791         payload += '<eventSubURL>' + eventSubURL + '</eventSubURL>\n'
3792     payload += '''</service>
3793 </serviceList>
3794 </device>
3795 </root>
3796 '''
3797     hdr = 'HTTP/1.1 200 OK\r\n' + \
3798           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3799           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3800           'Connection: close\r\n' + \
3801           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3802           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3803     return hdr + payload
3804
3805 def gen_wps_control(payload_override=None):
3806     payload = '''<?xml version="1.0"?>
3807 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
3808 <s:Body>
3809 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
3810 <NewDeviceInfo>EEoAARAQIgABBBBHABAn6oAanlxOc72C+Jy80Q1+ECAABgIAAAADABAaABCJZ7DPtbU3Ust9
3811 Z3wJF07WEDIAwH45D3i1OqB7eJGwTzqeapS71h3KyXncK2xJZ+xqScrlorNEg6LijBJzG2Ca
3812 +FZli0iliDJd397yAx/jk4nFXco3q5ylBSvSw9dhJ5u1xBKSnTilKGlUHPhLP75PUqM3fot9
3813 7zwtFZ4bx6x1sBA6oEe2d0aUJmLumQGCiKEIWlnxs44zego/2tAe81bDzdPBM7o5HH/FUhD+
3814 KoGzFXp51atP+1n9Vta6AkI0Vye99JKLcC6Md9dMJltSVBgd4Xc4lRAEAAIAIxAQAAIADRAN
3815 AAEBEAgAAgAEEEQAAQIQIQAHQ29tcGFueRAjAANXQVAQJAADMTIzEEIABTEyMzQ1EFQACAAG
3816 AFDyBAABEBEAC1dpcmVsZXNzIEFQEDwAAQEQAgACAAAQEgACAAAQCQACAAAQLQAEgQIDABBJ
3817 AAYANyoAASA=
3818 </NewDeviceInfo>
3819 </u:GetDeviceInfoResponse>
3820 </s:Body>
3821 </s:Envelope>
3822 '''
3823     if payload_override:
3824         payload = payload_override
3825     hdr = 'HTTP/1.1 200 OK\r\n' + \
3826           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3827           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3828           'Connection: close\r\n' + \
3829           'Content-Length: ' + str(len(payload)) + '\r\n' + \
3830           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3831     return hdr + payload
3832
3833 def gen_wps_event(sid='uuid:7eb3342a-8a5f-47fe-a585-0785bfec6d8a'):
3834     payload = ""
3835     hdr = 'HTTP/1.1 200 OK\r\n' + \
3836           'Content-Type: text/xml; charset="utf-8"\r\n' + \
3837           'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
3838           'Connection: close\r\n' + \
3839           'Content-Length: ' + str(len(payload)) + '\r\n'
3840     if sid:
3841         hdr += 'SID: ' + sid + '\r\n'
3842     hdr += 'Timeout: Second-1801\r\n' + \
3843           'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
3844     return hdr + payload
3845
3846 class WPSAPHTTPServer(SocketServer.StreamRequestHandler):
3847     def handle(self):
3848         data = self.rfile.readline().strip()
3849         logger.info("HTTP server received: " + data)
3850         while True:
3851             hdr = self.rfile.readline().strip()
3852             if len(hdr) == 0:
3853                 break
3854             logger.info("HTTP header: " + hdr)
3855             if "CALLBACK:" in hdr:
3856                 global wps_event_url
3857                 wps_event_url = hdr.split(' ')[1].strip('<>')
3858
3859         if "GET /foo.xml" in data:
3860             self.handle_upnp_info()
3861         elif "POST /wps_control" in data:
3862             self.handle_wps_control()
3863         elif "SUBSCRIBE /wps_event" in data:
3864             self.handle_wps_event()
3865         else:
3866             self.handle_others(data)
3867
3868     def handle_upnp_info(self):
3869         self.wfile.write(gen_upnp_info())
3870
3871     def handle_wps_control(self):
3872         self.wfile.write(gen_wps_control())
3873
3874     def handle_wps_event(self):
3875         self.wfile.write(gen_wps_event())
3876
3877     def handle_others(self, data):
3878         logger.info("Ignore HTTP request: " + data)
3879
3880 class MyTCPServer(SocketServer.TCPServer):
3881     def __init__(self, addr, handler):
3882         self.allow_reuse_address = True
3883         SocketServer.TCPServer.__init__(self, addr, handler)
3884
3885 def wps_er_start(dev, http_server, max_age=1, wait_m_search=False,
3886                  location_url=None):
3887     socket.setdefaulttimeout(1)
3888     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
3889     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3890     sock.bind(("239.255.255.250", 1900))
3891     dev.request("WPS_ER_START ifname=lo")
3892     for i in range(100):
3893         (msg,addr) = sock.recvfrom(1000)
3894         logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
3895         if "M-SEARCH" in msg:
3896             break
3897         if not wait_m_search:
3898             raise Exception("Not an M-SEARCH")
3899         if i == 99:
3900             raise Exception("No M-SEARCH seen")
3901
3902     # Add an AP with a valid URL and server listing to it
3903     server = MyTCPServer(("127.0.0.1", 12345), http_server)
3904     if not location_url:
3905         location_url = 'http://127.0.0.1:12345/foo.xml'
3906     sock.sendto("HTTP/1.1 200 OK\r\nST: urn:schemas-wifialliance-org:device:WFADevice:1\r\nlocation:%s\r\ncache-control:max-age=%d\r\n\r\n" % (location_url, max_age), addr)
3907     server.timeout = 1
3908     return server,sock
3909
3910 def wps_er_stop(dev, sock, server, on_alloc_fail=False):
3911     sock.close()
3912     server.server_close()
3913
3914     if on_alloc_fail:
3915         done = False
3916         for i in range(50):
3917             res = dev.request("GET_ALLOC_FAIL")
3918             if res.startswith("0:"):
3919                 done = True
3920                 break
3921             time.sleep(0.1)
3922         if not done:
3923             raise Exception("No allocation failure reported")
3924     else:
3925         ev = dev.wait_event(["WPS-ER-AP-REMOVE"], timeout=5)
3926         if ev is None:
3927             raise Exception("No WPS-ER-AP-REMOVE event on max-age timeout")
3928     dev.request("WPS_ER_STOP")
3929
3930 def run_wps_er_proto_test(dev, handler, no_event_url=False, location_url=None):
3931     try:
3932         uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3933         server,sock = wps_er_start(dev, handler, location_url=location_url)
3934         global wps_event_url
3935         wps_event_url = None
3936         server.handle_request()
3937         server.handle_request()
3938         server.handle_request()
3939         server.server_close()
3940         if no_event_url:
3941             if wps_event_url:
3942                 raise Exception("Received event URL unexpectedly")
3943             return
3944         if wps_event_url is None:
3945             raise Exception("Did not get event URL")
3946         logger.info("Event URL: " + wps_event_url)
3947     finally:
3948             dev.request("WPS_ER_STOP")
3949
3950 def send_wlanevent(url, uuid, data, no_response=False):
3951     conn = httplib.HTTPConnection(url.netloc)
3952     payload = '''<?xml version="1.0" encoding="utf-8"?>
3953 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
3954 <e:property><STAStatus>1</STAStatus></e:property>
3955 <e:property><APStatus>1</APStatus></e:property>
3956 <e:property><WLANEvent>'''
3957     payload += base64.b64encode(data)
3958     payload += '</WLANEvent></e:property></e:propertyset>'
3959     headers = { "Content-type": 'text/xml; charset="utf-8"',
3960                 "Server": "Unspecified, UPnP/1.0, Unspecified",
3961                 "HOST": url.netloc,
3962                 "NT": "upnp:event",
3963                 "SID": "uuid:" + uuid,
3964                 "SEQ": "0",
3965                 "Content-Length": str(len(payload)) }
3966     conn.request("NOTIFY", url.path, payload, headers)
3967     if no_response:
3968         try:
3969             conn.getresponse()
3970         except Exception, e:
3971             pass
3972         return
3973     resp = conn.getresponse()
3974     if resp.status != 200:
3975         raise Exception("Unexpected HTTP response: %d" % resp.status)
3976
3977 def test_ap_wps_er_http_proto(dev, apdev):
3978     """WPS ER HTTP protocol testing"""
3979     try:
3980         _test_ap_wps_er_http_proto(dev, apdev)
3981     finally:
3982         dev[0].request("WPS_ER_STOP")
3983
3984 def _test_ap_wps_er_http_proto(dev, apdev):
3985     uuid = '27ea801a-9e5c-4e73-bd82-f89cbcd10d7e'
3986     server,sock = wps_er_start(dev[0], WPSAPHTTPServer, max_age=15)
3987     global wps_event_url
3988     wps_event_url = None
3989     server.handle_request()
3990     server.handle_request()
3991     server.handle_request()
3992     server.server_close()
3993     if wps_event_url is None:
3994         raise Exception("Did not get event URL")
3995     logger.info("Event URL: " + wps_event_url)
3996
3997     ev = dev[0].wait_event(["WPS-ER-AP-ADD"], timeout=10)
3998     if ev is None:
3999         raise Exception("No WPS-ER-AP-ADD event")
4000     if uuid not in ev:
4001         raise Exception("UUID mismatch")
4002
4003     sock.close()
4004
4005     logger.info("Valid Probe Request notification")
4006     url = urlparse.urlparse(wps_event_url)
4007     conn = httplib.HTTPConnection(url.netloc)
4008     payload = '''<?xml version="1.0" encoding="utf-8"?>
4009 <e:propertyset xmlns:e="urn:schemas-upnp-org:event-1-0">
4010 <e:property><STAStatus>1</STAStatus></e:property>
4011 <e:property><APStatus>1</APStatus></e:property>
4012 <e:property><WLANEvent>ATAyOjAwOjAwOjAwOjAwOjAwEEoAARAQOgABAhAIAAIxSBBHABA2LbR7pTpRkYj7VFi5hrLk
4013 EFQACAAAAAAAAAAAEDwAAQMQAgACAAAQCQACAAAQEgACAAAQIQABIBAjAAEgECQAASAQEQAI
4014 RGV2aWNlIEEQSQAGADcqAAEg
4015 </WLANEvent></e:property>
4016 </e:propertyset>
4017 '''
4018     headers = { "Content-type": 'text/xml; charset="utf-8"',
4019                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4020                 "HOST": url.netloc,
4021                 "NT": "upnp:event",
4022                 "SID": "uuid:" + uuid,
4023                 "SEQ": "0",
4024                 "Content-Length": str(len(payload)) }
4025     conn.request("NOTIFY", url.path, payload, headers)
4026     resp = conn.getresponse()
4027     if resp.status != 200:
4028         raise Exception("Unexpected HTTP response: %d" % resp.status)
4029
4030     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=5)
4031     if ev is None:
4032         raise Exception("No WPS-ER-ENROLLEE-ADD event")
4033     if "362db47b-a53a-5191-88fb-5458b986b2e4" not in ev:
4034         raise Exception("No Enrollee UUID match")
4035
4036     logger.info("Incorrect event URL AP id")
4037     conn = httplib.HTTPConnection(url.netloc)
4038     conn.request("NOTIFY", url.path + '123', payload, headers)
4039     resp = conn.getresponse()
4040     if resp.status != 404:
4041         raise Exception("Unexpected HTTP response: %d" % resp.status)
4042
4043     logger.info("Missing AP id")
4044     conn = httplib.HTTPConnection(url.netloc)
4045     conn.request("NOTIFY", '/event/' + url.path.split('/')[2],
4046                  payload, headers)
4047     time.sleep(0.1)
4048
4049     logger.info("Incorrect event URL event id")
4050     conn = httplib.HTTPConnection(url.netloc)
4051     conn.request("NOTIFY", '/event/123456789/123', payload, headers)
4052     time.sleep(0.1)
4053
4054     logger.info("Incorrect event URL prefix")
4055     conn = httplib.HTTPConnection(url.netloc)
4056     conn.request("NOTIFY", '/foobar/123456789/123', payload, headers)
4057     resp = conn.getresponse()
4058     if resp.status != 404:
4059         raise Exception("Unexpected HTTP response: %d" % resp.status)
4060
4061     logger.info("Unsupported request")
4062     conn = httplib.HTTPConnection(url.netloc)
4063     conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4064     resp = conn.getresponse()
4065     if resp.status != 501:
4066         raise Exception("Unexpected HTTP response: %d" % resp.status)
4067
4068     logger.info("Unsupported request and OOM")
4069     with alloc_fail(dev[0], 1, "wps_er_http_req"):
4070         conn = httplib.HTTPConnection(url.netloc)
4071         conn.request("FOOBAR", '/foobar/123456789/123', payload, headers)
4072         time.sleep(0.5)
4073
4074     logger.info("Too short WLANEvent")
4075     data = '\x00'
4076     send_wlanevent(url, uuid, data)
4077
4078     logger.info("Invalid WLANEventMAC")
4079     data = '\x00qwertyuiopasdfghjklzxcvbnm'
4080     send_wlanevent(url, uuid, data)
4081
4082     logger.info("Unknown WLANEventType")
4083     data = '\xff02:00:00:00:00:00'
4084     send_wlanevent(url, uuid, data)
4085
4086     logger.info("Probe Request notification without any attributes")
4087     data = '\x0102:00:00:00:00:00'
4088     send_wlanevent(url, uuid, data)
4089
4090     logger.info("Probe Request notification with invalid attribute")
4091     data = '\x0102:00:00:00:00:00\xff'
4092     send_wlanevent(url, uuid, data)
4093
4094     logger.info("EAP message without any attributes")
4095     data = '\x0202:00:00:00:00:00'
4096     send_wlanevent(url, uuid, data)
4097
4098     logger.info("EAP message with invalid attribute")
4099     data = '\x0202:00:00:00:00:00\xff'
4100     send_wlanevent(url, uuid, data)
4101
4102     logger.info("EAP message from new STA and not M1")
4103     data = '\x0202:ff:ff:ff:ff:ff' + '\x10\x22\x00\x01\x05'
4104     send_wlanevent(url, uuid, data)
4105
4106     logger.info("EAP message: M1")
4107     data = '\x0202:00:00:00:00:00'
4108     data += '\x10\x22\x00\x01\x04'
4109     data += '\x10\x47\x00\x10' + 16*'\x00'
4110     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4111     data += '\x10\x1a\x00\x10' + 16*'\x00'
4112     data += '\x10\x32\x00\xc0' + 192*'\x00'
4113     data += '\x10\x04\x00\x02\x00\x00'
4114     data += '\x10\x10\x00\x02\x00\x00'
4115     data += '\x10\x0d\x00\x01\x00'
4116     data += '\x10\x08\x00\x02\x00\x00'
4117     data += '\x10\x44\x00\x01\x00'
4118     data += '\x10\x21\x00\x00'
4119     data += '\x10\x23\x00\x00'
4120     data += '\x10\x24\x00\x00'
4121     data += '\x10\x42\x00\x00'
4122     data += '\x10\x54\x00\x08' + 8*'\x00'
4123     data += '\x10\x11\x00\x00'
4124     data += '\x10\x3c\x00\x01\x00'
4125     data += '\x10\x02\x00\x02\x00\x00'
4126     data += '\x10\x12\x00\x02\x00\x00'
4127     data += '\x10\x09\x00\x02\x00\x00'
4128     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4129     m1 = data
4130     send_wlanevent(url, uuid, data)
4131
4132     logger.info("EAP message: WSC_ACK")
4133     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0d'
4134     send_wlanevent(url, uuid, data)
4135
4136     logger.info("EAP message: M1")
4137     send_wlanevent(url, uuid, m1)
4138
4139     logger.info("EAP message: WSC_NACK")
4140     data = '\x0202:00:00:00:00:00' + '\x10\x22\x00\x01\x0e'
4141     send_wlanevent(url, uuid, data)
4142
4143     logger.info("EAP message: M1 - Too long attribute values")
4144     data = '\x0202:00:00:00:00:00'
4145     data += '\x10\x11\x00\x21' + 33*'\x00'
4146     data += '\x10\x45\x00\x21' + 33*'\x00'
4147     data += '\x10\x42\x00\x21' + 33*'\x00'
4148     data += '\x10\x24\x00\x21' + 33*'\x00'
4149     data += '\x10\x23\x00\x21' + 33*'\x00'
4150     data += '\x10\x21\x00\x41' + 65*'\x00'
4151     data += '\x10\x49\x00\x09\x00\x37\x2a\x05\x02\x00\x00\x05\x00'
4152     send_wlanevent(url, uuid, data)
4153
4154     logger.info("EAP message: M1 missing UUID-E")
4155     data = '\x0202:00:00:00:00:00'
4156     data += '\x10\x22\x00\x01\x04'
4157     send_wlanevent(url, uuid, data)
4158
4159     logger.info("EAP message: M1 missing MAC Address")
4160     data += '\x10\x47\x00\x10' + 16*'\x00'
4161     send_wlanevent(url, uuid, data)
4162
4163     logger.info("EAP message: M1 missing Enrollee Nonce")
4164     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4165     send_wlanevent(url, uuid, data)
4166
4167     logger.info("EAP message: M1 missing Public Key")
4168     data += '\x10\x1a\x00\x10' + 16*'\x00'
4169     send_wlanevent(url, uuid, data)
4170
4171     logger.info("EAP message: M1 missing Authentication Type flags")
4172     data += '\x10\x32\x00\xc0' + 192*'\x00'
4173     send_wlanevent(url, uuid, data)
4174
4175     logger.info("EAP message: M1 missing Encryption Type Flags")
4176     data += '\x10\x04\x00\x02\x00\x00'
4177     send_wlanevent(url, uuid, data)
4178
4179     logger.info("EAP message: M1 missing Connection Type flags")
4180     data += '\x10\x10\x00\x02\x00\x00'
4181     send_wlanevent(url, uuid, data)
4182
4183     logger.info("EAP message: M1 missing Config Methods")
4184     data += '\x10\x0d\x00\x01\x00'
4185     send_wlanevent(url, uuid, data)
4186
4187     logger.info("EAP message: M1 missing Wi-Fi Protected Setup State")
4188     data += '\x10\x08\x00\x02\x00\x00'
4189     send_wlanevent(url, uuid, data)
4190
4191     logger.info("EAP message: M1 missing Manufacturer")
4192     data += '\x10\x44\x00\x01\x00'
4193     send_wlanevent(url, uuid, data)
4194
4195     logger.info("EAP message: M1 missing Model Name")
4196     data += '\x10\x21\x00\x00'
4197     send_wlanevent(url, uuid, data)
4198
4199     logger.info("EAP message: M1 missing Model Number")
4200     data += '\x10\x23\x00\x00'
4201     send_wlanevent(url, uuid, data)
4202
4203     logger.info("EAP message: M1 missing Serial Number")
4204     data += '\x10\x24\x00\x00'
4205     send_wlanevent(url, uuid, data)
4206
4207     logger.info("EAP message: M1 missing Primary Device Type")
4208     data += '\x10\x42\x00\x00'
4209     send_wlanevent(url, uuid, data)
4210
4211     logger.info("EAP message: M1 missing Device Name")
4212     data += '\x10\x54\x00\x08' + 8*'\x00'
4213     send_wlanevent(url, uuid, data)
4214
4215     logger.info("EAP message: M1 missing RF Bands")
4216     data += '\x10\x11\x00\x00'
4217     send_wlanevent(url, uuid, data)
4218
4219     logger.info("EAP message: M1 missing Association State")
4220     data += '\x10\x3c\x00\x01\x00'
4221     send_wlanevent(url, uuid, data)
4222
4223     logger.info("EAP message: M1 missing Device Password ID")
4224     data += '\x10\x02\x00\x02\x00\x00'
4225     send_wlanevent(url, uuid, data)
4226
4227     logger.info("EAP message: M1 missing Configuration Error")
4228     data += '\x10\x12\x00\x02\x00\x00'
4229     send_wlanevent(url, uuid, data)
4230
4231     logger.info("EAP message: M1 missing OS Version")
4232     data += '\x10\x09\x00\x02\x00\x00'
4233     send_wlanevent(url, uuid, data)
4234
4235     logger.info("Check max concurrent requests")
4236     addr = (url.hostname, url.port)
4237     socks = {}
4238     for i in range(20):
4239         socks[i] = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4240                                  socket.IPPROTO_TCP)
4241         socks[i].connect(addr)
4242     for i in range(20):
4243         socks[i].send("GET / HTTP/1.1\r\n\r\n")
4244     count = 0
4245     for i in range(20):
4246         try:
4247             res = socks[i].recv(100)
4248             if "HTTP/1" in res:
4249                 count += 1
4250         except:
4251             pass
4252         socks[i].close()
4253     logger.info("%d concurrent HTTP GET operations returned response" % count)
4254     if count < 10:
4255         raise Exception("Too few concurrent HTTP connections accepted")
4256
4257     logger.info("OOM in HTTP server")
4258     for func in [ "http_request_init", "httpread_create",
4259                   "eloop_register_timeout;httpread_create",
4260                   "eloop_register_sock;httpread_create",
4261                   "httpread_hdr_analyze" ]:
4262         with alloc_fail(dev[0], 1, func):
4263             sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4264                                  socket.IPPROTO_TCP)
4265             sock.connect(addr)
4266             sock.send("GET / HTTP/1.1\r\n\r\n")
4267             try:
4268                 sock.recv(100)
4269             except:
4270                 pass
4271             sock.close()
4272
4273     logger.info("Invalid HTTP header")
4274     for req in [ " GET / HTTP/1.1\r\n\r\n",
4275                  "HTTP/1.1 200 OK\r\n\r\n",
4276                  "HTTP/\r\n\r\n",
4277                  "GET %%a%aa% HTTP/1.1\r\n\r\n",
4278                  "GET / HTTP/1.1\r\n FOO\r\n\r\n",
4279                  "NOTIFY / HTTP/1.1\r\n" + 4097*'a' + '\r\n\r\n',
4280                  "NOTIFY / HTTP/1.1\r\n\r\n" + 8193*'a',
4281                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n foo\r\n",
4282                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n1\r\nfoo\r\n",
4283                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\n",
4284                  "POST / HTTP/1.1\r\nTransfer-Encoding: CHUNKED\r\n\r\n0\r\naa\ra\r\n\ra" ]:
4285         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4286                              socket.IPPROTO_TCP)
4287         sock.settimeout(0.1)
4288         sock.connect(addr)
4289         sock.send(req)
4290         try:
4291             sock.recv(100)
4292         except:
4293             pass
4294         sock.close()
4295
4296     with alloc_fail(dev[0], 2, "httpread_read_handler"):
4297         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4298                              socket.IPPROTO_TCP)
4299         sock.connect(addr)
4300         sock.send("NOTIFY / HTTP/1.1\r\n\r\n" + 4500*'a')
4301         try:
4302             sock.recv(100)
4303         except:
4304             pass
4305         sock.close()
4306
4307     conn = httplib.HTTPConnection(url.netloc)
4308     payload = '<foo'
4309     headers = { "Content-type": 'text/xml; charset="utf-8"',
4310                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4311                 "HOST": url.netloc,
4312                 "NT": "upnp:event",
4313                 "SID": "uuid:" + uuid,
4314                 "SEQ": "0",
4315                 "Content-Length": str(len(payload)) }
4316     conn.request("NOTIFY", url.path, payload, headers)
4317     resp = conn.getresponse()
4318     if resp.status != 200:
4319         raise Exception("Unexpected HTTP response: %d" % resp.status)
4320
4321     conn = httplib.HTTPConnection(url.netloc)
4322     payload = '<WLANEvent foo></WLANEvent>'
4323     headers = { "Content-type": 'text/xml; charset="utf-8"',
4324                 "Server": "Unspecified, UPnP/1.0, Unspecified",
4325                 "HOST": url.netloc,
4326                 "NT": "upnp:event",
4327                 "SID": "uuid:" + uuid,
4328                 "SEQ": "0",
4329                 "Content-Length": str(len(payload)) }
4330     conn.request("NOTIFY", url.path, payload, headers)
4331     resp = conn.getresponse()
4332     if resp.status != 200:
4333         raise Exception("Unexpected HTTP response: %d" % resp.status)
4334
4335     with alloc_fail(dev[0], 1, "xml_get_first_item"):
4336         send_wlanevent(url, uuid, '')
4337
4338     with alloc_fail(dev[0], 1, "wpabuf_alloc_ext_data;xml_get_base64_item"):
4339         send_wlanevent(url, uuid, 'foo')
4340
4341     for func in [ "wps_init",
4342                   "wps_process_manufacturer",
4343                   "wps_process_model_name",
4344                   "wps_process_model_number",
4345                   "wps_process_serial_number",
4346                   "wps_process_dev_name" ]:
4347         with alloc_fail(dev[0], 1, func):
4348             send_wlanevent(url, uuid, m1)
4349
4350     with alloc_fail(dev[0], 1, "wps_er_http_resp_ok"):
4351         send_wlanevent(url, uuid, m1, no_response=True)
4352
4353     with alloc_fail(dev[0], 1, "wps_er_http_resp_not_found"):
4354         url2 = urlparse.urlparse(wps_event_url.replace('/event/', '/notfound/'))
4355         send_wlanevent(url2, uuid, m1, no_response=True)
4356
4357     logger.info("EAP message: M1")
4358     data = '\x0202:11:22:00:00:00'
4359     data += '\x10\x22\x00\x01\x04'
4360     data += '\x10\x47\x00\x10' + 16*'\x00'
4361     data += '\x10\x20\x00\x06\x02\x00\x00\x00\x00\x00'
4362     data += '\x10\x1a\x00\x10' + 16*'\x00'
4363     data += '\x10\x32\x00\xc0' + 192*'\x00'
4364     data += '\x10\x04\x00\x02\x00\x00'
4365     data += '\x10\x10\x00\x02\x00\x00'
4366     data += '\x10\x0d\x00\x01\x00'
4367     data += '\x10\x08\x00\x02\x00\x00'
4368     data += '\x10\x44\x00\x01\x00'
4369     data += '\x10\x21\x00\x00'
4370     data += '\x10\x23\x00\x00'
4371     data += '\x10\x24\x00\x00'
4372     data += '\x10\x42\x00\x00'
4373     data += '\x10\x54\x00\x08' + 8*'\x00'
4374     data += '\x10\x11\x00\x00'
4375     data += '\x10\x3c\x00\x01\x00'
4376     data += '\x10\x02\x00\x02\x00\x00'
4377     data += '\x10\x12\x00\x02\x00\x00'
4378     data += '\x10\x09\x00\x02\x00\x00'
4379     data += '\x10\x2d\x00\x04\x00\x00\x00\x00'
4380     dev[0].dump_monitor()
4381     with alloc_fail(dev[0], 1, "wps_er_add_sta_data"):
4382         send_wlanevent(url, uuid, data)
4383         ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=0.1)
4384         if ev is not None:
4385             raise Exception("Unexpected enrollee add event")
4386     send_wlanevent(url, uuid, data)
4387     ev = dev[0].wait_event(["WPS-ER-ENROLLEE-ADD"], timeout=2)
4388     if ev is None:
4389         raise Exception("Enrollee add event not seen")
4390
4391 def test_ap_wps_er_http_proto_no_event_sub_url(dev, apdev):
4392     """WPS ER HTTP protocol testing - no eventSubURL"""
4393     class WPSAPHTTPServer_no_event_sub_url(WPSAPHTTPServer):
4394         def handle_upnp_info(self):
4395             self.wfile.write(gen_upnp_info(eventSubURL=None))
4396     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_event_sub_url,
4397                           no_event_url=True)
4398
4399 def test_ap_wps_er_http_proto_event_sub_url_dns(dev, apdev):
4400     """WPS ER HTTP protocol testing - DNS name in eventSubURL"""
4401     class WPSAPHTTPServer_event_sub_url_dns(WPSAPHTTPServer):
4402         def handle_upnp_info(self):
4403             self.wfile.write(gen_upnp_info(eventSubURL='http://example.com/wps_event'))
4404     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_event_sub_url_dns,
4405                           no_event_url=True)
4406
4407 def test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4408     """WPS ER HTTP protocol testing - subscribe OOM"""
4409     try:
4410         _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev)
4411     finally:
4412         dev[0].request("WPS_ER_STOP")
4413
4414 def _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4415     tests = [ (1, "http_client_url_parse"),
4416               (1, "wpabuf_alloc;wps_er_subscribe"),
4417               (1, "http_client_addr"),
4418               (1, "eloop_register_sock;http_client_addr"),
4419               (1, "eloop_register_timeout;http_client_addr") ]
4420     for count,func in tests:
4421         with alloc_fail(dev[0], count, func):
4422             server,sock = wps_er_start(dev[0], WPSAPHTTPServer)
4423             server.handle_request()
4424             server.handle_request()
4425             wps_er_stop(dev[0], sock, server, on_alloc_fail=True)
4426
4427 def test_ap_wps_er_http_proto_no_sid(dev, apdev):
4428     """WPS ER HTTP protocol testing - no SID"""
4429     class WPSAPHTTPServer_no_sid(WPSAPHTTPServer):
4430         def handle_wps_event(self):
4431             self.wfile.write(gen_wps_event(sid=None))
4432     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_sid)
4433
4434 def test_ap_wps_er_http_proto_invalid_sid_no_uuid(dev, apdev):
4435     """WPS ER HTTP protocol testing - invalid SID - no UUID"""
4436     class WPSAPHTTPServer_invalid_sid_no_uuid(WPSAPHTTPServer):
4437         def handle_wps_event(self):
4438             self.wfile.write(gen_wps_event(sid='FOO'))
4439     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_no_uuid)
4440
4441 def test_ap_wps_er_http_proto_invalid_sid_uuid(dev, apdev):
4442     """WPS ER HTTP protocol testing - invalid SID UUID"""
4443     class WPSAPHTTPServer_invalid_sid_uuid(WPSAPHTTPServer):
4444         def handle_wps_event(self):
4445             self.wfile.write(gen_wps_event(sid='uuid:FOO'))
4446     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_uuid)
4447
4448 def test_ap_wps_er_http_proto_subscribe_failing(dev, apdev):
4449     """WPS ER HTTP protocol testing - SUBSCRIBE failing"""
4450     class WPSAPHTTPServer_fail_subscribe(WPSAPHTTPServer):
4451         def handle_wps_event(self):
4452             payload = ""
4453             hdr = 'HTTP/1.1 404 Not Found\r\n' + \
4454                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4455                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4456                   'Connection: close\r\n' + \
4457                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4458                   'Timeout: Second-1801\r\n' + \
4459                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4460             self.wfile.write(hdr + payload)
4461     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_fail_subscribe)
4462
4463 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4464     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4465     class WPSAPHTTPServer_subscribe_invalid_response(WPSAPHTTPServer):
4466         def handle_wps_event(self):
4467             payload = ""
4468             hdr = 'HTTP/1.1 FOO\r\n' + \
4469                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4470                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4471                   'Connection: close\r\n' + \
4472                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4473                   'Timeout: Second-1801\r\n' + \
4474                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4475             self.wfile.write(hdr + payload)
4476     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_subscribe_invalid_response)
4477
4478 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4479     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4480     class WPSAPHTTPServer_invalid_m1(WPSAPHTTPServer):
4481         def handle_wps_control(self):
4482             payload = '''<?xml version="1.0"?>
4483 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
4484 <s:Body>
4485 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
4486 <NewDeviceInfo>Rk9P</NewDeviceInfo>
4487 </u:GetDeviceInfoResponse>
4488 </s:Body>
4489 </s:Envelope>
4490 '''
4491             self.wfile.write(gen_wps_control(payload_override=payload))
4492     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_m1, no_event_url=True)
4493
4494 def test_ap_wps_er_http_proto_upnp_info_no_device(dev, apdev):
4495     """WPS ER HTTP protocol testing - No device in UPnP info"""
4496     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4497         def handle_upnp_info(self):
4498             payload = '''<?xml version="1.0"?>
4499 <root xmlns="urn:schemas-upnp-org:device-1-0">
4500 <specVersion>
4501 <major>1</major>
4502 <minor>0</minor>
4503 </specVersion>
4504 </root>
4505 '''
4506             hdr = 'HTTP/1.1 200 OK\r\n' + \
4507                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4508                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4509                   'Connection: close\r\n' + \
4510                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4511                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4512             self.wfile.write(hdr + payload)
4513     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4514
4515 def test_ap_wps_er_http_proto_upnp_info_no_device_type(dev, apdev):
4516     """WPS ER HTTP protocol testing - No deviceType in UPnP info"""
4517     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4518         def handle_upnp_info(self):
4519             payload = '''<?xml version="1.0"?>
4520 <root xmlns="urn:schemas-upnp-org:device-1-0">
4521 <specVersion>
4522 <major>1</major>
4523 <minor>0</minor>
4524 </specVersion>
4525 <device>
4526 </device>
4527 </root>
4528 '''
4529             hdr = 'HTTP/1.1 200 OK\r\n' + \
4530                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4531                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4532                   'Connection: close\r\n' + \
4533                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4534                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4535             self.wfile.write(hdr + payload)
4536     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4537
4538 def test_ap_wps_er_http_proto_upnp_info_invalid_udn_uuid(dev, apdev):
4539     """WPS ER HTTP protocol testing - Invalid UDN UUID"""
4540     class WPSAPHTTPServer_invalid_udn_uuid(WPSAPHTTPServer):
4541         def handle_upnp_info(self):
4542             self.wfile.write(gen_upnp_info(udn='uuid:foo'))
4543     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_udn_uuid)
4544
4545 def test_ap_wps_er_http_proto_no_control_url(dev, apdev):
4546     """WPS ER HTTP protocol testing - no controlURL"""
4547     class WPSAPHTTPServer_no_control_url(WPSAPHTTPServer):
4548         def handle_upnp_info(self):
4549             self.wfile.write(gen_upnp_info(controlURL=None))
4550     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_control_url,
4551                           no_event_url=True)
4552
4553 def test_ap_wps_er_http_proto_control_url_dns(dev, apdev):
4554     """WPS ER HTTP protocol testing - DNS name in controlURL"""
4555     class WPSAPHTTPServer_control_url_dns(WPSAPHTTPServer):
4556         def handle_upnp_info(self):
4557             self.wfile.write(gen_upnp_info(controlURL='http://example.com/wps_control'))
4558     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_control_url_dns,
4559                           no_event_url=True)
4560
4561 def test_ap_wps_http_timeout(dev, apdev):
4562     """WPS AP/ER and HTTP timeout"""
4563     try:
4564         _test_ap_wps_http_timeout(dev, apdev)
4565     finally:
4566         dev[0].request("WPS_ER_STOP")
4567
4568 def _test_ap_wps_http_timeout(dev, apdev):
4569     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
4570     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
4571
4572     location = ssdp_get_location(ap_uuid)
4573     url = urlparse.urlparse(location)
4574     addr = (url.hostname, url.port)
4575     logger.debug("Open HTTP connection to hostapd, but do not complete request")
4576     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4577                          socket.IPPROTO_TCP)
4578     sock.connect(addr)
4579     sock.send("G")
4580
4581     class DummyServer(SocketServer.StreamRequestHandler):
4582         def handle(self):
4583             logger.debug("DummyServer - start 31 sec wait")
4584             time.sleep(31)
4585             logger.debug("DummyServer - wait done")
4586
4587     logger.debug("Start WPS ER")
4588     server,sock2 = wps_er_start(dev[0], DummyServer, max_age=40,
4589                                 wait_m_search=True)
4590
4591     logger.debug("Start server to accept, but not complete, HTTP connection from WPS ER")
4592     # This will wait for 31 seconds..
4593     server.handle_request()
4594
4595     logger.debug("Complete HTTP connection with hostapd (that should have already closed the connection)")
4596     try:
4597         sock.send("ET / HTTP/1.1\r\n\r\n")
4598         res = sock.recv(100)
4599         sock.close()
4600     except:
4601         pass
4602
4603 def test_ap_wps_er_url_parse(dev, apdev):
4604     """WPS ER and URL parsing special cases"""
4605     try:
4606         _test_ap_wps_er_url_parse(dev, apdev)
4607     finally:
4608         dev[0].request("WPS_ER_STOP")
4609
4610 def _test_ap_wps_er_url_parse(dev, apdev):
4611     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4612     sock.settimeout(1)
4613     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4614     sock.bind(("239.255.255.250", 1900))
4615     dev[0].request("WPS_ER_START ifname=lo")
4616     (msg,addr) = sock.recvfrom(1000)
4617     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4618     if "M-SEARCH" not in msg:
4619         raise Exception("Not an M-SEARCH")
4620     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)
4621     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4622     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)
4623     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4624     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)
4625     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4626
4627     sock.close()
4628
4629 def test_ap_wps_er_link_update(dev, apdev):
4630     """WPS ER and link update special cases"""
4631     class WPSAPHTTPServer_link_update(WPSAPHTTPServer):
4632         def handle_upnp_info(self):
4633             self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4634     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update)
4635
4636     class WPSAPHTTPServer_link_update2(WPSAPHTTPServer):
4637         def handle_others(self, data):
4638             if "GET / " in data:
4639                 self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4640     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update2,
4641                           location_url='http://127.0.0.1:12345')
4642
4643 def test_ap_wps_er_http_client(dev, apdev):
4644     """WPS ER and HTTP client special cases"""
4645     with alloc_fail(dev[0], 1, "http_link_update"):
4646         run_wps_er_proto_test(dev[0], WPSAPHTTPServer)
4647
4648     with alloc_fail(dev[0], 1, "wpabuf_alloc;http_client_url"):
4649         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4650
4651     with alloc_fail(dev[0], 1, "httpread_create;http_client_tx_ready"):
4652         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4653
4654     class WPSAPHTTPServer_req_as_resp(WPSAPHTTPServer):
4655         def handle_upnp_info(self):
4656             self.wfile.write("GET / HTTP/1.1\r\n\r\n")
4657     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_req_as_resp,
4658                           no_event_url=True)
4659
4660 def test_ap_wps_init_oom(dev, apdev):
4661     """wps_init OOM cases"""
4662     ssid = "test-wps"
4663     appin = "12345670"
4664     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4665                "ap_pin": appin }
4666     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4667     pin = dev[0].wps_read_pin()
4668
4669     with alloc_fail(hapd, 1, "wps_init"):
4670         hapd.request("WPS_PIN any " + pin)
4671         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4672         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4673         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4674         if ev is None:
4675             raise Exception("No EAP failure reported")
4676         dev[0].request("WPS_CANCEL")
4677
4678     with alloc_fail(dev[0], 2, "wps_init"):
4679         hapd.request("WPS_PIN any " + pin)
4680         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4681         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4682         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4683         if ev is None:
4684             raise Exception("No EAP failure reported")
4685         dev[0].request("WPS_CANCEL")
4686
4687     with alloc_fail(dev[0], 2, "wps_init"):
4688         hapd.request("WPS_PBC")
4689         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4690         dev[0].request("WPS_PBC %s" % (apdev[0]['bssid']))
4691         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4692         if ev is None:
4693             raise Exception("No EAP failure reported")
4694         dev[0].request("WPS_CANCEL")
4695
4696     dev[0].dump_monitor()
4697     new_ssid = "wps-new-ssid"
4698     new_passphrase = "1234567890"
4699     with alloc_fail(dev[0], 3, "wps_init"):
4700         dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
4701                        new_passphrase, no_wait=True)
4702         ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4703         if ev is None:
4704             raise Exception("No EAP failure reported")
4705
4706     dev[0].flush_scan_cache()
4707
4708 def test_ap_wps_invalid_assoc_req_elem(dev, apdev):
4709     """WPS and invalid IE in Association Request frame"""
4710     ssid = "test-wps"
4711     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4712     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4713     pin = "12345670"
4714     hapd.request("WPS_PIN any " + pin)
4715     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4716     try:
4717         dev[0].request("VENDOR_ELEM_ADD 13 dd050050f20410")
4718         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4719         for i in range(5):
4720             ev = hapd.wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
4721             if ev and "vendor=14122" in ev:
4722                 break
4723         if ev is None or "vendor=14122" not in ev:
4724             raise Exception("EAP-WSC not started")
4725         dev[0].request("WPS_CANCEL")
4726     finally:
4727         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
4728
4729 def test_ap_wps_pbc_pin_mismatch(dev, apdev):
4730     """WPS PBC/PIN mismatch"""
4731     ssid = "test-wps"
4732     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4733     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4734     hapd.request("SET wps_version_number 0x10")
4735     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4736     hapd.request("WPS_PBC")
4737     pin = dev[0].wps_read_pin()
4738     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4739     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4740     if ev is None:
4741         raise Exception("Scan did not complete")
4742     dev[0].request("WPS_CANCEL")
4743
4744     hapd.request("WPS_CANCEL")
4745     dev[0].flush_scan_cache()
4746
4747 def test_ap_wps_ie_invalid(dev, apdev):
4748     """WPS PIN attempt with AP that has invalid WSC IE"""
4749     ssid = "test-wps"
4750     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4751                "vendor_elements": "dd050050f20410" }
4752     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4753     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4754     hostapd.add_ap(apdev[1]['ifname'], params)
4755     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4756     pin = dev[0].wps_read_pin()
4757     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4758     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4759     if ev is None:
4760         raise Exception("Scan did not complete")
4761     dev[0].request("WPS_CANCEL")
4762
4763 def test_ap_wps_scan_prio_order(dev, apdev):
4764     """WPS scan priority ordering"""
4765     ssid = "test-wps"
4766     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4767     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4768     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4769     hostapd.add_ap(apdev[1]['ifname'], params)
4770     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4771     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4772     pin = dev[0].wps_read_pin()
4773     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4774     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4775     if ev is None:
4776         raise Exception("Scan did not complete")
4777     dev[0].request("WPS_CANCEL")
4778
4779 def test_ap_wps_probe_req_ie_oom(dev, apdev):
4780     """WPS ProbeReq IE OOM"""
4781     ssid = "test-wps"
4782     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4783     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4784     pin = dev[0].wps_read_pin()
4785     hapd.request("WPS_PIN any " + pin)
4786     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4787     with alloc_fail(dev[0], 1, "wps_build_probe_req_ie"):
4788         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4789         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4790         if ev is None:
4791             raise Exception("Association not seen")
4792     dev[0].request("WPS_CANCEL")
4793
4794     with alloc_fail(dev[0], 1, "wps_ie_encapsulate"):
4795         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4796         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4797         if ev is None:
4798             raise Exception("Association not seen")
4799     dev[0].request("WPS_CANCEL")
4800
4801 def test_ap_wps_assoc_req_ie_oom(dev, apdev):
4802     """WPS AssocReq IE OOM"""
4803     ssid = "test-wps"
4804     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4805     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4806     pin = dev[0].wps_read_pin()
4807     hapd.request("WPS_PIN any " + pin)
4808     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4809     with alloc_fail(dev[0], 1, "wps_build_assoc_req_ie"):
4810         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4811         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4812         if ev is None:
4813             raise Exception("Association not seen")
4814     dev[0].request("WPS_CANCEL")
4815
4816 def test_ap_wps_assoc_resp_ie_oom(dev, apdev):
4817     """WPS AssocResp IE OOM"""
4818     ssid = "test-wps"
4819     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4820     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4821     pin = dev[0].wps_read_pin()
4822     hapd.request("WPS_PIN any " + pin)
4823     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4824     with alloc_fail(hapd, 1, "wps_build_assoc_resp_ie"):
4825         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4826         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4827         if ev is None:
4828             raise Exception("Association not seen")
4829     dev[0].request("WPS_CANCEL")
4830
4831 def test_ap_wps_bss_info_errors(dev, apdev):
4832     """WPS BSS info errors"""
4833     params = { "ssid": "1",
4834                "vendor_elements": "dd0e0050f20410440001ff101100010a" }
4835     hostapd.add_ap(apdev[0]['ifname'], params)
4836     params = { 'ssid': "2", "vendor_elements": "dd050050f20410" }
4837     hostapd.add_ap(apdev[1]['ifname'], params)
4838     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4839     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4840     bss = dev[0].get_bss(apdev[0]['bssid'])
4841     logger.info("BSS: " + str(bss))
4842     if "wps_state" in bss:
4843         raise Exception("Unexpected wps_state in BSS info")
4844     if 'wps_device_name' not in bss:
4845         raise Exception("No wps_device_name in BSS info")
4846     if bss['wps_device_name'] != '_':
4847         raise Exception("Unexpected wps_device_name value")
4848     bss = dev[0].get_bss(apdev[1]['bssid'])
4849     logger.info("BSS: " + str(bss))
4850
4851     with alloc_fail(dev[0], 1, "=wps_attr_text"):
4852         bss = dev[0].get_bss(apdev[0]['bssid'])
4853         logger.info("BSS(OOM): " + str(bss))
4854
4855 def wps_run_pbc_fail_ap(apdev, dev, hapd):
4856     hapd.request("WPS_PBC")
4857     dev.scan_for_bss(apdev['bssid'], freq="2412")
4858     dev.request("WPS_PBC " + apdev['bssid'])
4859     ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4860     if ev is None:
4861         raise Exception("No EAP failure reported")
4862     dev.request("WPS_CANCEL")
4863     dev.wait_disconnected()
4864     for i in range(5):
4865         try:
4866             dev.flush_scan_cache()
4867             break
4868         except Exception, e:
4869             if str(e).startswith("Failed to trigger scan"):
4870                 # Try again
4871                 time.sleep(1)
4872             else:
4873                 raise
4874
4875 def wps_run_pbc_fail(apdev, dev):
4876     hapd = wps_start_ap(apdev)
4877     wps_run_pbc_fail_ap(apdev, dev, hapd)
4878
4879 def test_ap_wps_pk_oom(dev, apdev):
4880     """WPS and public key OOM"""
4881     with alloc_fail(dev[0], 1, "wps_build_public_key"):
4882         wps_run_pbc_fail(apdev[0], dev[0])
4883
4884 def test_ap_wps_pk_oom_ap(dev, apdev):
4885     """WPS and public key OOM on AP"""
4886     hapd = wps_start_ap(apdev[0])
4887     with alloc_fail(hapd, 1, "wps_build_public_key"):
4888         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4889
4890 def test_ap_wps_encr_oom_ap(dev, apdev):
4891     """WPS and encrypted settings decryption OOM on AP"""
4892     hapd = wps_start_ap(apdev[0])
4893     pin = dev[0].wps_read_pin()
4894     hapd.request("WPS_PIN any " + pin)
4895     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4896     with alloc_fail(hapd, 1, "wps_decrypt_encr_settings"):
4897         dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " " + pin)
4898         ev = hapd.wait_event(["WPS-FAIL"], timeout=10)
4899         if ev is None:
4900             raise Exception("No WPS-FAIL reported")
4901         dev[0].request("WPS_CANCEL")
4902     dev[0].wait_disconnected()
4903
4904 def test_ap_wps_encr_no_random_ap(dev, apdev):
4905     """WPS and no random data available for encryption on AP"""
4906     hapd = wps_start_ap(apdev[0])
4907     with fail_test(hapd, 1, "os_get_random;wps_build_encr_settings"):
4908         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4909
4910 def test_ap_wps_e_hash_no_random_sta(dev, apdev):
4911     """WPS and no random data available for e-hash on STA"""
4912     with fail_test(dev[0], 1, "os_get_random;wps_build_e_hash"):
4913         wps_run_pbc_fail(apdev[0], dev[0])
4914
4915 def test_ap_wps_m1_no_random(dev, apdev):
4916     """WPS and no random for M1 on STA"""
4917     with fail_test(dev[0], 1, "os_get_random;wps_build_m1"):
4918         wps_run_pbc_fail(apdev[0], dev[0])
4919
4920 def test_ap_wps_m1_oom(dev, apdev):
4921     """WPS and OOM for M1 on STA"""
4922     with alloc_fail(dev[0], 1, "wps_build_m1"):
4923         wps_run_pbc_fail(apdev[0], dev[0])
4924
4925 def test_ap_wps_m3_oom(dev, apdev):
4926     """WPS and OOM for M3 on STA"""
4927     with alloc_fail(dev[0], 1, "wps_build_m3"):
4928         wps_run_pbc_fail(apdev[0], dev[0])
4929
4930 def test_ap_wps_m5_oom(dev, apdev):
4931     """WPS and OOM for M5 on STA"""
4932     hapd = wps_start_ap(apdev[0])
4933     hapd.request("WPS_PBC")
4934     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4935     for i in range(1, 3):
4936         with alloc_fail(dev[0], i, "wps_build_m5"):
4937             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4938             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4939             if ev is None:
4940                 raise Exception("No EAP failure reported")
4941             dev[0].request("WPS_CANCEL")
4942             dev[0].wait_disconnected()
4943     dev[0].flush_scan_cache()
4944
4945 def test_ap_wps_m5_no_random(dev, apdev):
4946     """WPS and no random for M5 on STA"""
4947     with fail_test(dev[0], 1,
4948                    "os_get_random;wps_build_encr_settings;wps_build_m5"):
4949         wps_run_pbc_fail(apdev[0], dev[0])
4950
4951 def test_ap_wps_m7_oom(dev, apdev):
4952     """WPS and OOM for M7 on STA"""
4953     hapd = wps_start_ap(apdev[0])
4954     hapd.request("WPS_PBC")
4955     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4956     for i in range(1, 3):
4957         with alloc_fail(dev[0], i, "wps_build_m7"):
4958             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4959             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4960             if ev is None:
4961                 raise Exception("No EAP failure reported")
4962             dev[0].request("WPS_CANCEL")
4963             dev[0].wait_disconnected()
4964     dev[0].flush_scan_cache()
4965
4966 def test_ap_wps_m7_no_random(dev, apdev):
4967     """WPS and no random for M7 on STA"""
4968     with fail_test(dev[0], 1,
4969                    "os_get_random;wps_build_encr_settings;wps_build_m7"):
4970         wps_run_pbc_fail(apdev[0], dev[0])
4971
4972 def test_ap_wps_wsc_done_oom(dev, apdev):
4973     """WPS and OOM for WSC_Done on STA"""
4974     with alloc_fail(dev[0], 1, "wps_build_wsc_done"):
4975         wps_run_pbc_fail(apdev[0], dev[0])
4976
4977 def test_ap_wps_random_psk_fail(dev, apdev):
4978     """WPS and no random for PSK on AP"""
4979     ssid = "test-wps"
4980     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
4981     appin = "12345670"
4982     try:
4983         os.remove(pskfile)
4984     except:
4985         pass
4986
4987     try:
4988         with open(pskfile, "w") as f:
4989             f.write("# WPA PSKs\n")
4990
4991         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4992                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
4993                    "rsn_pairwise": "CCMP", "ap_pin": appin,
4994                    "wpa_psk_file": pskfile }
4995         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4996
4997         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4998         with fail_test(hapd, 1, "os_get_random;wps_build_cred_network_key"):
4999             dev[0].request("WPS_REG " + apdev[0]['bssid'] + " " + appin)
5000             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
5001             if ev is None:
5002                 raise Exception("No EAP failure reported")
5003             dev[0].request("WPS_CANCEL")
5004         dev[0].wait_disconnected()
5005
5006         with fail_test(hapd, 1, "os_get_random;wps_build_cred"):
5007             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5008
5009         with alloc_fail(hapd, 1, "wps_build_cred"):
5010             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5011
5012         with alloc_fail(hapd, 2, "wps_build_cred"):
5013             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
5014     finally:
5015         os.remove(pskfile)
5016
5017 def wps_ext_eap_identity_req(dev, hapd, bssid):
5018     logger.debug("EAP-Identity/Request")
5019     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5020     if ev is None:
5021         raise Exception("Timeout on EAPOL-TX from hostapd")
5022     res = dev.request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
5023     if "OK" not in res:
5024         raise Exception("EAPOL_RX to wpa_supplicant failed")
5025
5026 def wps_ext_eap_identity_resp(hapd, dev, addr):
5027     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
5028     if ev is None:
5029         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
5030     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
5031     if "OK" not in res:
5032         raise Exception("EAPOL_RX to hostapd failed")
5033
5034 def wps_ext_eap_wsc(dst, src, src_addr, msg):
5035     logger.debug(msg)
5036     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5037     if ev is None:
5038         raise Exception("Timeout on EAPOL-TX")
5039     res = dst.request("EAPOL_RX " + src_addr + " " + ev.split(' ')[2])
5040     if "OK" not in res:
5041         raise Exception("EAPOL_RX failed")
5042
5043 def wps_start_ext(apdev, dev, pbc=False, pin=None):
5044     addr = dev.own_addr()
5045     bssid = apdev['bssid']
5046     ssid = "test-wps-conf"
5047     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5048                "wpa_passphrase": "12345678", "wpa": "2",
5049                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
5050     hapd = hostapd.add_ap(apdev['ifname'], params)
5051
5052     if pbc:
5053         hapd.request("WPS_PBC")
5054     else:
5055         if pin is None:
5056             pin = dev.wps_read_pin()
5057         hapd.request("WPS_PIN any " + pin)
5058     dev.scan_for_bss(bssid, freq="2412")
5059     hapd.request("SET ext_eapol_frame_io 1")
5060     dev.request("SET ext_eapol_frame_io 1")
5061
5062     if pbc:
5063         dev.request("WPS_PBC " + bssid)
5064     else:
5065         dev.request("WPS_PIN " + bssid + " " + pin)
5066     return addr,bssid,hapd
5067
5068 def wps_auth_corrupt(dst, src, addr):
5069     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5070     if ev is None:
5071         raise Exception("Timeout on EAPOL-TX")
5072     src.request("SET ext_eapol_frame_io 0")
5073     dst.request("SET ext_eapol_frame_io 0")
5074     msg = ev.split(' ')[2]
5075     if msg[-24:-16] != '10050008':
5076         raise Exception("Could not find Authenticator attribute")
5077     # Corrupt Authenticator value
5078     msg = msg[:-1] + '%x' % ((int(msg[-1], 16) + 1) % 16)
5079     res = dst.request("EAPOL_RX " + addr + " " + msg)
5080     if "OK" not in res:
5081         raise Exception("EAPOL_RX failed")
5082
5083 def wps_fail_finish(hapd, dev, fail_str):
5084     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5085     if ev is None:
5086         raise Exception("WPS-FAIL not indicated")
5087     if fail_str not in ev:
5088         raise Exception("Unexpected WPS-FAIL value: " + ev)
5089     dev.request("WPS_CANCEL")
5090     dev.wait_disconnected()
5091
5092 def wps_auth_corrupt_from_ap(dev, hapd, bssid, fail_str):
5093     wps_auth_corrupt(dev, hapd, bssid)
5094     wps_fail_finish(hapd, dev, fail_str)
5095
5096 def wps_auth_corrupt_to_ap(dev, hapd, addr, fail_str):
5097     wps_auth_corrupt(hapd, dev, addr)
5098     wps_fail_finish(hapd, dev, fail_str)
5099
5100 def test_ap_wps_authenticator_mismatch_m2(dev, apdev):
5101     """WPS and Authenticator attribute mismatch in M2"""
5102     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5103     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5104     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5105     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5106     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5107     logger.debug("M2")
5108     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=5")
5109
5110 def test_ap_wps_authenticator_mismatch_m3(dev, apdev):
5111     """WPS and Authenticator attribute mismatch in M3"""
5112     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5113     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5114     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5115     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5116     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5117     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5118     logger.debug("M3")
5119     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=7")
5120
5121 def test_ap_wps_authenticator_mismatch_m4(dev, apdev):
5122     """WPS and Authenticator attribute mismatch in M4"""
5123     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5124     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5125     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5126     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5127     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5128     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5129     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5130     logger.debug("M4")
5131     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=8")
5132
5133 def test_ap_wps_authenticator_mismatch_m5(dev, apdev):
5134     """WPS and Authenticator attribute mismatch in M5"""
5135     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5136     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5137     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5138     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5139     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5140     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5141     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5142     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5143     logger.debug("M5")
5144     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=9")
5145
5146 def test_ap_wps_authenticator_mismatch_m6(dev, apdev):
5147     """WPS and Authenticator attribute mismatch in M6"""
5148     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5149     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5150     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5151     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5152     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5153     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5154     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5155     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5156     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5157     logger.debug("M6")
5158     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=10")
5159
5160 def test_ap_wps_authenticator_mismatch_m7(dev, apdev):
5161     """WPS and Authenticator attribute mismatch in M7"""
5162     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5163     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5164     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5165     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5166     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5167     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5168     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5169     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5170     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5171     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5172     logger.debug("M7")
5173     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=11")
5174
5175 def test_ap_wps_authenticator_mismatch_m8(dev, apdev):
5176     """WPS and Authenticator attribute mismatch in M8"""
5177     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5178     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5179     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5180     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5181     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5182     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5183     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5184     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5185     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5186     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5187     wps_ext_eap_wsc(hapd, dev[0], addr, "M7")
5188     logger.debug("M8")
5189     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=12")
5190
5191 def test_ap_wps_authenticator_missing_m2(dev, apdev):
5192     """WPS and Authenticator attribute missing from M2"""
5193     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5194     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5195     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5196     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5197     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5198     logger.debug("M2")
5199     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5200     if ev is None:
5201         raise Exception("Timeout on EAPOL-TX")
5202     hapd.request("SET ext_eapol_frame_io 0")
5203     dev[0].request("SET ext_eapol_frame_io 0")
5204     msg = ev.split(' ')[2]
5205     if msg[-24:-16] != '10050008':
5206         raise Exception("Could not find Authenticator attribute")
5207     # Remove Authenticator value
5208     msg = msg[:-24]
5209     mlen = "%04x" % (int(msg[4:8], 16) - 12)
5210     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:]
5211     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5212     if "OK" not in res:
5213         raise Exception("EAPOL_RX failed")
5214     wps_fail_finish(hapd, dev[0], "msg=5")
5215
5216 def test_ap_wps_m2_dev_passwd_id_p2p(dev, apdev):
5217     """WPS and M2 with different Device Password ID (P2P)"""
5218     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5219     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5220     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5221     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5222     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5223     logger.debug("M2")
5224     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5225     if ev is None:
5226         raise Exception("Timeout on EAPOL-TX")
5227     hapd.request("SET ext_eapol_frame_io 0")
5228     dev[0].request("SET ext_eapol_frame_io 0")
5229     msg = ev.split(' ')[2]
5230     if msg[722:730] != '10120002':
5231         raise Exception("Could not find Device Password ID attribute")
5232     # Replace Device Password ID value. This will fail Authenticator check, but
5233     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5234     # log.
5235     msg = msg[0:730] + "0005" + msg[734:]
5236     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5237     if "OK" not in res:
5238         raise Exception("EAPOL_RX failed")
5239     wps_fail_finish(hapd, dev[0], "msg=5")
5240
5241 def test_ap_wps_m2_dev_passwd_id_change_pin_to_pbc(dev, apdev):
5242     """WPS and M2 with different Device Password ID (PIN to PBC)"""
5243     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5244     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5245     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5246     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5247     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5248     logger.debug("M2")
5249     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5250     if ev is None:
5251         raise Exception("Timeout on EAPOL-TX")
5252     hapd.request("SET ext_eapol_frame_io 0")
5253     dev[0].request("SET ext_eapol_frame_io 0")
5254     msg = ev.split(' ')[2]
5255     if msg[722:730] != '10120002':
5256         raise Exception("Could not find Device Password ID attribute")
5257     # Replace Device Password ID value (PIN --> PBC). This will be rejected.
5258     msg = msg[0:730] + "0004" + msg[734:]
5259     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5260     if "OK" not in res:
5261         raise Exception("EAPOL_RX failed")
5262     wps_fail_finish(hapd, dev[0], "msg=5")
5263
5264 def test_ap_wps_m2_dev_passwd_id_change_pbc_to_pin(dev, apdev):
5265     """WPS and M2 with different Device Password ID (PBC to PIN)"""
5266     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5267     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5268     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5269     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5270     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5271     logger.debug("M2")
5272     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5273     if ev is None:
5274         raise Exception("Timeout on EAPOL-TX")
5275     hapd.request("SET ext_eapol_frame_io 0")
5276     dev[0].request("SET ext_eapol_frame_io 0")
5277     msg = ev.split(' ')[2]
5278     if msg[722:730] != '10120002':
5279         raise Exception("Could not find Device Password ID attribute")
5280     # Replace Device Password ID value. This will fail Authenticator check, but
5281     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5282     # log.
5283     msg = msg[0:730] + "0000" + msg[734:]
5284     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5285     if "OK" not in res:
5286         raise Exception("EAPOL_RX failed")
5287     wps_fail_finish(hapd, dev[0], "msg=5")
5288     dev[0].flush_scan_cache()
5289
5290 def test_ap_wps_m2_missing_dev_passwd_id(dev, apdev):
5291     """WPS and M2 without Device Password ID"""
5292     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5293     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5294     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5295     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5296     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5297     logger.debug("M2")
5298     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5299     if ev is None:
5300         raise Exception("Timeout on EAPOL-TX")
5301     hapd.request("SET ext_eapol_frame_io 0")
5302     dev[0].request("SET ext_eapol_frame_io 0")
5303     msg = ev.split(' ')[2]
5304     if msg[722:730] != '10120002':
5305         raise Exception("Could not find Device Password ID attribute")
5306     # Remove Device Password ID value. This will fail Authenticator check, but
5307     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5308     # log.
5309     mlen = "%04x" % (int(msg[4:8], 16) - 6)
5310     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:722] + msg[734:]
5311     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5312     if "OK" not in res:
5313         raise Exception("EAPOL_RX failed")
5314     wps_fail_finish(hapd, dev[0], "msg=5")
5315
5316 def test_ap_wps_m2_missing_registrar_nonce(dev, apdev):
5317     """WPS and M2 without Registrar Nonce"""
5318     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5319     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5320     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5321     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5322     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5323     logger.debug("M2")
5324     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5325     if ev is None:
5326         raise Exception("Timeout on EAPOL-TX")
5327     hapd.request("SET ext_eapol_frame_io 0")
5328     dev[0].request("SET ext_eapol_frame_io 0")
5329     msg = ev.split(' ')[2]
5330     if msg[96:104] != '10390010':
5331         raise Exception("Could not find Registrar Nonce attribute")
5332     # Remove Registrar Nonce. This will fail Authenticator check, but
5333     # allows the code path in wps_process_registrar_nonce() to be checked from
5334     # the debug log.
5335     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5336     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:96] + msg[136:]
5337     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5338     if "OK" not in res:
5339         raise Exception("EAPOL_RX failed")
5340     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5341     if ev is None:
5342         raise Exception("Disconnect event not seen")
5343     dev[0].request("WPS_CANCEL")
5344     dev[0].flush_scan_cache()
5345
5346 def test_ap_wps_m2_missing_enrollee_nonce(dev, apdev):
5347     """WPS and M2 without Enrollee Nonce"""
5348     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5349     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5350     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5351     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5352     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5353     logger.debug("M2")
5354     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5355     if ev is None:
5356         raise Exception("Timeout on EAPOL-TX")
5357     hapd.request("SET ext_eapol_frame_io 0")
5358     dev[0].request("SET ext_eapol_frame_io 0")
5359     msg = ev.split(' ')[2]
5360     if msg[56:64] != '101a0010':
5361         raise Exception("Could not find enrollee Nonce attribute")
5362     # Remove Enrollee Nonce. This will fail Authenticator check, but
5363     # allows the code path in wps_process_enrollee_nonce() to be checked from
5364     # the debug log.
5365     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5366     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:56] + msg[96:]
5367     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5368     if "OK" not in res:
5369         raise Exception("EAPOL_RX failed")
5370     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5371     if ev is None:
5372         raise Exception("Disconnect event not seen")
5373     dev[0].request("WPS_CANCEL")
5374     dev[0].flush_scan_cache()
5375
5376 def test_ap_wps_m2_missing_uuid_r(dev, apdev):
5377     """WPS and M2 without UUID-R"""
5378     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5379     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5380     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5381     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5382     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5383     logger.debug("M2")
5384     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5385     if ev is None:
5386         raise Exception("Timeout on EAPOL-TX")
5387     hapd.request("SET ext_eapol_frame_io 0")
5388     dev[0].request("SET ext_eapol_frame_io 0")
5389     msg = ev.split(' ')[2]
5390     if msg[136:144] != '10480010':
5391         raise Exception("Could not find enrollee Nonce attribute")
5392     # Remove UUID-R. This will fail Authenticator check, but allows the code
5393     # path in wps_process_uuid_r() to be checked from the debug log.
5394     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5395     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:136] + msg[176:]
5396     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5397     if "OK" not in res:
5398         raise Exception("EAPOL_RX failed")
5399     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5400     if ev is None:
5401         raise Exception("Disconnect event not seen")
5402     dev[0].request("WPS_CANCEL")
5403     dev[0].flush_scan_cache()
5404
5405 def test_ap_wps_m2_invalid(dev, apdev):
5406     """WPS and M2 parsing failure"""
5407     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5408     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5409     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5410     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5411     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5412     logger.debug("M2")
5413     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5414     if ev is None:
5415         raise Exception("Timeout on EAPOL-TX")
5416     hapd.request("SET ext_eapol_frame_io 0")
5417     dev[0].request("SET ext_eapol_frame_io 0")
5418     msg = ev.split(' ')[2]
5419     if msg[136:144] != '10480010':
5420         raise Exception("Could not find enrollee Nonce attribute")
5421     # Remove UUID-R. This will fail Authenticator check, but allows the code
5422     # path in wps_process_uuid_r() to be checked from the debug log.
5423     mlen = "%04x" % (int(msg[4:8], 16) - 1)
5424     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:-2]
5425     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5426     if "OK" not in res:
5427         raise Exception("EAPOL_RX failed")
5428     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5429     if ev is None:
5430         raise Exception("Disconnect event not seen")
5431     dev[0].request("WPS_CANCEL")
5432     dev[0].flush_scan_cache()
5433
5434 def test_ap_wps_m2_missing_msg_type(dev, apdev):
5435     """WPS and M2 without Message Type"""
5436     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5437     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5438     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5439     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5440     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5441     logger.debug("M2")
5442     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5443     if ev is None:
5444         raise Exception("Timeout on EAPOL-TX")
5445     hapd.request("SET ext_eapol_frame_io 0")
5446     dev[0].request("SET ext_eapol_frame_io 0")
5447     msg = ev.split(' ')[2]
5448     if msg[46:54] != '10220001':
5449         raise Exception("Could not find Message Type attribute")
5450     # Remove Message Type. This will fail Authenticator check, but allows the
5451     # code path in wps_process_wsc_msg() to be checked from the debug log.
5452     mlen = "%04x" % (int(msg[4:8], 16) - 5)
5453     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:46] + msg[56:]
5454     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5455     if "OK" not in res:
5456         raise Exception("EAPOL_RX failed")
5457     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5458     if ev is None:
5459         raise Exception("Disconnect event not seen")
5460     dev[0].request("WPS_CANCEL")
5461     dev[0].flush_scan_cache()
5462
5463 def test_ap_wps_m2_unknown_msg_type(dev, apdev):
5464     """WPS and M2 but unknown Message Type"""
5465     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5466     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5467     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5468     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5469     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5470     logger.debug("M2")
5471     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5472     if ev is None:
5473         raise Exception("Timeout on EAPOL-TX")
5474     hapd.request("SET ext_eapol_frame_io 0")
5475     dev[0].request("SET ext_eapol_frame_io 0")
5476     msg = ev.split(' ')[2]
5477     if msg[46:54] != '10220001':
5478         raise Exception("Could not find Message Type attribute")
5479     # Replace Message Type value. This will be rejected.
5480     msg = msg[0:54] + "00" + msg[56:]
5481     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5482     if "OK" not in res:
5483         raise Exception("EAPOL_RX failed")
5484     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5485     if ev is None:
5486         raise Exception("Disconnect event not seen")
5487     dev[0].request("WPS_CANCEL")
5488     dev[0].flush_scan_cache()
5489
5490 def test_ap_wps_m2_unknown_opcode(dev, apdev):
5491     """WPS and M2 but unknown opcode"""
5492     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5493     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5494     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5495     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5496     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5497     logger.debug("M2")
5498     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5499     if ev is None:
5500         raise Exception("Timeout on EAPOL-TX")
5501     hapd.request("SET ext_eapol_frame_io 0")
5502     dev[0].request("SET ext_eapol_frame_io 0")
5503     msg = ev.split(' ')[2]
5504     # Replace opcode. This will be discarded in EAP-WSC processing.
5505     msg = msg[0:32] + "00" + msg[34:]
5506     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5507     if "OK" not in res:
5508         raise Exception("EAPOL_RX failed")
5509     dev[0].request("WPS_CANCEL")
5510     dev[0].wait_disconnected()
5511     dev[0].flush_scan_cache()
5512
5513 def test_ap_wps_m2_unknown_opcode2(dev, apdev):
5514     """WPS and M2 but unknown opcode (WSC_Start)"""
5515     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5516     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5517     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5518     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5519     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5520     logger.debug("M2")
5521     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5522     if ev is None:
5523         raise Exception("Timeout on EAPOL-TX")
5524     hapd.request("SET ext_eapol_frame_io 0")
5525     dev[0].request("SET ext_eapol_frame_io 0")
5526     msg = ev.split(' ')[2]
5527     # Replace opcode. This will be discarded in EAP-WSC processing.
5528     msg = msg[0:32] + "01" + msg[34:]
5529     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5530     if "OK" not in res:
5531         raise Exception("EAPOL_RX failed")
5532     dev[0].request("WPS_CANCEL")
5533     dev[0].wait_disconnected()
5534     dev[0].flush_scan_cache()
5535
5536 def test_ap_wps_m2_unknown_opcode3(dev, apdev):
5537     """WPS and M2 but unknown opcode (WSC_Done)"""
5538     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5539     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5540     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5541     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5542     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5543     logger.debug("M2")
5544     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5545     if ev is None:
5546         raise Exception("Timeout on EAPOL-TX")
5547     hapd.request("SET ext_eapol_frame_io 0")
5548     dev[0].request("SET ext_eapol_frame_io 0")
5549     msg = ev.split(' ')[2]
5550     # Replace opcode. This will be discarded in WPS Enrollee processing.
5551     msg = msg[0:32] + "05" + msg[34:]
5552     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5553     if "OK" not in res:
5554         raise Exception("EAPOL_RX failed")
5555     dev[0].request("WPS_CANCEL")
5556     dev[0].wait_disconnected()
5557     dev[0].flush_scan_cache()
5558
5559 def wps_m2_but_other(dev, apdev, title, msgtype):
5560     addr,bssid,hapd = wps_start_ext(apdev, dev)
5561     wps_ext_eap_identity_req(dev, hapd, bssid)
5562     wps_ext_eap_identity_resp(hapd, dev, addr)
5563     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5564     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5565     logger.debug(title)
5566     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5567     if ev is None:
5568         raise Exception("Timeout on EAPOL-TX")
5569     hapd.request("SET ext_eapol_frame_io 0")
5570     dev.request("SET ext_eapol_frame_io 0")
5571     msg = ev.split(' ')[2]
5572     if msg[46:54] != '10220001':
5573         raise Exception("Could not find Message Type attribute")
5574     # Replace Message Type value. This will be rejected.
5575     msg = msg[0:54] + msgtype + msg[56:]
5576     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5577     if "OK" not in res:
5578         raise Exception("EAPOL_RX failed")
5579     ev = dev.wait_event(["WPS-FAIL"], timeout=5)
5580     if ev is None:
5581         raise Exception("WPS-FAIL event not seen")
5582     dev.request("WPS_CANCEL")
5583     dev.wait_disconnected()
5584
5585 def wps_m4_but_other(dev, apdev, title, msgtype):
5586     addr,bssid,hapd = wps_start_ext(apdev, dev)
5587     wps_ext_eap_identity_req(dev, hapd, bssid)
5588     wps_ext_eap_identity_resp(hapd, dev, addr)
5589     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5590     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5591     wps_ext_eap_wsc(dev, hapd, bssid, "M2")
5592     wps_ext_eap_wsc(hapd, dev, addr, "M3")
5593     logger.debug(title)
5594     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5595     if ev is None:
5596         raise Exception("Timeout on EAPOL-TX")
5597     hapd.request("SET ext_eapol_frame_io 0")
5598     dev.request("SET ext_eapol_frame_io 0")
5599     msg = ev.split(' ')[2]
5600     if msg[46:54] != '10220001':
5601         raise Exception("Could not find Message Type attribute")
5602     # Replace Message Type value. This will be rejected.
5603     msg = msg[0:54] + msgtype + msg[56:]
5604     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5605     if "OK" not in res:
5606         raise Exception("EAPOL_RX failed")
5607     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5608     if ev is None:
5609         raise Exception("WPS-FAIL event not seen")
5610     dev.request("WPS_CANCEL")
5611     dev.wait_disconnected()
5612
5613 def test_ap_wps_m2_msg_type_m4(dev, apdev):
5614     """WPS and M2 but Message Type M4"""
5615     wps_m2_but_other(dev[0], apdev[0], "M2/M4", "08")
5616
5617 def test_ap_wps_m2_msg_type_m6(dev, apdev):
5618     """WPS and M2 but Message Type M6"""
5619     wps_m2_but_other(dev[0], apdev[0], "M2/M6", "0a")
5620
5621 def test_ap_wps_m2_msg_type_m8(dev, apdev):
5622     """WPS and M2 but Message Type M8"""
5623     wps_m2_but_other(dev[0], apdev[0], "M2/M8", "0c")
5624
5625 def test_ap_wps_m4_msg_type_m2(dev, apdev):
5626     """WPS and M4 but Message Type M2"""
5627     wps_m4_but_other(dev[0], apdev[0], "M4/M2", "05")
5628
5629 def test_ap_wps_m4_msg_type_m2d(dev, apdev):
5630     """WPS and M4 but Message Type M2D"""
5631     wps_m4_but_other(dev[0], apdev[0], "M4/M2D", "06")
5632
5633 def test_ap_wps_config_methods(dev, apdev):
5634     """WPS configuration method parsing"""
5635     ssid = "test-wps-conf"
5636     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5637                "wpa_passphrase": "12345678", "wpa": "2",
5638                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5639                "config_methods": "ethernet display ext_nfc_token int_nfc_token physical_display physical_push_button" }
5640     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
5641     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5642                "wpa_passphrase": "12345678", "wpa": "2",
5643                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5644                "config_methods": "display push_button" }
5645     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
5646
5647 def test_ap_wps_set_selected_registrar_proto(dev, apdev):
5648     """WPS UPnP SetSelectedRegistrar protocol testing"""
5649     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5650     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5651
5652     location = ssdp_get_location(ap_uuid)
5653     urls = upnp_get_urls(location)
5654     eventurl = urlparse.urlparse(urls['event_sub_url'])
5655     ctrlurl = urlparse.urlparse(urls['control_url'])
5656     url = urlparse.urlparse(location)
5657     conn = httplib.HTTPConnection(url.netloc)
5658
5659     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
5660         def handle(self):
5661             data = self.rfile.readline().strip()
5662             logger.debug(data)
5663             self.wfile.write(gen_wps_event())
5664
5665     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
5666     server.timeout = 1
5667
5668     headers = { "callback": '<http://127.0.0.1:12345/event>',
5669                 "NT": "upnp:event",
5670                 "timeout": "Second-1234" }
5671     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
5672     resp = conn.getresponse()
5673     if resp.status != 200:
5674         raise Exception("Unexpected HTTP response: %d" % resp.status)
5675     sid = resp.getheader("sid")
5676     logger.debug("Subscription SID " + sid)
5677     server.handle_request()
5678
5679     tests = [ (500, "10"),
5680               (200, "104a000110" + "1041000101" + "101200020000" +
5681                "105300023148" +
5682                "1049002c00372a0001200124111111111111222222222222333333333333444444444444555555555555666666666666" +
5683                "10480010362db47ba53a519188fb5458b986b2e4"),
5684               (200, "104a000110" + "1041000100" + "101200020000" +
5685                "105300020000"),
5686               (200, "104a000110" + "1041000100"),
5687               (200, "104a000110") ]
5688     for status,test in tests:
5689         tlvs = binascii.unhexlify(test)
5690         newmsg = base64.b64encode(tlvs)
5691         msg = '<?xml version="1.0"?>\n'
5692         msg += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
5693         msg += '<s:Body>'
5694         msg += '<u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">'
5695         msg += '<NewMessage>'
5696         msg += newmsg
5697         msg += "</NewMessage></u:SetSelectedRegistrar></s:Body></s:Envelope>"
5698         headers = { "Content-type": 'text/xml; charset="utf-8"' }
5699         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
5700         conn.request("POST", ctrlurl.path, msg, headers)
5701         resp = conn.getresponse()
5702         if resp.status != status:
5703             raise Exception("Unexpected HTTP response: %d (expected %d)" % (resp.status, status))
5704
5705 def test_ap_wps_adv_oom(dev, apdev):
5706     """WPS AP and advertisement OOM"""
5707     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5708     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5709
5710     with alloc_fail(hapd, 1, "=msearchreply_state_machine_start"):
5711         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5712                           no_recv=True)
5713         time.sleep(0.2)
5714
5715     with alloc_fail(hapd, 1, "eloop_register_timeout;msearchreply_state_machine_start"):
5716         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5717                           no_recv=True)
5718         time.sleep(0.2)
5719
5720     with alloc_fail(hapd, 1,
5721                     "next_advertisement;advertisement_state_machine_stop"):
5722         hapd.disable()
5723
5724     with alloc_fail(hapd, 1, "ssdp_listener_start"):
5725         if "FAIL" not in hapd.request("ENABLE"):
5726             raise Exception("ENABLE succeeded during OOM")
5727
5728 def test_wps_config_methods(dev):
5729     """WPS config method update"""
5730     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
5731     wpas.interface_add("wlan5")
5732     if "OK" not in wpas.request("SET config_methods display label"):
5733         raise Exception("Failed to set config_methods")
5734     if wpas.request("GET config_methods").strip() != "display label":
5735         raise Exception("config_methods were not updated")
5736     if "OK" not in wpas.request("SET config_methods "):
5737         raise Exception("Failed to clear config_methods")
5738     if wpas.request("GET config_methods").strip() != "":
5739         raise Exception("config_methods were not cleared")
5740
5741 WPS_VENDOR_ID_WFA = 14122
5742 WPS_VENDOR_TYPE = 1
5743
5744 # EAP-WSC Op-Code values
5745 WSC_Start = 0x01
5746 WSC_ACK = 0x02
5747 WSC_NACK = 0x03
5748 WSC_MSG = 0x04
5749 WSC_Done = 0x05
5750 WSC_FRAG_ACK = 0x06
5751
5752 ATTR_AP_CHANNEL = 0x1001
5753 ATTR_ASSOC_STATE = 0x1002
5754 ATTR_AUTH_TYPE = 0x1003
5755 ATTR_AUTH_TYPE_FLAGS = 0x1004
5756 ATTR_AUTHENTICATOR = 0x1005
5757 ATTR_CONFIG_METHODS = 0x1008
5758 ATTR_CONFIG_ERROR = 0x1009
5759 ATTR_CONFIRM_URL4 = 0x100a
5760 ATTR_CONFIRM_URL6 = 0x100b
5761 ATTR_CONN_TYPE = 0x100c
5762 ATTR_CONN_TYPE_FLAGS = 0x100d
5763 ATTR_CRED = 0x100e
5764 ATTR_ENCR_TYPE = 0x100f
5765 ATTR_ENCR_TYPE_FLAGS = 0x1010
5766 ATTR_DEV_NAME = 0x1011
5767 ATTR_DEV_PASSWORD_ID = 0x1012
5768 ATTR_E_HASH1 = 0x1014
5769 ATTR_E_HASH2 = 0x1015
5770 ATTR_E_SNONCE1 = 0x1016
5771 ATTR_E_SNONCE2 = 0x1017
5772 ATTR_ENCR_SETTINGS = 0x1018
5773 ATTR_ENROLLEE_NONCE = 0x101a
5774 ATTR_FEATURE_ID = 0x101b
5775 ATTR_IDENTITY = 0x101c
5776 ATTR_IDENTITY_PROOF = 0x101d
5777 ATTR_KEY_WRAP_AUTH = 0x101e
5778 ATTR_KEY_ID = 0x101f
5779 ATTR_MAC_ADDR = 0x1020
5780 ATTR_MANUFACTURER = 0x1021
5781 ATTR_MSG_TYPE = 0x1022
5782 ATTR_MODEL_NAME = 0x1023
5783 ATTR_MODEL_NUMBER = 0x1024
5784 ATTR_NETWORK_INDEX = 0x1026
5785 ATTR_NETWORK_KEY = 0x1027
5786 ATTR_NETWORK_KEY_INDEX = 0x1028
5787 ATTR_NEW_DEVICE_NAME = 0x1029
5788 ATTR_NEW_PASSWORD = 0x102a
5789 ATTR_OOB_DEVICE_PASSWORD = 0x102c
5790 ATTR_OS_VERSION = 0x102d
5791 ATTR_POWER_LEVEL = 0x102f
5792 ATTR_PSK_CURRENT = 0x1030
5793 ATTR_PSK_MAX = 0x1031
5794 ATTR_PUBLIC_KEY = 0x1032
5795 ATTR_RADIO_ENABLE = 0x1033
5796 ATTR_REBOOT = 0x1034
5797 ATTR_REGISTRAR_CURRENT = 0x1035
5798 ATTR_REGISTRAR_ESTABLISHED = 0x1036
5799 ATTR_REGISTRAR_LIST = 0x1037
5800 ATTR_REGISTRAR_MAX = 0x1038
5801 ATTR_REGISTRAR_NONCE = 0x1039
5802 ATTR_REQUEST_TYPE = 0x103a
5803 ATTR_RESPONSE_TYPE = 0x103b
5804 ATTR_RF_BANDS = 0x103c
5805 ATTR_R_HASH1 = 0x103d
5806 ATTR_R_HASH2 = 0x103e
5807 ATTR_R_SNONCE1 = 0x103f
5808 ATTR_R_SNONCE2 = 0x1040
5809 ATTR_SELECTED_REGISTRAR = 0x1041
5810 ATTR_SERIAL_NUMBER = 0x1042
5811 ATTR_WPS_STATE = 0x1044
5812 ATTR_SSID = 0x1045
5813 ATTR_TOTAL_NETWORKS = 0x1046
5814 ATTR_UUID_E = 0x1047
5815 ATTR_UUID_R = 0x1048
5816 ATTR_VENDOR_EXT = 0x1049
5817 ATTR_VERSION = 0x104a
5818 ATTR_X509_CERT_REQ = 0x104b
5819 ATTR_X509_CERT = 0x104c
5820 ATTR_EAP_IDENTITY = 0x104d
5821 ATTR_MSG_COUNTER = 0x104e
5822 ATTR_PUBKEY_HASH = 0x104f
5823 ATTR_REKEY_KEY = 0x1050
5824 ATTR_KEY_LIFETIME = 0x1051
5825 ATTR_PERMITTED_CFG_METHODS = 0x1052
5826 ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053
5827 ATTR_PRIMARY_DEV_TYPE = 0x1054
5828 ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055
5829 ATTR_PORTABLE_DEV = 0x1056
5830 ATTR_AP_SETUP_LOCKED = 0x1057
5831 ATTR_APPLICATION_EXT = 0x1058
5832 ATTR_EAP_TYPE = 0x1059
5833 ATTR_IV = 0x1060
5834 ATTR_KEY_PROVIDED_AUTO = 0x1061
5835 ATTR_802_1X_ENABLED = 0x1062
5836 ATTR_APPSESSIONKEY = 0x1063
5837 ATTR_WEPTRANSMITKEY = 0x1064
5838 ATTR_REQUESTED_DEV_TYPE = 0x106a
5839
5840 # Message Type
5841 WPS_Beacon = 0x01
5842 WPS_ProbeRequest = 0x02
5843 WPS_ProbeResponse = 0x03
5844 WPS_M1 = 0x04
5845 WPS_M2 = 0x05
5846 WPS_M2D = 0x06
5847 WPS_M3 = 0x07
5848 WPS_M4 = 0x08
5849 WPS_M5 = 0x09
5850 WPS_M6 = 0x0a
5851 WPS_M7 = 0x0b
5852 WPS_M8 = 0x0c
5853 WPS_WSC_ACK = 0x0d
5854 WPS_WSC_NACK = 0x0e
5855 WPS_WSC_DONE = 0x0f
5856
5857 def get_wsc_msg(dev):
5858     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
5859     if ev is None:
5860         raise Exception("Timeout on EAPOL-TX")
5861     data = binascii.unhexlify(ev.split(' ')[2])
5862     msg = {}
5863
5864     # Parse EAPOL header
5865     if len(data) < 4:
5866         raise Exception("No room for EAPOL header")
5867     version,type,length = struct.unpack('>BBH', data[0:4])
5868     msg['eapol_version'] = version
5869     msg['eapol_type'] = type
5870     msg['eapol_length'] = length
5871     data = data[4:]
5872     if length != len(data):
5873         raise Exception("EAPOL header length mismatch (%d != %d)" % (length, len(data)))
5874     if type != 0:
5875         raise Exception("Unexpected EAPOL header type: %d" % type)
5876
5877     # Parse EAP header
5878     if len(data) < 4:
5879         raise Exception("No room for EAP header")
5880     code,identifier,length = struct.unpack('>BBH', data[0:4])
5881     msg['eap_code'] = code
5882     msg['eap_identifier'] = identifier
5883     msg['eap_length'] = length
5884     data = data[4:]
5885     if msg['eapol_length'] != msg['eap_length']:
5886         raise Exception("EAP header length mismatch (%d != %d)" % (msg['eapol_length'], length))
5887
5888     # Parse EAP expanded header
5889     if len(data) < 1:
5890         raise Exception("No EAP type included")
5891     msg['eap_type'], = struct.unpack('B', data[0])
5892     data = data[1:]
5893
5894     if msg['eap_type'] == 254:
5895         if len(data) < 3 + 4:
5896             raise Exception("Truncated EAP expanded header")
5897         msg['eap_vendor_id'], msg['eap_vendor_type'] = struct.unpack('>LL', '\0' + data[0:7])
5898         data = data[7:]
5899     else:
5900         raise Exception("Unexpected EAP type")
5901
5902     if msg['eap_vendor_id'] != WPS_VENDOR_ID_WFA:
5903         raise Exception("Unexpected Vendor-Id")
5904     if msg['eap_vendor_type'] != WPS_VENDOR_TYPE:
5905         raise Exception("Unexpected Vendor-Type")
5906
5907     # Parse EAP-WSC header
5908     if len(data) < 2:
5909         raise Exception("Truncated EAP-WSC header")
5910     msg['wsc_opcode'], msg['wsc_flags'] = struct.unpack('BB', data[0:2])
5911     data = data[2:]
5912
5913     # Parse WSC attributes
5914     msg['raw_attrs'] = data
5915     attrs = {}
5916     while len(data) > 0:
5917         if len(data) < 4:
5918             raise Exception("Truncated attribute header")
5919         attr,length = struct.unpack('>HH', data[0:4])
5920         data = data[4:]
5921         if length > len(data):
5922             raise Exception("Truncated attribute 0x%04x" % attr)
5923         attrs[attr] = data[0:length]
5924         data = data[length:]
5925     msg['wsc_attrs'] = attrs
5926
5927     if ATTR_MSG_TYPE in attrs:
5928         msg['wsc_msg_type'], = struct.unpack('B', attrs[ATTR_MSG_TYPE])
5929
5930     return msg
5931
5932 def recv_wsc_msg(dev, opcode, msg_type):
5933     msg = get_wsc_msg(dev)
5934     if msg['wsc_opcode'] != opcode or msg['wsc_msg_type'] != msg_type:
5935         raise Exception("Unexpected Op-Code/MsgType")
5936     return msg, msg['wsc_attrs'], msg['raw_attrs']
5937
5938 def build_wsc_attr(attr, payload):
5939     return struct.pack('>HH', attr, len(payload)) + payload
5940
5941 def build_attr_msg_type(msg_type):
5942     return build_wsc_attr(ATTR_MSG_TYPE, struct.pack('B', msg_type))
5943
5944 def build_eap_wsc(eap_code, eap_id, payload, opcode=WSC_MSG):
5945     length = 4 + 8 + 2 + len(payload)
5946     # EAPOL header
5947     msg = struct.pack('>BBH', 2, 0, length)
5948     # EAP header
5949     msg += struct.pack('>BBH', eap_code, eap_id, length)
5950     # EAP expanded header for EAP-WSC
5951     msg += struct.pack('B', 254)
5952     msg += struct.pack('>L', WPS_VENDOR_ID_WFA)[1:4]
5953     msg += struct.pack('>L', WPS_VENDOR_TYPE)
5954     # EAP-WSC header
5955     msg += struct.pack('BB', opcode, 0)
5956     # WSC attributes
5957     msg += payload
5958     return msg
5959
5960 def build_eap_success(eap_id):
5961     length = 4
5962     # EAPOL header
5963     msg = struct.pack('>BBH', 2, 0, length)
5964     # EAP header
5965     msg += struct.pack('>BBH', 3, eap_id, length)
5966     return msg
5967
5968 def build_eap_failure(eap_id):
5969     length = 4
5970     # EAPOL header
5971     msg = struct.pack('>BBH', 2, 0, length)
5972     # EAP header
5973     msg += struct.pack('>BBH', 4, eap_id, length)
5974     return msg
5975
5976 def send_wsc_msg(dev, src, msg):
5977     res = dev.request("EAPOL_RX " + src + " " + binascii.hexlify(msg))
5978     if "OK" not in res:
5979         raise Exception("EAPOL_RX failed")
5980
5981 group_5_prime = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF
5982 group_5_generator = 2
5983
5984 def wsc_kdf(key, label, bits):
5985     result = ''
5986     i = 1
5987     while len(result) * 8 < bits:
5988         data = struct.pack('>L', i) + label + struct.pack('>L', bits)
5989         m = hmac.new(key, data, hashlib.sha256)
5990         result += m.digest()
5991         i += 1
5992     return result[0:bits / 8]
5993
5994 def wsc_keys(kdk):
5995     keys = wsc_kdf(kdk, "Wi-Fi Easy and Secure Key Derivation", 640)
5996     authkey = keys[0:32]
5997     keywrapkey = keys[32:48]
5998     emsk = keys[48:80]
5999     return authkey,keywrapkey,emsk
6000
6001 def wsc_dev_pw_half_psk(authkey, dev_pw):
6002     m = hmac.new(authkey, dev_pw, hashlib.sha256)
6003     return m.digest()[0:16]
6004
6005 def wsc_dev_pw_psk(authkey, dev_pw):
6006     dev_pw_1 = dev_pw[0:len(dev_pw) / 2]
6007     dev_pw_2 = dev_pw[len(dev_pw) / 2:]
6008     psk1 = wsc_dev_pw_half_psk(authkey, dev_pw_1)
6009     psk2 = wsc_dev_pw_half_psk(authkey, dev_pw_2)
6010     return psk1,psk2
6011
6012 def build_attr_authenticator(authkey, prev_msg, curr_msg):
6013     m = hmac.new(authkey, prev_msg + curr_msg, hashlib.sha256)
6014     auth = m.digest()[0:8]
6015     return build_wsc_attr(ATTR_AUTHENTICATOR, auth)
6016
6017 def build_attr_encr_settings(authkey, keywrapkey, data):
6018     m = hmac.new(authkey, data, hashlib.sha256)
6019     kwa = m.digest()[0:8]
6020     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6021     iv = 16*'\x99'
6022     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6023     pad_len = 16 - len(data) % 16
6024     ps = pad_len * struct.pack('B', pad_len)
6025     data += ps
6026     wrapped = aes.encrypt(data)
6027     return build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6028
6029 def decrypt_attr_encr_settings(authkey, keywrapkey, data):
6030     if len(data) < 32 or len(data) % 16 != 0:
6031         raise Exception("Unexpected Encrypted Settings length: %d" % len(data))
6032     iv = data[0:16]
6033     encr = data[16:]
6034     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6035     decrypted = aes.decrypt(encr)
6036     pad_len, = struct.unpack('B', decrypted[-1])
6037     if pad_len > len(decrypted):
6038         raise Exception("Invalid padding in Encrypted Settings")
6039     for i in range(-pad_len, -1):
6040         if decrypted[i] != decrypted[-1]:
6041             raise Exception("Invalid PS value in Encrypted Settings")
6042     
6043     decrypted = decrypted[0:len(decrypted) - pad_len]
6044     if len(decrypted) < 12:
6045         raise Exception("Truncated Encrypted Settings plaintext")
6046     kwa = decrypted[-12:]
6047     attr,length = struct.unpack(">HH", kwa[0:4])
6048     if attr != ATTR_KEY_WRAP_AUTH or length != 8:
6049         raise Exception("Invalid KWA header")
6050     kwa = kwa[4:]
6051     decrypted = decrypted[0:len(decrypted) - 12]
6052
6053     m = hmac.new(authkey, decrypted, hashlib.sha256)
6054     calc_kwa = m.digest()[0:8]
6055     if kwa != calc_kwa:
6056         raise Exception("KWA mismatch")
6057
6058     return decrypted
6059
6060 def zeropad_str(val, pad_len):
6061     while len(val) < pad_len * 2:
6062         val = '0' + val
6063     return val
6064
6065 def wsc_dh_init():
6066     # For now, use a hardcoded private key. In theory, this is supposed to be
6067     # randomly selected.
6068     own_private = 0x123456789
6069     own_public = pow(group_5_generator, own_private, group_5_prime)
6070     pk = binascii.unhexlify(zeropad_str(format(own_public, '02x'), 192))
6071     return own_private, pk
6072
6073 def wsc_dh_kdf(peer_pk, own_private, mac_addr, e_nonce, r_nonce):
6074     peer_public = long(binascii.hexlify(peer_pk), 16)
6075     if peer_public < 2 or peer_public >= group_5_prime:
6076         raise Exception("Invalid peer public key")
6077     if pow(peer_public, (group_5_prime - 1) / 2, group_5_prime) != 1:
6078         raise Exception("Unexpected Legendre symbol for peer public key")
6079
6080     shared_secret = pow(peer_public, own_private, group_5_prime)
6081     ss = zeropad_str(format(shared_secret, "02x"), 192)
6082     logger.debug("DH shared secret: " + ss)
6083
6084     dhkey = hashlib.sha256(binascii.unhexlify(ss)).digest()
6085     logger.debug("DHKey: " + binascii.hexlify(dhkey))
6086
6087     m = hmac.new(dhkey, e_nonce + mac_addr + r_nonce, hashlib.sha256)
6088     kdk = m.digest()
6089     logger.debug("KDK: " + binascii.hexlify(kdk))
6090     authkey,keywrapkey,emsk = wsc_keys(kdk)
6091     logger.debug("AuthKey: " + binascii.hexlify(authkey))
6092     logger.debug("KeyWrapKey: " + binascii.hexlify(keywrapkey))
6093     logger.debug("EMSK: " + binascii.hexlify(emsk))
6094     return authkey,keywrapkey
6095
6096 def wsc_dev_pw_hash(authkey, dev_pw, e_pk, r_pk):
6097     psk1,psk2 = wsc_dev_pw_psk(authkey, dev_pw)
6098     logger.debug("PSK1: " + binascii.hexlify(psk1))
6099     logger.debug("PSK2: " + binascii.hexlify(psk2))
6100
6101     # Note: Secret values are supposed to be random, but hardcoded values are
6102     # fine for testing.
6103     s1 = 16*'\x77'
6104     m = hmac.new(authkey, s1 + psk1 + e_pk + r_pk, hashlib.sha256)
6105     hash1 = m.digest()
6106     logger.debug("Hash1: " + binascii.hexlify(hash1))
6107
6108     s2 = 16*'\x88'
6109     m = hmac.new(authkey, s2 + psk2 + e_pk + r_pk, hashlib.sha256)
6110     hash2 = m.digest()
6111     logger.debug("Hash2: " + binascii.hexlify(hash2))
6112     return s1,s2,hash1,hash2
6113
6114 def build_m1(eap_id, uuid_e, mac_addr, e_nonce, e_pk,
6115              manufacturer='', model_name='', config_methods='\x00\x00'):
6116     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6117     attrs += build_attr_msg_type(WPS_M1)
6118     attrs += build_wsc_attr(ATTR_UUID_E, uuid_e)
6119     attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6120     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6121     attrs += build_wsc_attr(ATTR_PUBLIC_KEY, e_pk)
6122     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6123     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6124     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6125     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, config_methods)
6126     attrs += build_wsc_attr(ATTR_WPS_STATE, '\x00')
6127     attrs += build_wsc_attr(ATTR_MANUFACTURER, manufacturer)
6128     attrs += build_wsc_attr(ATTR_MODEL_NAME, model_name)
6129     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6130     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6131     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6132     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6133     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6134     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6135     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, '\x00\x00')
6136     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6137     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6138     m1 = build_eap_wsc(2, eap_id, attrs)
6139     return m1, attrs
6140
6141 def build_m2(authkey, m1, eap_id, e_nonce, r_nonce, uuid_r, r_pk,
6142              dev_pw_id='\x00\x00', eap_code=1):
6143     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6144     attrs += build_attr_msg_type(WPS_M2)
6145     if e_nonce:
6146         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6147     if r_nonce:
6148         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6149     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6150     if r_pk:
6151         attrs += build_wsc_attr(ATTR_PUBLIC_KEY, r_pk)
6152     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6153     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6154     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6155     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6156     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6157     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6158     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6159     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6160     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6161     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6162     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6163     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6164     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6165     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6166     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6167     attrs += build_attr_authenticator(authkey, m1, attrs)
6168     m2 = build_eap_wsc(eap_code, eap_id, attrs)
6169     return m2, attrs
6170
6171 def build_m2d(m1, eap_id, e_nonce, r_nonce, uuid_r, dev_pw_id=None, eap_code=1):
6172     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6173     attrs += build_attr_msg_type(WPS_M2D)
6174     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6175     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6176     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6177     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6178     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6179     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6180     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6181     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6182     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6183     #attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6184     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6185     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6186     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6187     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6188     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6189     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6190     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6191     if dev_pw_id:
6192         attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6193     m2d = build_eap_wsc(eap_code, eap_id, attrs)
6194     return m2d, attrs
6195
6196 def build_ack(eap_id, e_nonce, r_nonce, msg_type=WPS_WSC_ACK, eap_code=1):
6197     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6198     if msg_type is not None:
6199         attrs += build_attr_msg_type(msg_type)
6200     if e_nonce:
6201         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6202     if r_nonce:
6203         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6204     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_ACK)
6205     return msg, attrs
6206
6207 def build_nack(eap_id, e_nonce, r_nonce, config_error='\x00\x00',
6208                msg_type=WPS_WSC_NACK, eap_code=1):
6209     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6210     if msg_type is not None:
6211         attrs += build_attr_msg_type(msg_type)
6212     if e_nonce:
6213         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6214     if r_nonce:
6215         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6216     if config_error:
6217         attrs += build_wsc_attr(ATTR_CONFIG_ERROR, config_error)
6218     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_NACK)
6219     return msg, attrs
6220
6221 def test_wps_ext(dev, apdev):
6222     """WPS against external implementation"""
6223     pin = "12345670"
6224     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6225     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6226     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6227
6228     logger.debug("Receive WSC/Start from AP")
6229     msg = get_wsc_msg(hapd)
6230     if msg['wsc_opcode'] != WSC_Start:
6231         raise Exception("Unexpected Op-Code for WSC/Start")
6232     wsc_start_id = msg['eap_identifier']
6233
6234     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6235     uuid_e = 16*'\x11'
6236     e_nonce = 16*'\x22'
6237     own_private, e_pk = wsc_dh_init()
6238
6239     logger.debug("Send M1 to AP")
6240     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
6241                                 e_nonce, e_pk)
6242     send_wsc_msg(hapd, addr, m1)
6243
6244     logger.debug("Receive M2 from AP")
6245     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
6246
6247     authkey,keywrapkey = wsc_dh_kdf(m2_attrs[ATTR_PUBLIC_KEY], own_private,
6248                                     mac_addr, e_nonce,
6249                                     m2_attrs[ATTR_REGISTRAR_NONCE])
6250     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk,
6251                                                 m2_attrs[ATTR_PUBLIC_KEY])
6252
6253     logger.debug("Send M3 to AP")
6254     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6255     attrs += build_attr_msg_type(WPS_M3)
6256     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6257                             m2_attrs[ATTR_REGISTRAR_NONCE])
6258     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
6259     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
6260     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
6261     raw_m3_attrs = attrs
6262     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6263     send_wsc_msg(hapd, addr, m3)
6264
6265     logger.debug("Receive M4 from AP")
6266     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
6267
6268     logger.debug("Send M5 to AP")
6269     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6270     attrs += build_attr_msg_type(WPS_M5)
6271     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6272                             m2_attrs[ATTR_REGISTRAR_NONCE])
6273     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
6274     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6275     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
6276     raw_m5_attrs = attrs
6277     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6278     send_wsc_msg(hapd, addr, m5)
6279
6280     logger.debug("Receive M6 from AP")
6281     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
6282
6283     logger.debug("Send M7 to AP")
6284     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6285     attrs += build_attr_msg_type(WPS_M7)
6286     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6287                             m2_attrs[ATTR_REGISTRAR_NONCE])
6288     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
6289     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6290     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
6291     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6292     raw_m7_attrs = attrs
6293     send_wsc_msg(hapd, addr, m7)
6294
6295     logger.debug("Receive M8 from AP")
6296     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
6297     m8_cred = decrypt_attr_encr_settings(authkey, keywrapkey,
6298                                          m8_attrs[ATTR_ENCR_SETTINGS])
6299     logger.debug("M8 Credential: " + binascii.hexlify(m8_cred))
6300
6301     logger.debug("Prepare WSC_Done")
6302     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6303     attrs += build_attr_msg_type(WPS_WSC_DONE)
6304     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6305     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6306                             m2_attrs[ATTR_REGISTRAR_NONCE])
6307     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
6308     # Do not send WSC_Done yet to allow exchangw with STA complete before the
6309     # AP disconnects.
6310
6311     uuid_r = 16*'\x33'
6312     r_nonce = 16*'\x44'
6313
6314     eap_id = wsc_start_id
6315     logger.debug("Send WSC/Start to STA")
6316     wsc_start = build_eap_wsc(1, eap_id, "", opcode=WSC_Start)
6317     send_wsc_msg(dev[0], bssid, wsc_start)
6318     eap_id = (eap_id + 1) % 256
6319
6320     logger.debug("Receive M1 from STA")
6321     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6322
6323     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6324                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6325                                     r_nonce)
6326     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6327                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6328
6329     logger.debug("Send M2 to STA")
6330     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6331                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6332                                 r_nonce, uuid_r, e_pk)
6333     send_wsc_msg(dev[0], bssid, m2)
6334     eap_id = (eap_id + 1) % 256
6335
6336     logger.debug("Receive M3 from STA")
6337     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6338
6339     logger.debug("Send M4 to STA")
6340     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6341     attrs += build_attr_msg_type(WPS_M4)
6342     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6343     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6344     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6345     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6346     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6347     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6348     raw_m4_attrs = attrs
6349     m4 = build_eap_wsc(1, eap_id, attrs)
6350     send_wsc_msg(dev[0], bssid, m4)
6351     eap_id = (eap_id + 1) % 256
6352
6353     logger.debug("Receive M5 from STA")
6354     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6355
6356     logger.debug("Send M6 to STA")
6357     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6358     attrs += build_attr_msg_type(WPS_M6)
6359     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6360                             m1_attrs[ATTR_ENROLLEE_NONCE])
6361     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6362     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6363     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6364     raw_m6_attrs = attrs
6365     m6 = build_eap_wsc(1, eap_id, attrs)
6366     send_wsc_msg(dev[0], bssid, m6)
6367     eap_id = (eap_id + 1) % 256
6368
6369     logger.debug("Receive M7 from STA")
6370     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6371
6372     logger.debug("Send M8 to STA")
6373     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6374     attrs += build_attr_msg_type(WPS_M8)
6375     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6376                             m1_attrs[ATTR_ENROLLEE_NONCE])
6377     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6378     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6379     raw_m8_attrs = attrs
6380     m8 = build_eap_wsc(1, eap_id, attrs)
6381     send_wsc_msg(dev[0], bssid, m8)
6382     eap_id = (eap_id + 1) % 256
6383
6384     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=5)
6385     if ev is None:
6386         raise Exception("wpa_supplicant did not report credential")
6387
6388     logger.debug("Receive WSC_Done from STA")
6389     msg = get_wsc_msg(dev[0])
6390     if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6391         raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6392
6393     logger.debug("Send WSC_Done to AP")
6394     hapd.request("SET ext_eapol_frame_io 0")
6395     dev[0].request("SET ext_eapol_frame_io 0")
6396     send_wsc_msg(hapd, addr, wsc_done)
6397
6398     ev = hapd.wait_event(["WPS-REG-SUCCESS"], timeout=5)
6399     if ev is None:
6400         raise Exception("hostapd did not report WPS success")
6401
6402     dev[0].wait_connected()
6403
6404 def wps_start_kwa(dev, apdev):
6405     pin = "12345670"
6406     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6407     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6408     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6409     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6410
6411     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6412     uuid_r = 16*'\x33'
6413     r_nonce = 16*'\x44'
6414     own_private, e_pk = wsc_dh_init()
6415
6416     logger.debug("Receive M1 from STA")
6417     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6418     eap_id = (msg['eap_identifier'] + 1) % 256
6419
6420     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6421                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6422                                     r_nonce)
6423     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6424                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6425
6426     logger.debug("Send M2 to STA")
6427     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6428                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6429                                 r_nonce, uuid_r, e_pk)
6430     send_wsc_msg(dev[0], bssid, m2)
6431     eap_id = (eap_id + 1) % 256
6432
6433     logger.debug("Receive M3 from STA")
6434     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6435
6436     logger.debug("Send M4 to STA")
6437     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6438     attrs += build_attr_msg_type(WPS_M4)
6439     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6440     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6441     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6442
6443     return r_s1, keywrapkey, authkey, raw_m3_attrs, eap_id, bssid, attrs
6444
6445 def wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id):
6446     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6447     m4 = build_eap_wsc(1, eap_id, attrs)
6448     send_wsc_msg(dev[0], bssid, m4)
6449     eap_id = (eap_id + 1) % 256
6450
6451     logger.debug("Receive M5 from STA")
6452     msg = get_wsc_msg(dev[0])
6453     if msg['wsc_opcode'] != WSC_NACK:
6454         raise Exception("Unexpected message - expected WSC_Nack")
6455
6456     dev[0].request("WPS_CANCEL")
6457     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6458     dev[0].wait_disconnected()
6459
6460 def test_wps_ext_kwa_proto_no_kwa(dev, apdev):
6461     """WPS and KWA error: No KWA attribute"""
6462     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6463     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6464     # Encrypted Settings without KWA
6465     iv = 16*'\x99'
6466     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6467     pad_len = 16 - len(data) % 16
6468     ps = pad_len * struct.pack('B', pad_len)
6469     data += ps
6470     wrapped = aes.encrypt(data)
6471     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6472     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6473
6474 def test_wps_ext_kwa_proto_data_after_kwa(dev, apdev):
6475     """WPS and KWA error: Data after KWA"""
6476     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6477     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6478     # Encrypted Settings and data after KWA
6479     m = hmac.new(authkey, data, hashlib.sha256)
6480     kwa = m.digest()[0:8]
6481     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6482     data += build_wsc_attr(ATTR_VENDOR_EXT, "1234567890")
6483     iv = 16*'\x99'
6484     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6485     pad_len = 16 - len(data) % 16
6486     ps = pad_len * struct.pack('B', pad_len)
6487     data += ps
6488     wrapped = aes.encrypt(data)
6489     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6490     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6491
6492 def test_wps_ext_kwa_proto_kwa_mismatch(dev, apdev):
6493     """WPS and KWA error: KWA mismatch"""
6494     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6495     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6496     # Encrypted Settings and KWA with incorrect value
6497     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, 8*'\x00')
6498     iv = 16*'\x99'
6499     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6500     pad_len = 16 - len(data) % 16
6501     ps = pad_len * struct.pack('B', pad_len)
6502     data += ps
6503     wrapped = aes.encrypt(data)
6504     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6505     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6506
6507 def wps_run_cred_proto(dev, apdev, m8_cred, connect=False, no_connect=False):
6508     pin = "12345670"
6509     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6510     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6511     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6512     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6513
6514     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6515     uuid_r = 16*'\x33'
6516     r_nonce = 16*'\x44'
6517     own_private, e_pk = wsc_dh_init()
6518
6519     logger.debug("Receive M1 from STA")
6520     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6521     eap_id = (msg['eap_identifier'] + 1) % 256
6522
6523     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6524                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6525                                     r_nonce)
6526     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6527                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6528
6529     logger.debug("Send M2 to STA")
6530     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6531                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6532                                 r_nonce, uuid_r, e_pk)
6533     send_wsc_msg(dev[0], bssid, m2)
6534     eap_id = (eap_id + 1) % 256
6535
6536     logger.debug("Receive M3 from STA")
6537     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6538
6539     logger.debug("Send M4 to STA")
6540     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6541     attrs += build_attr_msg_type(WPS_M4)
6542     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6543     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6544     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6545     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6546     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6547     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6548     raw_m4_attrs = attrs
6549     m4 = build_eap_wsc(1, eap_id, attrs)
6550     send_wsc_msg(dev[0], bssid, m4)
6551     eap_id = (eap_id + 1) % 256
6552
6553     logger.debug("Receive M5 from STA")
6554     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6555
6556     logger.debug("Send M6 to STA")
6557     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6558     attrs += build_attr_msg_type(WPS_M6)
6559     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6560                             m1_attrs[ATTR_ENROLLEE_NONCE])
6561     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6562     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6563     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6564     raw_m6_attrs = attrs
6565     m6 = build_eap_wsc(1, eap_id, attrs)
6566     send_wsc_msg(dev[0], bssid, m6)
6567     eap_id = (eap_id + 1) % 256
6568
6569     logger.debug("Receive M7 from STA")
6570     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6571
6572     logger.debug("Send M8 to STA")
6573     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6574     attrs += build_attr_msg_type(WPS_M8)
6575     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6576                             m1_attrs[ATTR_ENROLLEE_NONCE])
6577     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6578     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6579     raw_m8_attrs = attrs
6580     m8 = build_eap_wsc(1, eap_id, attrs)
6581     send_wsc_msg(dev[0], bssid, m8)
6582     eap_id = (eap_id + 1) % 256
6583
6584     if no_connect:
6585         logger.debug("Receive WSC_Done from STA")
6586         msg = get_wsc_msg(dev[0])
6587         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6588             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6589
6590         hapd.request("SET ext_eapol_frame_io 0")
6591         dev[0].request("SET ext_eapol_frame_io 0")
6592
6593         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6594
6595         dev[0].wait_disconnected()
6596         dev[0].request("REMOVE_NETWORK all")
6597     elif connect:
6598         logger.debug("Receive WSC_Done from STA")
6599         msg = get_wsc_msg(dev[0])
6600         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6601             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6602
6603         hapd.request("SET ext_eapol_frame_io 0")
6604         dev[0].request("SET ext_eapol_frame_io 0")
6605
6606         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6607
6608         dev[0].wait_connected()
6609     else:
6610         # Verify STA NACK's the credential
6611         msg = get_wsc_msg(dev[0])
6612         if msg['wsc_opcode'] != WSC_NACK:
6613             raise Exception("Unexpected message - expected WSC_Nack")
6614         dev[0].request("WPS_CANCEL")
6615         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6616         dev[0].wait_disconnected()
6617
6618 def build_cred(nw_idx='\x01', ssid='test-wps-conf', auth_type='\x00\x20',
6619                encr_type='\x00\x08', nw_key="12345678",
6620                mac_addr='\x00\x00\x00\x00\x00\x00'):
6621     attrs = ''
6622     if nw_idx is not None:
6623         attrs += build_wsc_attr(ATTR_NETWORK_INDEX, nw_idx)
6624     if ssid is not None:
6625         attrs += build_wsc_attr(ATTR_SSID, ssid)
6626     if auth_type is not None:
6627         attrs += build_wsc_attr(ATTR_AUTH_TYPE, auth_type)
6628     if encr_type is not None:
6629         attrs += build_wsc_attr(ATTR_ENCR_TYPE, encr_type)
6630     if nw_key is not None:
6631         attrs += build_wsc_attr(ATTR_NETWORK_KEY, nw_key)
6632     if mac_addr is not None:
6633         attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6634     return build_wsc_attr(ATTR_CRED, attrs)
6635
6636 def test_wps_ext_cred_proto_success(dev, apdev):
6637     """WPS and Credential: success"""
6638     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6639     m8_cred = build_cred(mac_addr=mac_addr)
6640     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6641
6642 def test_wps_ext_cred_proto_mac_addr_mismatch(dev, apdev):
6643     """WPS and Credential: MAC Address mismatch"""
6644     m8_cred = build_cred()
6645     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6646
6647 def test_wps_ext_cred_proto_zero_padding(dev, apdev):
6648     """WPS and Credential: zeropadded attributes"""
6649     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6650     m8_cred = build_cred(mac_addr=mac_addr, ssid='test-wps-conf\x00',
6651                          nw_key="12345678\x00")
6652     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6653
6654 def test_wps_ext_cred_proto_ssid_missing(dev, apdev):
6655     """WPS and Credential: SSID missing"""
6656     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6657     m8_cred = build_cred(mac_addr=mac_addr, ssid=None)
6658     wps_run_cred_proto(dev, apdev, m8_cred)
6659
6660 def test_wps_ext_cred_proto_ssid_zero_len(dev, apdev):
6661     """WPS and Credential: Zero-length SSID"""
6662     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6663     m8_cred = build_cred(mac_addr=mac_addr, ssid="")
6664     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6665
6666 def test_wps_ext_cred_proto_auth_type_missing(dev, apdev):
6667     """WPS and Credential: Auth Type missing"""
6668     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6669     m8_cred = build_cred(mac_addr=mac_addr, auth_type=None)
6670     wps_run_cred_proto(dev, apdev, m8_cred)
6671
6672 def test_wps_ext_cred_proto_encr_type_missing(dev, apdev):
6673     """WPS and Credential: Encr Type missing"""
6674     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6675     m8_cred = build_cred(mac_addr=mac_addr, encr_type=None)
6676     wps_run_cred_proto(dev, apdev, m8_cred)
6677
6678 def test_wps_ext_cred_proto_network_key_missing(dev, apdev):
6679     """WPS and Credential: Network Key missing"""
6680     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6681     m8_cred = build_cred(mac_addr=mac_addr, nw_key=None)
6682     wps_run_cred_proto(dev, apdev, m8_cred)
6683
6684 def test_wps_ext_cred_proto_network_key_missing_open(dev, apdev):
6685     """WPS and Credential: Network Key missing (open)"""
6686     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6687     m8_cred = build_cred(mac_addr=mac_addr, auth_type='\x00\x01',
6688                          encr_type='\x00\x01', nw_key=None, ssid="foo")
6689     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6690
6691 def test_wps_ext_cred_proto_mac_addr_missing(dev, apdev):
6692     """WPS and Credential: MAC Address missing"""
6693     m8_cred = build_cred(mac_addr=None)
6694     wps_run_cred_proto(dev, apdev, m8_cred)
6695
6696 def test_wps_ext_cred_proto_invalid_encr_type(dev, apdev):
6697     """WPS and Credential: Invalid Encr Type"""
6698     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6699     m8_cred = build_cred(mac_addr=mac_addr, encr_type='\x00\x00')
6700     wps_run_cred_proto(dev, apdev, m8_cred)
6701
6702 def test_wps_ext_cred_proto_missing_cred(dev, apdev):
6703     """WPS and Credential: Missing Credential"""
6704     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6705     m8_cred = ''
6706     wps_run_cred_proto(dev, apdev, m8_cred)
6707
6708 def test_wps_ext_proto_m2_no_public_key(dev, apdev):
6709     """WPS and no Public Key in M2"""
6710     pin = "12345670"
6711     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6712     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6713     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6714     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6715
6716     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6717     uuid_r = 16*'\x33'
6718     r_nonce = 16*'\x44'
6719     own_private, e_pk = wsc_dh_init()
6720
6721     logger.debug("Receive M1 from STA")
6722     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6723     eap_id = (msg['eap_identifier'] + 1) % 256
6724
6725     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6726                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6727                                     r_nonce)
6728     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6729                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6730
6731     logger.debug("Send M2 to STA")
6732     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6733                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6734                                 r_nonce, uuid_r, None)
6735     send_wsc_msg(dev[0], bssid, m2)
6736     eap_id = (eap_id + 1) % 256
6737
6738     # Verify STA NACK's the credential
6739     msg = get_wsc_msg(dev[0])
6740     if msg['wsc_opcode'] != WSC_NACK:
6741         raise Exception("Unexpected message - expected WSC_Nack")
6742     dev[0].request("WPS_CANCEL")
6743     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6744     dev[0].wait_disconnected()
6745
6746 def test_wps_ext_proto_m2_invalid_public_key(dev, apdev):
6747     """WPS and invalid Public Key in M2"""
6748     pin = "12345670"
6749     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6750     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6751     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6752     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6753
6754     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6755     uuid_r = 16*'\x33'
6756     r_nonce = 16*'\x44'
6757     own_private, e_pk = wsc_dh_init()
6758
6759     logger.debug("Receive M1 from STA")
6760     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6761     eap_id = (msg['eap_identifier'] + 1) % 256
6762
6763     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6764                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6765                                     r_nonce)
6766     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6767                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6768
6769     logger.debug("Send M2 to STA")
6770     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6771                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6772                                 r_nonce, uuid_r, 192*'\xff')
6773     send_wsc_msg(dev[0], bssid, m2)
6774     eap_id = (eap_id + 1) % 256
6775
6776     # Verify STA NACK's the credential
6777     msg = get_wsc_msg(dev[0])
6778     if msg['wsc_opcode'] != WSC_NACK:
6779         raise Exception("Unexpected message - expected WSC_Nack")
6780     dev[0].request("WPS_CANCEL")
6781     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6782     dev[0].wait_disconnected()
6783
6784 def test_wps_ext_proto_m2_public_key_oom(dev, apdev):
6785     """WPS and Public Key OOM in M2"""
6786     pin = "12345670"
6787     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6788     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6789     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6790     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6791
6792     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6793     uuid_r = 16*'\x33'
6794     r_nonce = 16*'\x44'
6795     own_private, e_pk = wsc_dh_init()
6796
6797     logger.debug("Receive M1 from STA")
6798     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6799     eap_id = (msg['eap_identifier'] + 1) % 256
6800
6801     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6802                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6803                                     r_nonce)
6804     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6805                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6806
6807     logger.debug("Send M2 to STA")
6808     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6809                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6810                                 r_nonce, uuid_r, e_pk)
6811     with alloc_fail(dev[0], 1, "wpabuf_alloc_copy;wps_process_pubkey"):
6812         send_wsc_msg(dev[0], bssid, m2)
6813         eap_id = (eap_id + 1) % 256
6814
6815         # Verify STA NACK's the credential
6816         msg = get_wsc_msg(dev[0])
6817         if msg['wsc_opcode'] != WSC_NACK:
6818             raise Exception("Unexpected message - expected WSC_Nack")
6819         dev[0].request("WPS_CANCEL")
6820         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6821         dev[0].wait_disconnected()
6822
6823 def test_wps_ext_proto_nack_m3(dev, apdev):
6824     """WPS and NACK M3"""
6825     pin = "12345670"
6826     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6827     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6828     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6829     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6830
6831     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6832     uuid_r = 16*'\x33'
6833     r_nonce = 16*'\x44'
6834     own_private, e_pk = wsc_dh_init()
6835
6836     logger.debug("Receive M1 from STA")
6837     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6838     eap_id = (msg['eap_identifier'] + 1) % 256
6839
6840     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6841                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6842                                     r_nonce)
6843     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6844                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6845
6846     logger.debug("Send M2 to STA")
6847     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6848                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6849                                 r_nonce, uuid_r, e_pk)
6850     send_wsc_msg(dev[0], bssid, m2)
6851     eap_id = (eap_id + 1) % 256
6852
6853     logger.debug("Receive M3 from STA")
6854     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6855
6856     logger.debug("Send NACK to STA")
6857     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
6858                             r_nonce, config_error='\x01\x23')
6859     send_wsc_msg(dev[0], bssid, msg)
6860     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
6861     if ev is None:
6862         raise Exception("Failure not reported")
6863     if "msg=7 config_error=291" not in ev:
6864         raise Exception("Unexpected failure reason: " + ev)
6865
6866 def test_wps_ext_proto_nack_m5(dev, apdev):
6867     """WPS and NACK M5"""
6868     pin = "12345670"
6869     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6870     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6871     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6872     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6873
6874     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6875     uuid_r = 16*'\x33'
6876     r_nonce = 16*'\x44'
6877     own_private, e_pk = wsc_dh_init()
6878
6879     logger.debug("Receive M1 from STA")
6880     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6881     eap_id = (msg['eap_identifier'] + 1) % 256
6882
6883     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6884                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6885                                     r_nonce)
6886     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6887                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6888
6889     logger.debug("Send M2 to STA")
6890     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6891                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6892                                 r_nonce, uuid_r, e_pk)
6893     send_wsc_msg(dev[0], bssid, m2)
6894     eap_id = (eap_id + 1) % 256
6895
6896     logger.debug("Receive M3 from STA")
6897     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6898
6899     logger.debug("Send M4 to STA")
6900     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6901     attrs += build_attr_msg_type(WPS_M4)
6902     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6903     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6904     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6905     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6906     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6907     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6908     raw_m4_attrs = attrs
6909     m4 = build_eap_wsc(1, eap_id, attrs)
6910     send_wsc_msg(dev[0], bssid, m4)
6911     eap_id = (eap_id + 1) % 256
6912
6913     logger.debug("Receive M5 from STA")
6914     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6915
6916     logger.debug("Send NACK to STA")
6917     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
6918                             r_nonce, config_error='\x01\x24')
6919     send_wsc_msg(dev[0], bssid, msg)
6920     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
6921     if ev is None:
6922         raise Exception("Failure not reported")
6923     if "msg=9 config_error=292" not in ev:
6924         raise Exception("Unexpected failure reason: " + ev)
6925
6926 def wps_nack_m3(dev, apdev):
6927     pin = "00000000"
6928     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
6929     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6930     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6931     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6932
6933     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6934     uuid_r = 16*'\x33'
6935     r_nonce = 16*'\x44'
6936     own_private, e_pk = wsc_dh_init()
6937
6938     logger.debug("Receive M1 from STA")
6939     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6940     eap_id = (msg['eap_identifier'] + 1) % 256
6941
6942     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6943                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6944                                     r_nonce)
6945     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6946                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6947
6948     logger.debug("Send M2 to STA")
6949     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6950                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6951                                 r_nonce, uuid_r, e_pk, dev_pw_id='\x00\x04')
6952     send_wsc_msg(dev[0], bssid, m2)
6953     eap_id = (eap_id + 1) % 256
6954
6955     logger.debug("Receive M3 from STA")
6956     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6957     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid
6958
6959 def test_wps_ext_proto_nack_m3_no_config_error(dev, apdev):
6960     """WPS and NACK M3 missing Config Error"""
6961     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6962     logger.debug("Send NACK to STA")
6963     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, config_error=None)
6964     send_wsc_msg(dev[0], bssid, msg)
6965     dev[0].request("WPS_CANCEL")
6966     dev[0].wait_disconnected()
6967     dev[0].flush_scan_cache()
6968
6969 def test_wps_ext_proto_nack_m3_no_e_nonce(dev, apdev):
6970     """WPS and NACK M3 missing E-Nonce"""
6971     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6972     logger.debug("Send NACK to STA")
6973     msg, attrs = build_nack(eap_id, None, r_nonce)
6974     send_wsc_msg(dev[0], bssid, msg)
6975     dev[0].request("WPS_CANCEL")
6976     dev[0].wait_disconnected()
6977     dev[0].flush_scan_cache()
6978
6979 def test_wps_ext_proto_nack_m3_e_nonce_mismatch(dev, apdev):
6980     """WPS and NACK M3 E-Nonce mismatch"""
6981     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6982     logger.debug("Send NACK to STA")
6983     msg, attrs = build_nack(eap_id, 16*'\x00', r_nonce)
6984     send_wsc_msg(dev[0], bssid, msg)
6985     dev[0].request("WPS_CANCEL")
6986     dev[0].wait_disconnected()
6987     dev[0].flush_scan_cache()
6988
6989 def test_wps_ext_proto_nack_m3_no_r_nonce(dev, apdev):
6990     """WPS and NACK M3 missing R-Nonce"""
6991     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6992     logger.debug("Send NACK to STA")
6993     msg, attrs = build_nack(eap_id, e_nonce, None)
6994     send_wsc_msg(dev[0], bssid, msg)
6995     dev[0].request("WPS_CANCEL")
6996     dev[0].wait_disconnected()
6997     dev[0].flush_scan_cache()
6998
6999 def test_wps_ext_proto_nack_m3_r_nonce_mismatch(dev, apdev):
7000     """WPS and NACK M3 R-Nonce mismatch"""
7001     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7002     logger.debug("Send NACK to STA")
7003     msg, attrs = build_nack(eap_id, e_nonce, 16*'\x00')
7004     send_wsc_msg(dev[0], bssid, msg)
7005     dev[0].request("WPS_CANCEL")
7006     dev[0].wait_disconnected()
7007     dev[0].flush_scan_cache()
7008
7009 def test_wps_ext_proto_nack_m3_no_msg_type(dev, apdev):
7010     """WPS and NACK M3 no Message Type"""
7011     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7012     logger.debug("Send NACK to STA")
7013     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=None)
7014     send_wsc_msg(dev[0], bssid, msg)
7015     dev[0].request("WPS_CANCEL")
7016     dev[0].wait_disconnected()
7017     dev[0].flush_scan_cache()
7018
7019 def test_wps_ext_proto_nack_m3_invalid_msg_type(dev, apdev):
7020     """WPS and NACK M3 invalid Message Type"""
7021     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7022     logger.debug("Send NACK to STA")
7023     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=123)
7024     send_wsc_msg(dev[0], bssid, msg)
7025     dev[0].request("WPS_CANCEL")
7026     dev[0].wait_disconnected()
7027     dev[0].flush_scan_cache()
7028
7029 def test_wps_ext_proto_nack_m3_invalid_attr(dev, apdev):
7030     """WPS and NACK M3 invalid attribute"""
7031     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7032     logger.debug("Send NACK to STA")
7033     attrs = '\x10\x10\x00'
7034     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_NACK)
7035     send_wsc_msg(dev[0], bssid, msg)
7036     dev[0].request("WPS_CANCEL")
7037     dev[0].wait_disconnected()
7038     dev[0].flush_scan_cache()
7039
7040 def test_wps_ext_proto_ack_m3_no_e_nonce(dev, apdev):
7041     """WPS and ACK M3 missing E-Nonce"""
7042     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7043     logger.debug("Send NACK to STA")
7044     msg, attrs = build_ack(eap_id, None, r_nonce)
7045     send_wsc_msg(dev[0], bssid, msg)
7046     dev[0].request("WPS_CANCEL")
7047     dev[0].wait_disconnected()
7048     dev[0].flush_scan_cache()
7049
7050 def test_wps_ext_proto_ack_m3_e_nonce_mismatch(dev, apdev):
7051     """WPS and ACK M3 E-Nonce mismatch"""
7052     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7053     logger.debug("Send NACK to STA")
7054     msg, attrs = build_ack(eap_id, 16*'\x00', r_nonce)
7055     send_wsc_msg(dev[0], bssid, msg)
7056     dev[0].request("WPS_CANCEL")
7057     dev[0].wait_disconnected()
7058     dev[0].flush_scan_cache()
7059
7060 def test_wps_ext_proto_ack_m3_no_r_nonce(dev, apdev):
7061     """WPS and ACK M3 missing R-Nonce"""
7062     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7063     logger.debug("Send NACK to STA")
7064     msg, attrs = build_ack(eap_id, e_nonce, None)
7065     send_wsc_msg(dev[0], bssid, msg)
7066     dev[0].request("WPS_CANCEL")
7067     dev[0].wait_disconnected()
7068     dev[0].flush_scan_cache()
7069
7070 def test_wps_ext_proto_ack_m3_r_nonce_mismatch(dev, apdev):
7071     """WPS and ACK M3 R-Nonce mismatch"""
7072     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7073     logger.debug("Send NACK to STA")
7074     msg, attrs = build_ack(eap_id, e_nonce, 16*'\x00')
7075     send_wsc_msg(dev[0], bssid, msg)
7076     dev[0].request("WPS_CANCEL")
7077     dev[0].wait_disconnected()
7078     dev[0].flush_scan_cache()
7079
7080 def test_wps_ext_proto_ack_m3_no_msg_type(dev, apdev):
7081     """WPS and ACK M3 no Message Type"""
7082     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7083     logger.debug("Send NACK to STA")
7084     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=None)
7085     send_wsc_msg(dev[0], bssid, msg)
7086     dev[0].request("WPS_CANCEL")
7087     dev[0].wait_disconnected()
7088     dev[0].flush_scan_cache()
7089
7090 def test_wps_ext_proto_ack_m3_invalid_msg_type(dev, apdev):
7091     """WPS and ACK M3 invalid Message Type"""
7092     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7093     logger.debug("Send NACK to STA")
7094     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=123)
7095     send_wsc_msg(dev[0], bssid, msg)
7096     dev[0].request("WPS_CANCEL")
7097     dev[0].wait_disconnected()
7098     dev[0].flush_scan_cache()
7099
7100 def test_wps_ext_proto_ack_m3_invalid_attr(dev, apdev):
7101     """WPS and ACK M3 invalid attribute"""
7102     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7103     logger.debug("Send ACK to STA")
7104     attrs = '\x10\x10\x00'
7105     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_ACK)
7106     send_wsc_msg(dev[0], bssid, msg)
7107     dev[0].request("WPS_CANCEL")
7108     dev[0].wait_disconnected()
7109     dev[0].flush_scan_cache()
7110
7111 def test_wps_ext_proto_ack_m3(dev, apdev):
7112     """WPS and ACK M3"""
7113     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7114     logger.debug("Send ACK to STA")
7115     msg, attrs = build_ack(eap_id, e_nonce, r_nonce)
7116     send_wsc_msg(dev[0], bssid, msg)
7117     dev[0].request("WPS_CANCEL")
7118     dev[0].wait_disconnected()
7119     dev[0].flush_scan_cache()
7120
7121 def wps_to_m3_helper(dev, apdev):
7122     pin = "12345670"
7123     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7124     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7125     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7126     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7127
7128     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7129     uuid_r = 16*'\x33'
7130     r_nonce = 16*'\x44'
7131     own_private, e_pk = wsc_dh_init()
7132
7133     logger.debug("Receive M1 from STA")
7134     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7135     eap_id = (msg['eap_identifier'] + 1) % 256
7136
7137     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7138                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7139                                     r_nonce)
7140     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7141                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7142
7143     logger.debug("Send M2 to STA")
7144     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7145                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7146                                 r_nonce, uuid_r, e_pk)
7147     send_wsc_msg(dev[0], bssid, m2)
7148     eap_id = (eap_id + 1) % 256
7149
7150     logger.debug("Receive M3 from STA")
7151     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7152     return eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey
7153
7154 def wps_to_m3(dev, apdev):
7155     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)
7156     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s1, raw_m3_attrs, authkey, keywrapkey
7157
7158 def wps_to_m5(dev, apdev):
7159     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)
7160
7161     logger.debug("Send M4 to STA")
7162     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7163     attrs += build_attr_msg_type(WPS_M4)
7164     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
7165     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7166     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7167     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7168     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7169     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7170     raw_m4_attrs = attrs
7171     m4 = build_eap_wsc(1, eap_id, attrs)
7172     send_wsc_msg(dev[0], bssid, m4)
7173     eap_id = (eap_id + 1) % 256
7174
7175     logger.debug("Receive M5 from STA")
7176     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
7177
7178     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s2, raw_m5_attrs, authkey, keywrapkey
7179
7180 def test_wps_ext_proto_m4_missing_r_hash1(dev, apdev):
7181     """WPS and no R-Hash1 in M4"""
7182     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7183
7184     logger.debug("Send M4 to STA")
7185     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7186     attrs += build_attr_msg_type(WPS_M4)
7187     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7188     #attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7189     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7190     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7191     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7192     attrs += build_attr_authenticator(authkey, m3, attrs)
7193     m4 = build_eap_wsc(1, eap_id, attrs)
7194     send_wsc_msg(dev[0], bssid, m4)
7195     eap_id = (eap_id + 1) % 256
7196
7197     logger.debug("Receive M5 (NACK) from STA")
7198     msg = get_wsc_msg(dev[0])
7199     if msg['wsc_opcode'] != WSC_NACK:
7200         raise Exception("Unexpected message - expected WSC_Nack")
7201
7202     dev[0].request("WPS_CANCEL")
7203     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7204     dev[0].wait_disconnected()
7205
7206 def test_wps_ext_proto_m4_missing_r_hash2(dev, apdev):
7207     """WPS and no R-Hash2 in M4"""
7208     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7209
7210     logger.debug("Send M4 to STA")
7211     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7212     attrs += build_attr_msg_type(WPS_M4)
7213     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7214     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7215     #attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7216     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7217     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7218     attrs += build_attr_authenticator(authkey, m3, attrs)
7219     m4 = build_eap_wsc(1, eap_id, attrs)
7220     send_wsc_msg(dev[0], bssid, m4)
7221     eap_id = (eap_id + 1) % 256
7222
7223     logger.debug("Receive M5 (NACK) from STA")
7224     msg = get_wsc_msg(dev[0])
7225     if msg['wsc_opcode'] != WSC_NACK:
7226         raise Exception("Unexpected message - expected WSC_Nack")
7227
7228     dev[0].request("WPS_CANCEL")
7229     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7230     dev[0].wait_disconnected()
7231
7232 def test_wps_ext_proto_m4_missing_r_snonce1(dev, apdev):
7233     """WPS and no R-SNonce1 in M4"""
7234     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7235
7236     logger.debug("Send M4 to STA")
7237     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7238     attrs += build_attr_msg_type(WPS_M4)
7239     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7240     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7241     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7242     #data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7243     data = ''
7244     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7245     attrs += build_attr_authenticator(authkey, m3, attrs)
7246     m4 = build_eap_wsc(1, eap_id, attrs)
7247     send_wsc_msg(dev[0], bssid, m4)
7248     eap_id = (eap_id + 1) % 256
7249
7250     logger.debug("Receive M5 (NACK) from STA")
7251     msg = get_wsc_msg(dev[0])
7252     if msg['wsc_opcode'] != WSC_NACK:
7253         raise Exception("Unexpected message - expected WSC_Nack")
7254
7255     dev[0].request("WPS_CANCEL")
7256     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7257     dev[0].wait_disconnected()
7258
7259 def test_wps_ext_proto_m4_invalid_pad_string(dev, apdev):
7260     """WPS and invalid pad string in M4"""
7261     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7262
7263     logger.debug("Send M4 to STA")
7264     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7265     attrs += build_attr_msg_type(WPS_M4)
7266     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7267     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7268     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7269     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7270
7271     m = hmac.new(authkey, data, hashlib.sha256)
7272     kwa = m.digest()[0:8]
7273     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7274     iv = 16*'\x99'
7275     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7276     pad_len = 16 - len(data) % 16
7277     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', pad_len - 1)
7278     data += ps
7279     wrapped = aes.encrypt(data)
7280     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7281
7282     attrs += build_attr_authenticator(authkey, m3, attrs)
7283     m4 = build_eap_wsc(1, eap_id, attrs)
7284     send_wsc_msg(dev[0], bssid, m4)
7285     eap_id = (eap_id + 1) % 256
7286
7287     logger.debug("Receive M5 (NACK) from STA")
7288     msg = get_wsc_msg(dev[0])
7289     if msg['wsc_opcode'] != WSC_NACK:
7290         raise Exception("Unexpected message - expected WSC_Nack")
7291
7292     dev[0].request("WPS_CANCEL")
7293     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7294     dev[0].wait_disconnected()
7295
7296 def test_wps_ext_proto_m4_invalid_pad_value(dev, apdev):
7297     """WPS and invalid pad value in M4"""
7298     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7299
7300     logger.debug("Send M4 to STA")
7301     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7302     attrs += build_attr_msg_type(WPS_M4)
7303     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7304     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7305     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7306     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7307
7308     m = hmac.new(authkey, data, hashlib.sha256)
7309     kwa = m.digest()[0:8]
7310     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7311     iv = 16*'\x99'
7312     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7313     pad_len = 16 - len(data) % 16
7314     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', 255)
7315     data += ps
7316     wrapped = aes.encrypt(data)
7317     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7318
7319     attrs += build_attr_authenticator(authkey, m3, attrs)
7320     m4 = build_eap_wsc(1, eap_id, attrs)
7321     send_wsc_msg(dev[0], bssid, m4)
7322     eap_id = (eap_id + 1) % 256
7323
7324     logger.debug("Receive M5 (NACK) from STA")
7325     msg = get_wsc_msg(dev[0])
7326     if msg['wsc_opcode'] != WSC_NACK:
7327         raise Exception("Unexpected message - expected WSC_Nack")
7328
7329     dev[0].request("WPS_CANCEL")
7330     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7331     dev[0].wait_disconnected()
7332
7333 def test_wps_ext_proto_m4_no_encr_settings(dev, apdev):
7334     """WPS and no Encr Settings in M4"""
7335     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7336
7337     logger.debug("Send M4 to STA")
7338     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7339     attrs += build_attr_msg_type(WPS_M4)
7340     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7341     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7342     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7343     attrs += build_attr_authenticator(authkey, m3, attrs)
7344     m4 = build_eap_wsc(1, eap_id, attrs)
7345     send_wsc_msg(dev[0], bssid, m4)
7346     eap_id = (eap_id + 1) % 256
7347
7348     logger.debug("Receive M5 (NACK) from STA")
7349     msg = get_wsc_msg(dev[0])
7350     if msg['wsc_opcode'] != WSC_NACK:
7351         raise Exception("Unexpected message - expected WSC_Nack")
7352
7353     dev[0].request("WPS_CANCEL")
7354     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7355     dev[0].wait_disconnected()
7356
7357 def test_wps_ext_proto_m6_missing_r_snonce2(dev, apdev):
7358     """WPS and no R-SNonce2 in M6"""
7359     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7360
7361     logger.debug("Send M6 to STA")
7362     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7363     attrs += build_attr_msg_type(WPS_M6)
7364     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7365     #data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7366     data = ''
7367     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7368     attrs += build_attr_authenticator(authkey, m5, attrs)
7369     m6 = build_eap_wsc(1, eap_id, attrs)
7370     send_wsc_msg(dev[0], bssid, m6)
7371     eap_id = (eap_id + 1) % 256
7372
7373     logger.debug("Receive M7 (NACK) from STA")
7374     msg = get_wsc_msg(dev[0])
7375     if msg['wsc_opcode'] != WSC_NACK:
7376         raise Exception("Unexpected message - expected WSC_Nack")
7377
7378     dev[0].request("WPS_CANCEL")
7379     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7380     dev[0].wait_disconnected()
7381
7382 def test_wps_ext_proto_m6_no_encr_settings(dev, apdev):
7383     """WPS and no Encr Settings in M6"""
7384     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7385
7386     logger.debug("Send M6 to STA")
7387     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7388     attrs += build_attr_msg_type(WPS_M6)
7389     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7390     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7391     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7392     attrs += build_attr_authenticator(authkey, m5, attrs)
7393     m6 = build_eap_wsc(1, eap_id, attrs)
7394     send_wsc_msg(dev[0], bssid, m6)
7395     eap_id = (eap_id + 1) % 256
7396
7397     logger.debug("Receive M7 (NACK) from STA")
7398     msg = get_wsc_msg(dev[0])
7399     if msg['wsc_opcode'] != WSC_NACK:
7400         raise Exception("Unexpected message - expected WSC_Nack")
7401
7402     dev[0].request("WPS_CANCEL")
7403     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7404     dev[0].wait_disconnected()
7405
7406 def test_wps_ext_proto_m8_no_encr_settings(dev, apdev):
7407     """WPS and no Encr Settings in M6"""
7408     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7409
7410     logger.debug("Send M6 to STA")
7411     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7412     attrs += build_attr_msg_type(WPS_M6)
7413     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7414     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7415     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7416     attrs += build_attr_authenticator(authkey, m5, attrs)
7417     raw_m6_attrs = attrs
7418     m6 = build_eap_wsc(1, eap_id, attrs)
7419     send_wsc_msg(dev[0], bssid, m6)
7420     eap_id = (eap_id + 1) % 256
7421
7422     logger.debug("Receive M7 from STA")
7423     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
7424
7425     logger.debug("Send M8 to STA")
7426     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7427     attrs += build_attr_msg_type(WPS_M8)
7428     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7429     #attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
7430     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7431     raw_m8_attrs = attrs
7432     m8 = build_eap_wsc(1, eap_id, attrs)
7433     send_wsc_msg(dev[0], bssid, m8)
7434
7435     logger.debug("Receive WSC_Done (NACK) from STA")
7436     msg = get_wsc_msg(dev[0])
7437     if msg['wsc_opcode'] != WSC_NACK:
7438         raise Exception("Unexpected message - expected WSC_Nack")
7439
7440     dev[0].request("WPS_CANCEL")
7441     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7442     dev[0].wait_disconnected()
7443
7444 def wps_start_ext_reg(apdev, dev):
7445     addr = dev.own_addr()
7446     bssid = apdev['bssid']
7447     ssid = "test-wps-conf"
7448     appin = "12345670"
7449     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
7450                "wpa_passphrase": "12345678", "wpa": "2",
7451                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
7452                "ap_pin": appin }
7453     hapd = hostapd.add_ap(apdev['ifname'], params)
7454
7455     dev.scan_for_bss(bssid, freq="2412")
7456     hapd.request("SET ext_eapol_frame_io 1")
7457     dev.request("SET ext_eapol_frame_io 1")
7458
7459     dev.request("WPS_REG " + bssid + " " + appin)
7460
7461     return addr,bssid,hapd
7462
7463 def wps_run_ap_settings_proto(dev, apdev, ap_settings, success):
7464     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7465     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7466     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7467
7468     logger.debug("Receive M1 from AP")
7469     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7470     mac_addr = m1_attrs[ATTR_MAC_ADDR]
7471     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7472     e_pk = m1_attrs[ATTR_PUBLIC_KEY]
7473
7474     appin = '12345670'
7475     uuid_r = 16*'\x33'
7476     r_nonce = 16*'\x44'
7477     own_private, r_pk = wsc_dh_init()
7478     authkey,keywrapkey = wsc_dh_kdf(e_pk, own_private, mac_addr, e_nonce,
7479                                     r_nonce)
7480     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, appin, e_pk, r_pk)
7481
7482     logger.debug("Send M2 to AP")
7483     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, msg['eap_identifier'],
7484                                 e_nonce, r_nonce, uuid_r, r_pk, eap_code=2)
7485     send_wsc_msg(hapd, addr, m2)
7486
7487     logger.debug("Receive M3 from AP")
7488     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M3)
7489
7490     logger.debug("Send M4 to AP")
7491     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7492     attrs += build_attr_msg_type(WPS_M4)
7493     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7494     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7495     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7496     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7497     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7498     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7499     raw_m4_attrs = attrs
7500     m4 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7501     send_wsc_msg(hapd, addr, m4)
7502
7503     logger.debug("Receive M5 from AP")
7504     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M5)
7505
7506     logger.debug("Send M6 to STA")
7507     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7508     attrs += build_attr_msg_type(WPS_M6)
7509     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7510     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7511     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7512     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
7513     raw_m6_attrs = attrs
7514     m6 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7515     send_wsc_msg(hapd, addr, m6)
7516
7517     logger.debug("Receive M7 from AP")
7518     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M7)
7519
7520     logger.debug("Send M8 to STA")
7521     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7522     attrs += build_attr_msg_type(WPS_M8)
7523     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7524     if ap_settings:
7525         attrs += build_attr_encr_settings(authkey, keywrapkey, ap_settings)
7526     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7527     raw_m8_attrs = attrs
7528     m8 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7529     send_wsc_msg(hapd, addr, m8)
7530
7531     if success:
7532         ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
7533         if ev is None:
7534             raise Exception("New AP settings not reported")
7535         logger.debug("Receive WSC_Done from AP")
7536         msg = get_wsc_msg(hapd)
7537         if msg['wsc_opcode'] != WSC_Done:
7538             raise Exception("Unexpected message - expected WSC_Done")
7539
7540         logger.debug("Send WSC_ACK to AP")
7541         ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
7542                               eap_code=2)
7543         send_wsc_msg(hapd, addr, ack)
7544         dev[0].wait_disconnected()
7545     else:
7546         ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
7547         if ev is None:
7548             raise Exception("WPS failure not reported")
7549         logger.debug("Receive WSC_NACK from AP")
7550         msg = get_wsc_msg(hapd)
7551         if msg['wsc_opcode'] != WSC_NACK:
7552             raise Exception("Unexpected message - expected WSC_NACK")
7553
7554         logger.debug("Send WSC_NACK to AP")
7555         nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7556                                 eap_code=2)
7557         send_wsc_msg(hapd, addr, nack)
7558         dev[0].wait_disconnected()
7559
7560 def test_wps_ext_ap_settings_success(dev, apdev):
7561     """WPS and AP Settings: success"""
7562     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7563     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7564     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7565     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7566     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7567     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7568     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7569
7570 def test_wps_ext_ap_settings_missing(dev, apdev):
7571     """WPS and AP Settings: missing"""
7572     wps_run_ap_settings_proto(dev, apdev, None, False)
7573
7574 def test_wps_ext_ap_settings_mac_addr_mismatch(dev, apdev):
7575     """WPS and AP Settings: MAC Address mismatch"""
7576     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7577     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7578     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7579     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7580     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7581     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, '\x00\x00\x00\x00\x00\x00')
7582     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7583
7584 def test_wps_ext_ap_settings_mac_addr_missing(dev, apdev):
7585     """WPS and AP Settings: missing MAC Address"""
7586     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7587     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7588     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7589     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7590     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7591     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7592
7593 def test_wps_ext_ap_settings_reject_encr_type(dev, apdev):
7594     """WPS and AP Settings: reject Encr Type"""
7595     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7596     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7597     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7598     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x00')
7599     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7600     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7601     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7602
7603 def test_wps_ext_ap_settings_m2d(dev, apdev):
7604     """WPS and AP Settings: M2D"""
7605     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7606     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7607     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7608
7609     logger.debug("Receive M1 from AP")
7610     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7611     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7612
7613     r_nonce = 16*'\x44'
7614     uuid_r = 16*'\x33'
7615
7616     logger.debug("Send M2D to AP")
7617     m2d, raw_m2d_attrs = build_m2d(raw_m1_attrs, msg['eap_identifier'],
7618                                    e_nonce, r_nonce, uuid_r,
7619                                    dev_pw_id='\x00\x00', eap_code=2)
7620     send_wsc_msg(hapd, addr, m2d)
7621
7622     ev = hapd.wait_event(["WPS-M2D"], timeout=5)
7623     if ev is None:
7624         raise Exception("M2D not reported")
7625
7626     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7627
7628 def wps_wait_ap_nack(hapd, dev, e_nonce, r_nonce):
7629     logger.debug("Receive WSC_NACK from AP")
7630     msg = get_wsc_msg(hapd)
7631     if msg['wsc_opcode'] != WSC_NACK:
7632         raise Exception("Unexpected message - expected WSC_NACK")
7633
7634     logger.debug("Send WSC_NACK to AP")
7635     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7636                             eap_code=2)
7637     send_wsc_msg(hapd, dev.own_addr(), nack)
7638     dev.wait_disconnected()
7639
7640 def test_wps_ext_m3_missing_e_hash1(dev, apdev):
7641     """WPS proto: M3 missing E-Hash1"""
7642     pin = "12345670"
7643     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7644     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7645     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7646
7647     logger.debug("Receive WSC/Start from AP")
7648     msg = get_wsc_msg(hapd)
7649     if msg['wsc_opcode'] != WSC_Start:
7650         raise Exception("Unexpected Op-Code for WSC/Start")
7651
7652     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7653     uuid_e = 16*'\x11'
7654     e_nonce = 16*'\x22'
7655     own_private, e_pk = wsc_dh_init()
7656
7657     logger.debug("Send M1 to AP")
7658     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7659                                 e_nonce, e_pk)
7660     send_wsc_msg(hapd, addr, m1)
7661
7662     logger.debug("Receive M2 from AP")
7663     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7664     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7665     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7666
7667     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7668                                     r_nonce)
7669     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7670
7671     logger.debug("Send M3 to AP")
7672     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7673     attrs += build_attr_msg_type(WPS_M3)
7674     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7675     #attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7676     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7677     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7678     raw_m3_attrs = attrs
7679     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7680     send_wsc_msg(hapd, addr, m3)
7681
7682     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7683
7684 def test_wps_ext_m3_missing_e_hash2(dev, apdev):
7685     """WPS proto: M3 missing E-Hash2"""
7686     pin = "12345670"
7687     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7688     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7689     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7690
7691     logger.debug("Receive WSC/Start from AP")
7692     msg = get_wsc_msg(hapd)
7693     if msg['wsc_opcode'] != WSC_Start:
7694         raise Exception("Unexpected Op-Code for WSC/Start")
7695
7696     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7697     uuid_e = 16*'\x11'
7698     e_nonce = 16*'\x22'
7699     own_private, e_pk = wsc_dh_init()
7700
7701     logger.debug("Send M1 to AP")
7702     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7703                                 e_nonce, e_pk)
7704     send_wsc_msg(hapd, addr, m1)
7705
7706     logger.debug("Receive M2 from AP")
7707     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7708     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7709     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7710
7711     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7712                                     r_nonce)
7713     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7714
7715     logger.debug("Send M3 to AP")
7716     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7717     attrs += build_attr_msg_type(WPS_M3)
7718     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7719     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7720     #attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7721     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7722     raw_m3_attrs = attrs
7723     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7724     send_wsc_msg(hapd, addr, m3)
7725
7726     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7727
7728 def test_wps_ext_m5_missing_e_snonce1(dev, apdev):
7729     """WPS proto: M5 missing E-SNonce1"""
7730     pin = "12345670"
7731     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7732     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7733     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7734
7735     logger.debug("Receive WSC/Start from AP")
7736     msg = get_wsc_msg(hapd)
7737     if msg['wsc_opcode'] != WSC_Start:
7738         raise Exception("Unexpected Op-Code for WSC/Start")
7739
7740     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7741     uuid_e = 16*'\x11'
7742     e_nonce = 16*'\x22'
7743     own_private, e_pk = wsc_dh_init()
7744
7745     logger.debug("Send M1 to AP")
7746     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7747                                 e_nonce, e_pk)
7748     send_wsc_msg(hapd, addr, m1)
7749
7750     logger.debug("Receive M2 from AP")
7751     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7752     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7753     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7754
7755     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7756                                     r_nonce)
7757     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7758
7759     logger.debug("Send M3 to AP")
7760     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7761     attrs += build_attr_msg_type(WPS_M3)
7762     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7763     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7764     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7765     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7766     raw_m3_attrs = attrs
7767     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7768     send_wsc_msg(hapd, addr, m3)
7769
7770     logger.debug("Receive M4 from AP")
7771     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7772
7773     logger.debug("Send M5 to AP")
7774     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7775     attrs += build_attr_msg_type(WPS_M5)
7776     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7777     #data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7778     data = ''
7779     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7780     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7781     raw_m5_attrs = attrs
7782     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7783     send_wsc_msg(hapd, addr, m5)
7784
7785     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7786
7787 def test_wps_ext_m5_e_snonce1_mismatch(dev, apdev):
7788     """WPS proto: M5 E-SNonce1 mismatch"""
7789     pin = "12345670"
7790     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7791     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7792     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7793
7794     logger.debug("Receive WSC/Start from AP")
7795     msg = get_wsc_msg(hapd)
7796     if msg['wsc_opcode'] != WSC_Start:
7797         raise Exception("Unexpected Op-Code for WSC/Start")
7798
7799     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7800     uuid_e = 16*'\x11'
7801     e_nonce = 16*'\x22'
7802     own_private, e_pk = wsc_dh_init()
7803
7804     logger.debug("Send M1 to AP")
7805     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7806                                 e_nonce, e_pk)
7807     send_wsc_msg(hapd, addr, m1)
7808
7809     logger.debug("Receive M2 from AP")
7810     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7811     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7812     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7813
7814     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7815                                     r_nonce)
7816     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7817
7818     logger.debug("Send M3 to AP")
7819     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7820     attrs += build_attr_msg_type(WPS_M3)
7821     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7822     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7823     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7824     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7825     raw_m3_attrs = attrs
7826     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7827     send_wsc_msg(hapd, addr, m3)
7828
7829     logger.debug("Receive M4 from AP")
7830     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7831
7832     logger.debug("Send M5 to AP")
7833     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7834     attrs += build_attr_msg_type(WPS_M5)
7835     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7836     data = build_wsc_attr(ATTR_E_SNONCE1, 16*'\x00')
7837     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7838     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7839     raw_m5_attrs = attrs
7840     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7841     send_wsc_msg(hapd, addr, m5)
7842
7843     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7844
7845 def test_wps_ext_m7_missing_e_snonce2(dev, apdev):
7846     """WPS proto: M7 missing E-SNonce2"""
7847     pin = "12345670"
7848     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7849     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7850     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7851
7852     logger.debug("Receive WSC/Start from AP")
7853     msg = get_wsc_msg(hapd)
7854     if msg['wsc_opcode'] != WSC_Start:
7855         raise Exception("Unexpected Op-Code for WSC/Start")
7856
7857     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7858     uuid_e = 16*'\x11'
7859     e_nonce = 16*'\x22'
7860     own_private, e_pk = wsc_dh_init()
7861
7862     logger.debug("Send M1 to AP")
7863     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7864                                 e_nonce, e_pk)
7865     send_wsc_msg(hapd, addr, m1)
7866
7867     logger.debug("Receive M2 from AP")
7868     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7869     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7870     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7871
7872     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7873                                     r_nonce)
7874     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7875
7876     logger.debug("Send M3 to AP")
7877     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7878     attrs += build_attr_msg_type(WPS_M3)
7879     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7880     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7881     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7882     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7883     raw_m3_attrs = attrs
7884     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7885     send_wsc_msg(hapd, addr, m3)
7886
7887     logger.debug("Receive M4 from AP")
7888     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7889
7890     logger.debug("Send M5 to AP")
7891     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7892     attrs += build_attr_msg_type(WPS_M5)
7893     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7894     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7895     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7896     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7897     raw_m5_attrs = attrs
7898     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7899     send_wsc_msg(hapd, addr, m5)
7900
7901     logger.debug("Receive M6 from AP")
7902     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
7903
7904     logger.debug("Send M7 to AP")
7905     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7906     attrs += build_attr_msg_type(WPS_M7)
7907     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7908     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
7909     data = ''
7910     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7911     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
7912     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7913     raw_m7_attrs = attrs
7914     send_wsc_msg(hapd, addr, m7)
7915
7916     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7917
7918 def test_wps_ext_m7_e_snonce2_mismatch(dev, apdev):
7919     """WPS proto: M7 E-SNonce2 mismatch"""
7920     pin = "12345670"
7921     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7922     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7923     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7924
7925     logger.debug("Receive WSC/Start from AP")
7926     msg = get_wsc_msg(hapd)
7927     if msg['wsc_opcode'] != WSC_Start:
7928         raise Exception("Unexpected Op-Code for WSC/Start")
7929
7930     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7931     uuid_e = 16*'\x11'
7932     e_nonce = 16*'\x22'
7933     own_private, e_pk = wsc_dh_init()
7934
7935     logger.debug("Send M1 to AP")
7936     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7937                                 e_nonce, e_pk)
7938     send_wsc_msg(hapd, addr, m1)
7939
7940     logger.debug("Receive M2 from AP")
7941     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7942     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7943     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7944
7945     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7946                                     r_nonce)
7947     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7948
7949     logger.debug("Send M3 to AP")
7950     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7951     attrs += build_attr_msg_type(WPS_M3)
7952     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7953     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7954     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7955     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7956     raw_m3_attrs = attrs
7957     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7958     send_wsc_msg(hapd, addr, m3)
7959
7960     logger.debug("Receive M4 from AP")
7961     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7962
7963     logger.debug("Send M5 to AP")
7964     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7965     attrs += build_attr_msg_type(WPS_M5)
7966     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7967     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7968     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7969     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7970     raw_m5_attrs = attrs
7971     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7972     send_wsc_msg(hapd, addr, m5)
7973
7974     logger.debug("Receive M6 from AP")
7975     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
7976
7977     logger.debug("Send M7 to AP")
7978     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7979     attrs += build_attr_msg_type(WPS_M7)
7980     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7981     data = build_wsc_attr(ATTR_E_SNONCE2, 16*'\x00')
7982     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7983     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
7984     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7985     raw_m7_attrs = attrs
7986     send_wsc_msg(hapd, addr, m7)
7987
7988     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7989
7990 def test_wps_ext_m1_pubkey_oom(dev, apdev):
7991     """WPS proto: M1 PubKey OOM"""
7992     pin = "12345670"
7993     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7994     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7995     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7996
7997     logger.debug("Receive WSC/Start from AP")
7998     msg = get_wsc_msg(hapd)
7999     if msg['wsc_opcode'] != WSC_Start:
8000         raise Exception("Unexpected Op-Code for WSC/Start")
8001
8002     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8003     uuid_e = 16*'\x11'
8004     e_nonce = 16*'\x22'
8005     own_private, e_pk = wsc_dh_init()
8006
8007     logger.debug("Send M1 to AP")
8008     with alloc_fail(hapd, 1, "wpabuf_alloc_copy;wps_process_pubkey"):
8009         m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8010                                     e_nonce, e_pk)
8011         send_wsc_msg(hapd, addr, m1)
8012         wps_wait_eap_failure(hapd, dev[0])
8013
8014 def wps_wait_eap_failure(hapd, dev):
8015     ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
8016     if ev is None:
8017         raise Exception("EAP-Failure not reported")
8018     dev.wait_disconnected()
8019
8020 def test_wps_ext_m3_m1(dev, apdev):
8021     """WPS proto: M3 replaced with M1"""
8022     pin = "12345670"
8023     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8024     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8025     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8026
8027     logger.debug("Receive WSC/Start from AP")
8028     msg = get_wsc_msg(hapd)
8029     if msg['wsc_opcode'] != WSC_Start:
8030         raise Exception("Unexpected Op-Code for WSC/Start")
8031
8032     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8033     uuid_e = 16*'\x11'
8034     e_nonce = 16*'\x22'
8035     own_private, e_pk = wsc_dh_init()
8036
8037     logger.debug("Send M1 to AP")
8038     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8039                                 e_nonce, e_pk)
8040     send_wsc_msg(hapd, addr, m1)
8041
8042     logger.debug("Receive M2 from AP")
8043     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8044     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8045     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8046
8047     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8048                                     r_nonce)
8049     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8050
8051     logger.debug("Send M3(M1) to AP")
8052     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8053     attrs += build_attr_msg_type(WPS_M1)
8054     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8055     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8056     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8057     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8058     raw_m3_attrs = attrs
8059     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8060     send_wsc_msg(hapd, addr, m3)
8061
8062     wps_wait_eap_failure(hapd, dev[0])
8063
8064 def test_wps_ext_m5_m3(dev, apdev):
8065     """WPS proto: M5 replaced with M3"""
8066     pin = "12345670"
8067     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8068     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8069     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8070
8071     logger.debug("Receive WSC/Start from AP")
8072     msg = get_wsc_msg(hapd)
8073     if msg['wsc_opcode'] != WSC_Start:
8074         raise Exception("Unexpected Op-Code for WSC/Start")
8075
8076     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8077     uuid_e = 16*'\x11'
8078     e_nonce = 16*'\x22'
8079     own_private, e_pk = wsc_dh_init()
8080
8081     logger.debug("Send M1 to AP")
8082     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8083                                 e_nonce, e_pk)
8084     send_wsc_msg(hapd, addr, m1)
8085
8086     logger.debug("Receive M2 from AP")
8087     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8088     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8089     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8090
8091     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8092                                     r_nonce)
8093     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8094
8095     logger.debug("Send M3 to AP")
8096     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8097     attrs += build_attr_msg_type(WPS_M3)
8098     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8099     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8100     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8101     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8102     raw_m3_attrs = attrs
8103     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8104     send_wsc_msg(hapd, addr, m3)
8105
8106     logger.debug("Receive M4 from AP")
8107     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8108
8109     logger.debug("Send M5(M3) to AP")
8110     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8111     attrs += build_attr_msg_type(WPS_M3)
8112     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8113     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8114     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8115     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8116     raw_m5_attrs = attrs
8117     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8118     send_wsc_msg(hapd, addr, m5)
8119
8120     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8121
8122 def test_wps_ext_m3_m2(dev, apdev):
8123     """WPS proto: M3 replaced with M2"""
8124     pin = "12345670"
8125     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8126     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8127     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8128
8129     logger.debug("Receive WSC/Start from AP")
8130     msg = get_wsc_msg(hapd)
8131     if msg['wsc_opcode'] != WSC_Start:
8132         raise Exception("Unexpected Op-Code for WSC/Start")
8133
8134     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8135     uuid_e = 16*'\x11'
8136     e_nonce = 16*'\x22'
8137     own_private, e_pk = wsc_dh_init()
8138
8139     logger.debug("Send M1 to AP")
8140     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8141                                 e_nonce, e_pk)
8142     send_wsc_msg(hapd, addr, m1)
8143
8144     logger.debug("Receive M2 from AP")
8145     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8146     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8147     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8148
8149     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8150                                     r_nonce)
8151     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8152
8153     logger.debug("Send M3(M2) to AP")
8154     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8155     attrs += build_attr_msg_type(WPS_M2)
8156     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8157     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8158     raw_m3_attrs = attrs
8159     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8160     send_wsc_msg(hapd, addr, m3)
8161
8162     wps_wait_eap_failure(hapd, dev[0])
8163
8164 def test_wps_ext_m3_m5(dev, apdev):
8165     """WPS proto: M3 replaced with M5"""
8166     pin = "12345670"
8167     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8168     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8169     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8170
8171     logger.debug("Receive WSC/Start from AP")
8172     msg = get_wsc_msg(hapd)
8173     if msg['wsc_opcode'] != WSC_Start:
8174         raise Exception("Unexpected Op-Code for WSC/Start")
8175
8176     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8177     uuid_e = 16*'\x11'
8178     e_nonce = 16*'\x22'
8179     own_private, e_pk = wsc_dh_init()
8180
8181     logger.debug("Send M1 to AP")
8182     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8183                                 e_nonce, e_pk)
8184     send_wsc_msg(hapd, addr, m1)
8185
8186     logger.debug("Receive M2 from AP")
8187     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8188     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8189     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8190
8191     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8192                                     r_nonce)
8193     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8194
8195     logger.debug("Send M3(M5) to AP")
8196     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8197     attrs += build_attr_msg_type(WPS_M5)
8198     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8199     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8200     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8201     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8202     raw_m3_attrs = attrs
8203     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8204     send_wsc_msg(hapd, addr, m3)
8205
8206     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8207
8208 def test_wps_ext_m3_m7(dev, apdev):
8209     """WPS proto: M3 replaced with M7"""
8210     pin = "12345670"
8211     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8212     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8213     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8214
8215     logger.debug("Receive WSC/Start from AP")
8216     msg = get_wsc_msg(hapd)
8217     if msg['wsc_opcode'] != WSC_Start:
8218         raise Exception("Unexpected Op-Code for WSC/Start")
8219
8220     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8221     uuid_e = 16*'\x11'
8222     e_nonce = 16*'\x22'
8223     own_private, e_pk = wsc_dh_init()
8224
8225     logger.debug("Send M1 to AP")
8226     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8227                                 e_nonce, e_pk)
8228     send_wsc_msg(hapd, addr, m1)
8229
8230     logger.debug("Receive M2 from AP")
8231     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8232     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8233     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8234
8235     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8236                                     r_nonce)
8237     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8238
8239     logger.debug("Send M3(M7) to AP")
8240     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8241     attrs += build_attr_msg_type(WPS_M7)
8242     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8243     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8244     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8245     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8246     raw_m3_attrs = attrs
8247     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8248     send_wsc_msg(hapd, addr, m3)
8249
8250     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8251
8252 def test_wps_ext_m3_done(dev, apdev):
8253     """WPS proto: M3 replaced with WSC_Done"""
8254     pin = "12345670"
8255     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8256     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8257     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8258
8259     logger.debug("Receive WSC/Start from AP")
8260     msg = get_wsc_msg(hapd)
8261     if msg['wsc_opcode'] != WSC_Start:
8262         raise Exception("Unexpected Op-Code for WSC/Start")
8263
8264     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8265     uuid_e = 16*'\x11'
8266     e_nonce = 16*'\x22'
8267     own_private, e_pk = wsc_dh_init()
8268
8269     logger.debug("Send M1 to AP")
8270     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8271                                 e_nonce, e_pk)
8272     send_wsc_msg(hapd, addr, m1)
8273
8274     logger.debug("Receive M2 from AP")
8275     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8276     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8277     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8278
8279     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8280                                     r_nonce)
8281     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8282
8283     logger.debug("Send M3(WSC_Done) to AP")
8284     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8285     attrs += build_attr_msg_type(WPS_WSC_DONE)
8286     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8287     raw_m3_attrs = attrs
8288     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8289     send_wsc_msg(hapd, addr, m3)
8290
8291     wps_wait_eap_failure(hapd, dev[0])
8292
8293 def test_wps_ext_m2_nack_invalid(dev, apdev):
8294     """WPS proto: M2 followed by invalid NACK"""
8295     pin = "12345670"
8296     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8297     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8298     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8299
8300     logger.debug("Receive WSC/Start from AP")
8301     msg = get_wsc_msg(hapd)
8302     if msg['wsc_opcode'] != WSC_Start:
8303         raise Exception("Unexpected Op-Code for WSC/Start")
8304
8305     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8306     uuid_e = 16*'\x11'
8307     e_nonce = 16*'\x22'
8308     own_private, e_pk = wsc_dh_init()
8309
8310     logger.debug("Send M1 to AP")
8311     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8312                                 e_nonce, e_pk)
8313     send_wsc_msg(hapd, addr, m1)
8314
8315     logger.debug("Receive M2 from AP")
8316     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8317     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8318     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8319
8320     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8321                                     r_nonce)
8322     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8323
8324     logger.debug("Send WSC_NACK to AP")
8325     attrs = '\x10\x00\x00'
8326     nack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_NACK)
8327     send_wsc_msg(hapd, addr, nack)
8328
8329     wps_wait_eap_failure(hapd, dev[0])
8330
8331 def test_wps_ext_m2_nack_no_msg_type(dev, apdev):
8332     """WPS proto: M2 followed by NACK without Msg Type"""
8333     pin = "12345670"
8334     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8335     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8336     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8337
8338     logger.debug("Receive WSC/Start from AP")
8339     msg = get_wsc_msg(hapd)
8340     if msg['wsc_opcode'] != WSC_Start:
8341         raise Exception("Unexpected Op-Code for WSC/Start")
8342
8343     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8344     uuid_e = 16*'\x11'
8345     e_nonce = 16*'\x22'
8346     own_private, e_pk = wsc_dh_init()
8347
8348     logger.debug("Send M1 to AP")
8349     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8350                                 e_nonce, e_pk)
8351     send_wsc_msg(hapd, addr, m1)
8352
8353     logger.debug("Receive M2 from AP")
8354     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8355     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8356     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8357
8358     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8359                                     r_nonce)
8360     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8361
8362     logger.debug("Send WSC_NACK to AP")
8363     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8364                             msg_type=None, eap_code=2)
8365     send_wsc_msg(hapd, addr, nack)
8366
8367     wps_wait_eap_failure(hapd, dev[0])
8368
8369 def test_wps_ext_m2_nack_invalid_msg_type(dev, apdev):
8370     """WPS proto: M2 followed by NACK with invalid Msg Type"""
8371     pin = "12345670"
8372     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8373     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8374     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8375
8376     logger.debug("Receive WSC/Start from AP")
8377     msg = get_wsc_msg(hapd)
8378     if msg['wsc_opcode'] != WSC_Start:
8379         raise Exception("Unexpected Op-Code for WSC/Start")
8380
8381     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8382     uuid_e = 16*'\x11'
8383     e_nonce = 16*'\x22'
8384     own_private, e_pk = wsc_dh_init()
8385
8386     logger.debug("Send M1 to AP")
8387     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8388                                 e_nonce, e_pk)
8389     send_wsc_msg(hapd, addr, m1)
8390
8391     logger.debug("Receive M2 from AP")
8392     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8393     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8394     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8395
8396     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8397                                     r_nonce)
8398     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8399
8400     logger.debug("Send WSC_NACK to AP")
8401     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8402                             msg_type=WPS_WSC_ACK, eap_code=2)
8403     send_wsc_msg(hapd, addr, nack)
8404
8405     wps_wait_eap_failure(hapd, dev[0])
8406
8407 def test_wps_ext_m2_nack_e_nonce_mismatch(dev, apdev):
8408     """WPS proto: M2 followed by NACK with e-nonce mismatch"""
8409     pin = "12345670"
8410     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8411     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8412     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8413
8414     logger.debug("Receive WSC/Start from AP")
8415     msg = get_wsc_msg(hapd)
8416     if msg['wsc_opcode'] != WSC_Start:
8417         raise Exception("Unexpected Op-Code for WSC/Start")
8418
8419     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8420     uuid_e = 16*'\x11'
8421     e_nonce = 16*'\x22'
8422     own_private, e_pk = wsc_dh_init()
8423
8424     logger.debug("Send M1 to AP")
8425     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8426                                 e_nonce, e_pk)
8427     send_wsc_msg(hapd, addr, m1)
8428
8429     logger.debug("Receive M2 from AP")
8430     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8431     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8432     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8433
8434     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8435                                     r_nonce)
8436     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8437
8438     logger.debug("Send WSC_NACK to AP")
8439     nack,attrs = build_nack(msg['eap_identifier'], 16*'\x00', r_nonce,
8440                             eap_code=2)
8441     send_wsc_msg(hapd, addr, nack)
8442
8443     wps_wait_eap_failure(hapd, dev[0])
8444
8445 def test_wps_ext_m2_nack_no_config_error(dev, apdev):
8446     """WPS proto: M2 followed by NACK without Config Error"""
8447     pin = "12345670"
8448     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8449     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8450     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8451
8452     logger.debug("Receive WSC/Start from AP")
8453     msg = get_wsc_msg(hapd)
8454     if msg['wsc_opcode'] != WSC_Start:
8455         raise Exception("Unexpected Op-Code for WSC/Start")
8456
8457     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8458     uuid_e = 16*'\x11'
8459     e_nonce = 16*'\x22'
8460     own_private, e_pk = wsc_dh_init()
8461
8462     logger.debug("Send M1 to AP")
8463     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8464                                 e_nonce, e_pk)
8465     send_wsc_msg(hapd, addr, m1)
8466
8467     logger.debug("Receive M2 from AP")
8468     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8469     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8470     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8471
8472     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8473                                     r_nonce)
8474     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8475
8476     logger.debug("Send WSC_NACK to AP")
8477     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8478                             config_error=None, eap_code=2)
8479     send_wsc_msg(hapd, addr, nack)
8480
8481     wps_wait_eap_failure(hapd, dev[0])
8482
8483 def test_wps_ext_m2_ack_invalid(dev, apdev):
8484     """WPS proto: M2 followed by invalid ACK"""
8485     pin = "12345670"
8486     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8487     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8488     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8489
8490     logger.debug("Receive WSC/Start from AP")
8491     msg = get_wsc_msg(hapd)
8492     if msg['wsc_opcode'] != WSC_Start:
8493         raise Exception("Unexpected Op-Code for WSC/Start")
8494
8495     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8496     uuid_e = 16*'\x11'
8497     e_nonce = 16*'\x22'
8498     own_private, e_pk = wsc_dh_init()
8499
8500     logger.debug("Send M1 to AP")
8501     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8502                                 e_nonce, e_pk)
8503     send_wsc_msg(hapd, addr, m1)
8504
8505     logger.debug("Receive M2 from AP")
8506     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8507     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8508     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8509
8510     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8511                                     r_nonce)
8512     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8513
8514     logger.debug("Send WSC_ACK to AP")
8515     attrs = '\x10\x00\x00'
8516     ack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_ACK)
8517     send_wsc_msg(hapd, addr, ack)
8518
8519     wps_wait_eap_failure(hapd, dev[0])
8520
8521 def test_wps_ext_m2_ack(dev, apdev):
8522     """WPS proto: M2 followed by ACK"""
8523     pin = "12345670"
8524     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8525     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8526     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8527
8528     logger.debug("Receive WSC/Start from AP")
8529     msg = get_wsc_msg(hapd)
8530     if msg['wsc_opcode'] != WSC_Start:
8531         raise Exception("Unexpected Op-Code for WSC/Start")
8532
8533     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8534     uuid_e = 16*'\x11'
8535     e_nonce = 16*'\x22'
8536     own_private, e_pk = wsc_dh_init()
8537
8538     logger.debug("Send M1 to AP")
8539     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8540                                 e_nonce, e_pk)
8541     send_wsc_msg(hapd, addr, m1)
8542
8543     logger.debug("Receive M2 from AP")
8544     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8545     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8546     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8547
8548     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8549                                     r_nonce)
8550     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8551
8552     logger.debug("Send WSC_ACK to AP")
8553     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce, eap_code=2)
8554     send_wsc_msg(hapd, addr, ack)
8555
8556     wps_wait_eap_failure(hapd, dev[0])
8557
8558 def test_wps_ext_m2_ack_no_msg_type(dev, apdev):
8559     """WPS proto: M2 followed by ACK missing Msg Type"""
8560     pin = "12345670"
8561     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8562     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8563     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8564
8565     logger.debug("Receive WSC/Start from AP")
8566     msg = get_wsc_msg(hapd)
8567     if msg['wsc_opcode'] != WSC_Start:
8568         raise Exception("Unexpected Op-Code for WSC/Start")
8569
8570     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8571     uuid_e = 16*'\x11'
8572     e_nonce = 16*'\x22'
8573     own_private, e_pk = wsc_dh_init()
8574
8575     logger.debug("Send M1 to AP")
8576     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8577                                 e_nonce, e_pk)
8578     send_wsc_msg(hapd, addr, m1)
8579
8580     logger.debug("Receive M2 from AP")
8581     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8582     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8583     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8584
8585     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8586                                     r_nonce)
8587     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8588
8589     logger.debug("Send WSC_ACK to AP")
8590     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8591                           msg_type=None, eap_code=2)
8592     send_wsc_msg(hapd, addr, ack)
8593
8594     wps_wait_eap_failure(hapd, dev[0])
8595
8596 def test_wps_ext_m2_ack_invalid_msg_type(dev, apdev):
8597     """WPS proto: M2 followed by ACK with invalid Msg Type"""
8598     pin = "12345670"
8599     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8600     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8601     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8602
8603     logger.debug("Receive WSC/Start from AP")
8604     msg = get_wsc_msg(hapd)
8605     if msg['wsc_opcode'] != WSC_Start:
8606         raise Exception("Unexpected Op-Code for WSC/Start")
8607
8608     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8609     uuid_e = 16*'\x11'
8610     e_nonce = 16*'\x22'
8611     own_private, e_pk = wsc_dh_init()
8612
8613     logger.debug("Send M1 to AP")
8614     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8615                                 e_nonce, e_pk)
8616     send_wsc_msg(hapd, addr, m1)
8617
8618     logger.debug("Receive M2 from AP")
8619     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8620     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8621     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8622
8623     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8624                                     r_nonce)
8625     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8626
8627     logger.debug("Send WSC_ACK to AP")
8628     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8629                           msg_type=WPS_WSC_NACK, eap_code=2)
8630     send_wsc_msg(hapd, addr, ack)
8631
8632     wps_wait_eap_failure(hapd, dev[0])
8633
8634 def test_wps_ext_m2_ack_e_nonce_mismatch(dev, apdev):
8635     """WPS proto: M2 followed by ACK with e-nonce mismatch"""
8636     pin = "12345670"
8637     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8638     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8639     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8640
8641     logger.debug("Receive WSC/Start from AP")
8642     msg = get_wsc_msg(hapd)
8643     if msg['wsc_opcode'] != WSC_Start:
8644         raise Exception("Unexpected Op-Code for WSC/Start")
8645
8646     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8647     uuid_e = 16*'\x11'
8648     e_nonce = 16*'\x22'
8649     own_private, e_pk = wsc_dh_init()
8650
8651     logger.debug("Send M1 to AP")
8652     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8653                                 e_nonce, e_pk)
8654     send_wsc_msg(hapd, addr, m1)
8655
8656     logger.debug("Receive M2 from AP")
8657     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8658     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8659     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8660
8661     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8662                                     r_nonce)
8663     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8664
8665     logger.debug("Send WSC_ACK to AP")
8666     ack,attrs = build_ack(msg['eap_identifier'], 16*'\x00', r_nonce,
8667                           eap_code=2)
8668     send_wsc_msg(hapd, addr, ack)
8669
8670     wps_wait_eap_failure(hapd, dev[0])
8671
8672 def test_wps_ext_m1_invalid(dev, apdev):
8673     """WPS proto: M1 failing parsing"""
8674     pin = "12345670"
8675     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8676     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8677     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8678
8679     logger.debug("Receive WSC/Start from AP")
8680     msg = get_wsc_msg(hapd)
8681     if msg['wsc_opcode'] != WSC_Start:
8682         raise Exception("Unexpected Op-Code for WSC/Start")
8683
8684     logger.debug("Send M1 to AP")
8685     attrs = '\x10\x00\x00'
8686     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8687     send_wsc_msg(hapd, addr, m1)
8688
8689     wps_wait_eap_failure(hapd, dev[0])
8690
8691 def test_wps_ext_m1_missing_msg_type(dev, apdev):
8692     """WPS proto: M1 missing Msg Type"""
8693     pin = "12345670"
8694     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8695     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8696     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8697
8698     logger.debug("Receive WSC/Start from AP")
8699     msg = get_wsc_msg(hapd)
8700     if msg['wsc_opcode'] != WSC_Start:
8701         raise Exception("Unexpected Op-Code for WSC/Start")
8702
8703     logger.debug("Send M1 to AP")
8704     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8705     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8706     send_wsc_msg(hapd, addr, m1)
8707
8708     wps_wait_ap_nack(hapd, dev[0], 16*'\x00', 16*'\x00')
8709
8710 def wps_ext_wsc_done(dev, apdev):
8711     pin = "12345670"
8712     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8713     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8714     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8715
8716     logger.debug("Receive WSC/Start from AP")
8717     msg = get_wsc_msg(hapd)
8718     if msg['wsc_opcode'] != WSC_Start:
8719         raise Exception("Unexpected Op-Code for WSC/Start")
8720
8721     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8722     uuid_e = 16*'\x11'
8723     e_nonce = 16*'\x22'
8724     own_private, e_pk = wsc_dh_init()
8725
8726     logger.debug("Send M1 to AP")
8727     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8728                                 e_nonce, e_pk)
8729     send_wsc_msg(hapd, addr, m1)
8730
8731     logger.debug("Receive M2 from AP")
8732     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8733     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8734     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8735
8736     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8737                                     r_nonce)
8738     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8739
8740     logger.debug("Send M3 to AP")
8741     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8742     attrs += build_attr_msg_type(WPS_M3)
8743     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8744     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8745     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8746     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8747     raw_m3_attrs = attrs
8748     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8749     send_wsc_msg(hapd, addr, m3)
8750
8751     logger.debug("Receive M4 from AP")
8752     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8753
8754     logger.debug("Send M5 to AP")
8755     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8756     attrs += build_attr_msg_type(WPS_M5)
8757     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8758     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8759     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8760     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8761     raw_m5_attrs = attrs
8762     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8763     send_wsc_msg(hapd, addr, m5)
8764
8765     logger.debug("Receive M6 from AP")
8766     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8767
8768     logger.debug("Send M7 to AP")
8769     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8770     attrs += build_attr_msg_type(WPS_M7)
8771     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8772     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8773     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8774     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8775     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8776     raw_m7_attrs = attrs
8777     send_wsc_msg(hapd, addr, m7)
8778
8779     logger.debug("Receive M8 from AP")
8780     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
8781     return hapd, msg, e_nonce, r_nonce
8782
8783 def test_wps_ext_wsc_done_invalid(dev, apdev):
8784     """WPS proto: invalid WSC_Done"""
8785     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8786
8787     logger.debug("Send WSC_Done to AP")
8788     attrs = '\x10\x00\x00'
8789     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8790     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8791
8792     wps_wait_eap_failure(hapd, dev[0])
8793
8794 def test_wps_ext_wsc_done_no_msg_type(dev, apdev):
8795     """WPS proto: invalid WSC_Done"""
8796     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8797
8798     logger.debug("Send WSC_Done to AP")
8799     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8800     #attrs += build_attr_msg_type(WPS_WSC_DONE)
8801     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8802     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8803     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8804     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8805
8806     wps_wait_eap_failure(hapd, dev[0])
8807
8808 def test_wps_ext_wsc_done_wrong_msg_type(dev, apdev):
8809     """WPS proto: WSC_Done with wrong Msg Type"""
8810     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8811
8812     logger.debug("Send WSC_Done to AP")
8813     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8814     attrs += build_attr_msg_type(WPS_WSC_ACK)
8815     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8816     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8817     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8818     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8819
8820     wps_wait_eap_failure(hapd, dev[0])
8821
8822 def test_wps_ext_wsc_done_no_e_nonce(dev, apdev):
8823     """WPS proto: WSC_Done without e_nonce"""
8824     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8825
8826     logger.debug("Send WSC_Done to AP")
8827     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8828     attrs += build_attr_msg_type(WPS_WSC_DONE)
8829     #attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8830     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8831     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8832     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8833
8834     wps_wait_eap_failure(hapd, dev[0])
8835
8836 def test_wps_ext_wsc_done_no_r_nonce(dev, apdev):
8837     """WPS proto: WSC_Done without r_nonce"""
8838     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8839
8840     logger.debug("Send WSC_Done to AP")
8841     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8842     attrs += build_attr_msg_type(WPS_WSC_DONE)
8843     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8844     #attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8845     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8846     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8847
8848     wps_wait_eap_failure(hapd, dev[0])
8849
8850 def test_wps_ext_m7_no_encr_settings(dev, apdev):
8851     """WPS proto: M7 without Encr Settings"""
8852     pin = "12345670"
8853     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8854     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8855     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8856
8857     logger.debug("Receive WSC/Start from AP")
8858     msg = get_wsc_msg(hapd)
8859     if msg['wsc_opcode'] != WSC_Start:
8860         raise Exception("Unexpected Op-Code for WSC/Start")
8861
8862     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8863     uuid_e = 16*'\x11'
8864     e_nonce = 16*'\x22'
8865     own_private, e_pk = wsc_dh_init()
8866
8867     logger.debug("Send M1 to AP")
8868     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8869                                 e_nonce, e_pk)
8870     send_wsc_msg(hapd, addr, m1)
8871
8872     logger.debug("Receive M2 from AP")
8873     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8874     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8875     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8876
8877     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8878                                     r_nonce)
8879     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8880
8881     logger.debug("Send M3 to AP")
8882     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8883     attrs += build_attr_msg_type(WPS_M3)
8884     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8885     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8886     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8887     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8888     raw_m3_attrs = attrs
8889     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8890     send_wsc_msg(hapd, addr, m3)
8891
8892     logger.debug("Receive M4 from AP")
8893     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8894
8895     logger.debug("Send M5 to AP")
8896     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8897     attrs += build_attr_msg_type(WPS_M5)
8898     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8899     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8900     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8901     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8902     raw_m5_attrs = attrs
8903     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8904     send_wsc_msg(hapd, addr, m5)
8905
8906     logger.debug("Receive M6 from AP")
8907     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8908
8909     logger.debug("Send M7 to AP")
8910     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8911     attrs += build_attr_msg_type(WPS_M7)
8912     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8913     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8914     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8915     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8916     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8917     raw_m7_attrs = attrs
8918     send_wsc_msg(hapd, addr, m7)
8919
8920     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8921
8922 def test_wps_ext_m1_workaround(dev, apdev):
8923     """WPS proto: M1 Manufacturer/Model workaround"""
8924     pin = "12345670"
8925     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8926     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8927     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8928
8929     logger.debug("Receive WSC/Start from AP")
8930     msg = get_wsc_msg(hapd)
8931     if msg['wsc_opcode'] != WSC_Start:
8932         raise Exception("Unexpected Op-Code for WSC/Start")
8933
8934     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8935     uuid_e = 16*'\x11'
8936     e_nonce = 16*'\x22'
8937     own_private, e_pk = wsc_dh_init()
8938
8939     logger.debug("Send M1 to AP")
8940     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8941                                 e_nonce, e_pk, manufacturer='Apple TEST',
8942                                 model_name='AirPort', config_methods='\xff\xff')
8943     send_wsc_msg(hapd, addr, m1)
8944
8945     logger.debug("Receive M2 from AP")
8946     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)