tests: WPS ER and OOM in HTTP response generation
[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 def test_ap_wps_er_http_proto_no_event_sub_url(dev, apdev):
4358     """WPS ER HTTP protocol testing - no eventSubURL"""
4359     class WPSAPHTTPServer_no_event_sub_url(WPSAPHTTPServer):
4360         def handle_upnp_info(self):
4361             self.wfile.write(gen_upnp_info(eventSubURL=None))
4362     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_event_sub_url,
4363                           no_event_url=True)
4364
4365 def test_ap_wps_er_http_proto_event_sub_url_dns(dev, apdev):
4366     """WPS ER HTTP protocol testing - DNS name in eventSubURL"""
4367     class WPSAPHTTPServer_event_sub_url_dns(WPSAPHTTPServer):
4368         def handle_upnp_info(self):
4369             self.wfile.write(gen_upnp_info(eventSubURL='http://example.com/wps_event'))
4370     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_event_sub_url_dns,
4371                           no_event_url=True)
4372
4373 def test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4374     """WPS ER HTTP protocol testing - subscribe OOM"""
4375     try:
4376         _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev)
4377     finally:
4378         dev[0].request("WPS_ER_STOP")
4379
4380 def _test_ap_wps_er_http_proto_subscribe_oom(dev, apdev):
4381     tests = [ (1, "http_client_url_parse"),
4382               (1, "wpabuf_alloc;wps_er_subscribe"),
4383               (1, "http_client_addr"),
4384               (1, "eloop_register_sock;http_client_addr"),
4385               (1, "eloop_register_timeout;http_client_addr") ]
4386     for count,func in tests:
4387         with alloc_fail(dev[0], count, func):
4388             server,sock = wps_er_start(dev[0], WPSAPHTTPServer)
4389             server.handle_request()
4390             server.handle_request()
4391             wps_er_stop(dev[0], sock, server, on_alloc_fail=True)
4392
4393 def test_ap_wps_er_http_proto_no_sid(dev, apdev):
4394     """WPS ER HTTP protocol testing - no SID"""
4395     class WPSAPHTTPServer_no_sid(WPSAPHTTPServer):
4396         def handle_wps_event(self):
4397             self.wfile.write(gen_wps_event(sid=None))
4398     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_sid)
4399
4400 def test_ap_wps_er_http_proto_invalid_sid_no_uuid(dev, apdev):
4401     """WPS ER HTTP protocol testing - invalid SID - no UUID"""
4402     class WPSAPHTTPServer_invalid_sid_no_uuid(WPSAPHTTPServer):
4403         def handle_wps_event(self):
4404             self.wfile.write(gen_wps_event(sid='FOO'))
4405     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_no_uuid)
4406
4407 def test_ap_wps_er_http_proto_invalid_sid_uuid(dev, apdev):
4408     """WPS ER HTTP protocol testing - invalid SID UUID"""
4409     class WPSAPHTTPServer_invalid_sid_uuid(WPSAPHTTPServer):
4410         def handle_wps_event(self):
4411             self.wfile.write(gen_wps_event(sid='uuid:FOO'))
4412     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_sid_uuid)
4413
4414 def test_ap_wps_er_http_proto_subscribe_failing(dev, apdev):
4415     """WPS ER HTTP protocol testing - SUBSCRIBE failing"""
4416     class WPSAPHTTPServer_fail_subscribe(WPSAPHTTPServer):
4417         def handle_wps_event(self):
4418             payload = ""
4419             hdr = 'HTTP/1.1 404 Not Found\r\n' + \
4420                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4421                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4422                   'Connection: close\r\n' + \
4423                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4424                   'Timeout: Second-1801\r\n' + \
4425                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4426             self.wfile.write(hdr + payload)
4427     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_fail_subscribe)
4428
4429 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4430     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4431     class WPSAPHTTPServer_subscribe_invalid_response(WPSAPHTTPServer):
4432         def handle_wps_event(self):
4433             payload = ""
4434             hdr = 'HTTP/1.1 FOO\r\n' + \
4435                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4436                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4437                   'Connection: close\r\n' + \
4438                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4439                   'Timeout: Second-1801\r\n' + \
4440                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4441             self.wfile.write(hdr + payload)
4442     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_subscribe_invalid_response)
4443
4444 def test_ap_wps_er_http_proto_subscribe_invalid_response(dev, apdev):
4445     """WPS ER HTTP protocol testing - SUBSCRIBE and invalid response"""
4446     class WPSAPHTTPServer_invalid_m1(WPSAPHTTPServer):
4447         def handle_wps_control(self):
4448             payload = '''<?xml version="1.0"?>
4449 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
4450 <s:Body>
4451 <u:GetDeviceInfoResponse xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">
4452 <NewDeviceInfo>Rk9P</NewDeviceInfo>
4453 </u:GetDeviceInfoResponse>
4454 </s:Body>
4455 </s:Envelope>
4456 '''
4457             self.wfile.write(gen_wps_control(payload_override=payload))
4458     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_m1, no_event_url=True)
4459
4460 def test_ap_wps_er_http_proto_upnp_info_no_device(dev, apdev):
4461     """WPS ER HTTP protocol testing - No device in UPnP info"""
4462     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4463         def handle_upnp_info(self):
4464             payload = '''<?xml version="1.0"?>
4465 <root xmlns="urn:schemas-upnp-org:device-1-0">
4466 <specVersion>
4467 <major>1</major>
4468 <minor>0</minor>
4469 </specVersion>
4470 </root>
4471 '''
4472             hdr = 'HTTP/1.1 200 OK\r\n' + \
4473                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4474                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4475                   'Connection: close\r\n' + \
4476                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4477                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4478             self.wfile.write(hdr + payload)
4479     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4480
4481 def test_ap_wps_er_http_proto_upnp_info_no_device_type(dev, apdev):
4482     """WPS ER HTTP protocol testing - No deviceType in UPnP info"""
4483     class WPSAPHTTPServer_no_device(WPSAPHTTPServer):
4484         def handle_upnp_info(self):
4485             payload = '''<?xml version="1.0"?>
4486 <root xmlns="urn:schemas-upnp-org:device-1-0">
4487 <specVersion>
4488 <major>1</major>
4489 <minor>0</minor>
4490 </specVersion>
4491 <device>
4492 </device>
4493 </root>
4494 '''
4495             hdr = 'HTTP/1.1 200 OK\r\n' + \
4496                   'Content-Type: text/xml; charset="utf-8"\r\n' + \
4497                   'Server: Unspecified, UPnP/1.0, Unspecified\r\n' + \
4498                   'Connection: close\r\n' + \
4499                   'Content-Length: ' + str(len(payload)) + '\r\n' + \
4500                   'Date: Sat, 15 Aug 2015 18:55:08 GMT\r\n\r\n'
4501             self.wfile.write(hdr + payload)
4502     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_device, no_event_url=True)
4503
4504 def test_ap_wps_er_http_proto_upnp_info_invalid_udn_uuid(dev, apdev):
4505     """WPS ER HTTP protocol testing - Invalid UDN UUID"""
4506     class WPSAPHTTPServer_invalid_udn_uuid(WPSAPHTTPServer):
4507         def handle_upnp_info(self):
4508             self.wfile.write(gen_upnp_info(udn='uuid:foo'))
4509     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_invalid_udn_uuid)
4510
4511 def test_ap_wps_er_http_proto_no_control_url(dev, apdev):
4512     """WPS ER HTTP protocol testing - no controlURL"""
4513     class WPSAPHTTPServer_no_control_url(WPSAPHTTPServer):
4514         def handle_upnp_info(self):
4515             self.wfile.write(gen_upnp_info(controlURL=None))
4516     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_no_control_url,
4517                           no_event_url=True)
4518
4519 def test_ap_wps_er_http_proto_control_url_dns(dev, apdev):
4520     """WPS ER HTTP protocol testing - DNS name in controlURL"""
4521     class WPSAPHTTPServer_control_url_dns(WPSAPHTTPServer):
4522         def handle_upnp_info(self):
4523             self.wfile.write(gen_upnp_info(controlURL='http://example.com/wps_control'))
4524     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_control_url_dns,
4525                           no_event_url=True)
4526
4527 def test_ap_wps_http_timeout(dev, apdev):
4528     """WPS AP/ER and HTTP timeout"""
4529     try:
4530         _test_ap_wps_http_timeout(dev, apdev)
4531     finally:
4532         dev[0].request("WPS_ER_STOP")
4533
4534 def _test_ap_wps_http_timeout(dev, apdev):
4535     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
4536     add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
4537
4538     location = ssdp_get_location(ap_uuid)
4539     url = urlparse.urlparse(location)
4540     addr = (url.hostname, url.port)
4541     logger.debug("Open HTTP connection to hostapd, but do not complete request")
4542     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM,
4543                          socket.IPPROTO_TCP)
4544     sock.connect(addr)
4545     sock.send("G")
4546
4547     class DummyServer(SocketServer.StreamRequestHandler):
4548         def handle(self):
4549             logger.debug("DummyServer - start 31 sec wait")
4550             time.sleep(31)
4551             logger.debug("DummyServer - wait done")
4552
4553     logger.debug("Start WPS ER")
4554     server,sock2 = wps_er_start(dev[0], DummyServer, max_age=40,
4555                                 wait_m_search=True)
4556
4557     logger.debug("Start server to accept, but not complete, HTTP connection from WPS ER")
4558     # This will wait for 31 seconds..
4559     server.handle_request()
4560
4561     logger.debug("Complete HTTP connection with hostapd (that should have already closed the connection)")
4562     try:
4563         sock.send("ET / HTTP/1.1\r\n\r\n")
4564         res = sock.recv(100)
4565         sock.close()
4566     except:
4567         pass
4568
4569 def test_ap_wps_er_url_parse(dev, apdev):
4570     """WPS ER and URL parsing special cases"""
4571     try:
4572         _test_ap_wps_er_url_parse(dev, apdev)
4573     finally:
4574         dev[0].request("WPS_ER_STOP")
4575
4576 def _test_ap_wps_er_url_parse(dev, apdev):
4577     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
4578     sock.settimeout(1)
4579     sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
4580     sock.bind(("239.255.255.250", 1900))
4581     dev[0].request("WPS_ER_START ifname=lo")
4582     (msg,addr) = sock.recvfrom(1000)
4583     logger.debug("Received SSDP message from %s: %s" % (str(addr), msg))
4584     if "M-SEARCH" not in msg:
4585         raise Exception("Not an M-SEARCH")
4586     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)
4587     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4588     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)
4589     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4590     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)
4591     ev = dev[0].wait_event(["WPS-ER-AP-REMOVE"], timeout=2)
4592
4593     sock.close()
4594
4595 def test_ap_wps_er_link_update(dev, apdev):
4596     """WPS ER and link update special cases"""
4597     class WPSAPHTTPServer_link_update(WPSAPHTTPServer):
4598         def handle_upnp_info(self):
4599             self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4600     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update)
4601
4602     class WPSAPHTTPServer_link_update2(WPSAPHTTPServer):
4603         def handle_others(self, data):
4604             if "GET / " in data:
4605                 self.wfile.write(gen_upnp_info(controlURL='/wps_control'))
4606     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_link_update2,
4607                           location_url='http://127.0.0.1:12345')
4608
4609 def test_ap_wps_er_http_client(dev, apdev):
4610     """WPS ER and HTTP client special cases"""
4611     with alloc_fail(dev[0], 1, "http_link_update"):
4612         run_wps_er_proto_test(dev[0], WPSAPHTTPServer)
4613
4614     with alloc_fail(dev[0], 1, "wpabuf_alloc;http_client_url"):
4615         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4616
4617     with alloc_fail(dev[0], 1, "httpread_create;http_client_tx_ready"):
4618         run_wps_er_proto_test(dev[0], WPSAPHTTPServer, no_event_url=True)
4619
4620     class WPSAPHTTPServer_req_as_resp(WPSAPHTTPServer):
4621         def handle_upnp_info(self):
4622             self.wfile.write("GET / HTTP/1.1\r\n\r\n")
4623     run_wps_er_proto_test(dev[0], WPSAPHTTPServer_req_as_resp,
4624                           no_event_url=True)
4625
4626 def test_ap_wps_init_oom(dev, apdev):
4627     """wps_init OOM cases"""
4628     ssid = "test-wps"
4629     appin = "12345670"
4630     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4631                "ap_pin": appin }
4632     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4633     pin = dev[0].wps_read_pin()
4634
4635     with alloc_fail(hapd, 1, "wps_init"):
4636         hapd.request("WPS_PIN any " + pin)
4637         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4638         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4639         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4640         if ev is None:
4641             raise Exception("No EAP failure reported")
4642         dev[0].request("WPS_CANCEL")
4643
4644     with alloc_fail(dev[0], 2, "wps_init"):
4645         hapd.request("WPS_PIN any " + pin)
4646         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4647         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4648         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4649         if ev is None:
4650             raise Exception("No EAP failure reported")
4651         dev[0].request("WPS_CANCEL")
4652
4653     with alloc_fail(dev[0], 2, "wps_init"):
4654         hapd.request("WPS_PBC")
4655         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4656         dev[0].request("WPS_PBC %s" % (apdev[0]['bssid']))
4657         ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4658         if ev is None:
4659             raise Exception("No EAP failure reported")
4660         dev[0].request("WPS_CANCEL")
4661
4662     dev[0].dump_monitor()
4663     new_ssid = "wps-new-ssid"
4664     new_passphrase = "1234567890"
4665     with alloc_fail(dev[0], 3, "wps_init"):
4666         dev[0].wps_reg(apdev[0]['bssid'], appin, new_ssid, "WPA2PSK", "CCMP",
4667                        new_passphrase, no_wait=True)
4668         ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4669         if ev is None:
4670             raise Exception("No EAP failure reported")
4671
4672     dev[0].flush_scan_cache()
4673
4674 def test_ap_wps_invalid_assoc_req_elem(dev, apdev):
4675     """WPS and invalid IE in Association Request frame"""
4676     ssid = "test-wps"
4677     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4678     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4679     pin = "12345670"
4680     hapd.request("WPS_PIN any " + pin)
4681     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4682     try:
4683         dev[0].request("VENDOR_ELEM_ADD 13 dd050050f20410")
4684         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4685         for i in range(5):
4686             ev = hapd.wait_event(["CTRL-EVENT-EAP-PROPOSED-METHOD"], timeout=10)
4687             if ev and "vendor=14122" in ev:
4688                 break
4689         if ev is None or "vendor=14122" not in ev:
4690             raise Exception("EAP-WSC not started")
4691         dev[0].request("WPS_CANCEL")
4692     finally:
4693         dev[0].request("VENDOR_ELEM_REMOVE 13 *")
4694
4695 def test_ap_wps_pbc_pin_mismatch(dev, apdev):
4696     """WPS PBC/PIN mismatch"""
4697     ssid = "test-wps"
4698     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4699     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4700     hapd.request("SET wps_version_number 0x10")
4701     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4702     hapd.request("WPS_PBC")
4703     pin = dev[0].wps_read_pin()
4704     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4705     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4706     if ev is None:
4707         raise Exception("Scan did not complete")
4708     dev[0].request("WPS_CANCEL")
4709
4710     hapd.request("WPS_CANCEL")
4711     dev[0].flush_scan_cache()
4712
4713 def test_ap_wps_ie_invalid(dev, apdev):
4714     """WPS PIN attempt with AP that has invalid WSC IE"""
4715     ssid = "test-wps"
4716     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4717                "vendor_elements": "dd050050f20410" }
4718     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4719     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4720     hostapd.add_ap(apdev[1]['ifname'], params)
4721     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4722     pin = dev[0].wps_read_pin()
4723     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4724     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4725     if ev is None:
4726         raise Exception("Scan did not complete")
4727     dev[0].request("WPS_CANCEL")
4728
4729 def test_ap_wps_scan_prio_order(dev, apdev):
4730     """WPS scan priority ordering"""
4731     ssid = "test-wps"
4732     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4733     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4734     params = { 'ssid': "another", "vendor_elements": "dd050050f20410" }
4735     hostapd.add_ap(apdev[1]['ifname'], params)
4736     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4737     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4738     pin = dev[0].wps_read_pin()
4739     dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4740     ev = dev[0].wait_event(["CTRL-EVENT-SCAN-RESULTS"])
4741     if ev is None:
4742         raise Exception("Scan did not complete")
4743     dev[0].request("WPS_CANCEL")
4744
4745 def test_ap_wps_probe_req_ie_oom(dev, apdev):
4746     """WPS ProbeReq IE OOM"""
4747     ssid = "test-wps"
4748     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4749     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4750     pin = dev[0].wps_read_pin()
4751     hapd.request("WPS_PIN any " + pin)
4752     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4753     with alloc_fail(dev[0], 1, "wps_build_probe_req_ie"):
4754         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4755         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4756         if ev is None:
4757             raise Exception("Association not seen")
4758     dev[0].request("WPS_CANCEL")
4759
4760     with alloc_fail(dev[0], 1, "wps_ie_encapsulate"):
4761         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4762         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4763         if ev is None:
4764             raise Exception("Association not seen")
4765     dev[0].request("WPS_CANCEL")
4766
4767 def test_ap_wps_assoc_req_ie_oom(dev, apdev):
4768     """WPS AssocReq IE OOM"""
4769     ssid = "test-wps"
4770     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4771     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4772     pin = dev[0].wps_read_pin()
4773     hapd.request("WPS_PIN any " + pin)
4774     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4775     with alloc_fail(dev[0], 1, "wps_build_assoc_req_ie"):
4776         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4777         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4778         if ev is None:
4779             raise Exception("Association not seen")
4780     dev[0].request("WPS_CANCEL")
4781
4782 def test_ap_wps_assoc_resp_ie_oom(dev, apdev):
4783     """WPS AssocResp IE OOM"""
4784     ssid = "test-wps"
4785     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2" }
4786     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4787     pin = dev[0].wps_read_pin()
4788     hapd.request("WPS_PIN any " + pin)
4789     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4790     with alloc_fail(hapd, 1, "wps_build_assoc_resp_ie"):
4791         dev[0].request("WPS_PIN %s %s" % (apdev[0]['bssid'], pin))
4792         ev = hapd.wait_event(["AP-STA-CONNECTED"], timeout=10)
4793         if ev is None:
4794             raise Exception("Association not seen")
4795     dev[0].request("WPS_CANCEL")
4796
4797 def test_ap_wps_bss_info_errors(dev, apdev):
4798     """WPS BSS info errors"""
4799     params = { "ssid": "1",
4800                "vendor_elements": "dd0e0050f20410440001ff101100010a" }
4801     hostapd.add_ap(apdev[0]['ifname'], params)
4802     params = { 'ssid': "2", "vendor_elements": "dd050050f20410" }
4803     hostapd.add_ap(apdev[1]['ifname'], params)
4804     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4805     dev[0].scan_for_bss(apdev[1]['bssid'], freq="2412")
4806     bss = dev[0].get_bss(apdev[0]['bssid'])
4807     logger.info("BSS: " + str(bss))
4808     if "wps_state" in bss:
4809         raise Exception("Unexpected wps_state in BSS info")
4810     if 'wps_device_name' not in bss:
4811         raise Exception("No wps_device_name in BSS info")
4812     if bss['wps_device_name'] != '_':
4813         raise Exception("Unexpected wps_device_name value")
4814     bss = dev[0].get_bss(apdev[1]['bssid'])
4815     logger.info("BSS: " + str(bss))
4816
4817     with alloc_fail(dev[0], 1, "=wps_attr_text"):
4818         bss = dev[0].get_bss(apdev[0]['bssid'])
4819         logger.info("BSS(OOM): " + str(bss))
4820
4821 def wps_run_pbc_fail_ap(apdev, dev, hapd):
4822     hapd.request("WPS_PBC")
4823     dev.scan_for_bss(apdev['bssid'], freq="2412")
4824     dev.request("WPS_PBC " + apdev['bssid'])
4825     ev = dev.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4826     if ev is None:
4827         raise Exception("No EAP failure reported")
4828     dev.request("WPS_CANCEL")
4829     dev.wait_disconnected()
4830     for i in range(5):
4831         try:
4832             dev.flush_scan_cache()
4833             break
4834         except Exception, e:
4835             if str(e).startswith("Failed to trigger scan"):
4836                 # Try again
4837                 time.sleep(1)
4838             else:
4839                 raise
4840
4841 def wps_run_pbc_fail(apdev, dev):
4842     hapd = wps_start_ap(apdev)
4843     wps_run_pbc_fail_ap(apdev, dev, hapd)
4844
4845 def test_ap_wps_pk_oom(dev, apdev):
4846     """WPS and public key OOM"""
4847     with alloc_fail(dev[0], 1, "wps_build_public_key"):
4848         wps_run_pbc_fail(apdev[0], dev[0])
4849
4850 def test_ap_wps_pk_oom_ap(dev, apdev):
4851     """WPS and public key OOM on AP"""
4852     hapd = wps_start_ap(apdev[0])
4853     with alloc_fail(hapd, 1, "wps_build_public_key"):
4854         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4855
4856 def test_ap_wps_encr_oom_ap(dev, apdev):
4857     """WPS and encrypted settings decryption OOM on AP"""
4858     hapd = wps_start_ap(apdev[0])
4859     pin = dev[0].wps_read_pin()
4860     hapd.request("WPS_PIN any " + pin)
4861     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4862     with alloc_fail(hapd, 1, "wps_decrypt_encr_settings"):
4863         dev[0].request("WPS_PIN " + apdev[0]['bssid'] + " " + pin)
4864         ev = hapd.wait_event(["WPS-FAIL"], timeout=10)
4865         if ev is None:
4866             raise Exception("No WPS-FAIL reported")
4867         dev[0].request("WPS_CANCEL")
4868     dev[0].wait_disconnected()
4869
4870 def test_ap_wps_encr_no_random_ap(dev, apdev):
4871     """WPS and no random data available for encryption on AP"""
4872     hapd = wps_start_ap(apdev[0])
4873     with fail_test(hapd, 1, "os_get_random;wps_build_encr_settings"):
4874         wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4875
4876 def test_ap_wps_e_hash_no_random_sta(dev, apdev):
4877     """WPS and no random data available for e-hash on STA"""
4878     with fail_test(dev[0], 1, "os_get_random;wps_build_e_hash"):
4879         wps_run_pbc_fail(apdev[0], dev[0])
4880
4881 def test_ap_wps_m1_no_random(dev, apdev):
4882     """WPS and no random for M1 on STA"""
4883     with fail_test(dev[0], 1, "os_get_random;wps_build_m1"):
4884         wps_run_pbc_fail(apdev[0], dev[0])
4885
4886 def test_ap_wps_m1_oom(dev, apdev):
4887     """WPS and OOM for M1 on STA"""
4888     with alloc_fail(dev[0], 1, "wps_build_m1"):
4889         wps_run_pbc_fail(apdev[0], dev[0])
4890
4891 def test_ap_wps_m3_oom(dev, apdev):
4892     """WPS and OOM for M3 on STA"""
4893     with alloc_fail(dev[0], 1, "wps_build_m3"):
4894         wps_run_pbc_fail(apdev[0], dev[0])
4895
4896 def test_ap_wps_m5_oom(dev, apdev):
4897     """WPS and OOM for M5 on STA"""
4898     hapd = wps_start_ap(apdev[0])
4899     hapd.request("WPS_PBC")
4900     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4901     for i in range(1, 3):
4902         with alloc_fail(dev[0], i, "wps_build_m5"):
4903             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4904             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4905             if ev is None:
4906                 raise Exception("No EAP failure reported")
4907             dev[0].request("WPS_CANCEL")
4908             dev[0].wait_disconnected()
4909     dev[0].flush_scan_cache()
4910
4911 def test_ap_wps_m5_no_random(dev, apdev):
4912     """WPS and no random for M5 on STA"""
4913     with fail_test(dev[0], 1,
4914                    "os_get_random;wps_build_encr_settings;wps_build_m5"):
4915         wps_run_pbc_fail(apdev[0], dev[0])
4916
4917 def test_ap_wps_m7_oom(dev, apdev):
4918     """WPS and OOM for M7 on STA"""
4919     hapd = wps_start_ap(apdev[0])
4920     hapd.request("WPS_PBC")
4921     dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4922     for i in range(1, 3):
4923         with alloc_fail(dev[0], i, "wps_build_m7"):
4924             dev[0].request("WPS_PBC " + apdev[0]['bssid'])
4925             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4926             if ev is None:
4927                 raise Exception("No EAP failure reported")
4928             dev[0].request("WPS_CANCEL")
4929             dev[0].wait_disconnected()
4930     dev[0].flush_scan_cache()
4931
4932 def test_ap_wps_m7_no_random(dev, apdev):
4933     """WPS and no random for M7 on STA"""
4934     with fail_test(dev[0], 1,
4935                    "os_get_random;wps_build_encr_settings;wps_build_m7"):
4936         wps_run_pbc_fail(apdev[0], dev[0])
4937
4938 def test_ap_wps_wsc_done_oom(dev, apdev):
4939     """WPS and OOM for WSC_Done on STA"""
4940     with alloc_fail(dev[0], 1, "wps_build_wsc_done"):
4941         wps_run_pbc_fail(apdev[0], dev[0])
4942
4943 def test_ap_wps_random_psk_fail(dev, apdev):
4944     """WPS and no random for PSK on AP"""
4945     ssid = "test-wps"
4946     pskfile = "/tmp/ap_wps_per_enrollee_psk.psk_file"
4947     appin = "12345670"
4948     try:
4949         os.remove(pskfile)
4950     except:
4951         pass
4952
4953     try:
4954         with open(pskfile, "w") as f:
4955             f.write("# WPA PSKs\n")
4956
4957         params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
4958                    "wpa": "2", "wpa_key_mgmt": "WPA-PSK",
4959                    "rsn_pairwise": "CCMP", "ap_pin": appin,
4960                    "wpa_psk_file": pskfile }
4961         hapd = hostapd.add_ap(apdev[0]['ifname'], params)
4962
4963         dev[0].scan_for_bss(apdev[0]['bssid'], freq="2412")
4964         with fail_test(hapd, 1, "os_get_random;wps_build_cred_network_key"):
4965             dev[0].request("WPS_REG " + apdev[0]['bssid'] + " " + appin)
4966             ev = dev[0].wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=10)
4967             if ev is None:
4968                 raise Exception("No EAP failure reported")
4969             dev[0].request("WPS_CANCEL")
4970         dev[0].wait_disconnected()
4971
4972         with fail_test(hapd, 1, "os_get_random;wps_build_cred"):
4973             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4974
4975         with alloc_fail(hapd, 1, "wps_build_cred"):
4976             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4977
4978         with alloc_fail(hapd, 2, "wps_build_cred"):
4979             wps_run_pbc_fail_ap(apdev[0], dev[0], hapd)
4980     finally:
4981         os.remove(pskfile)
4982
4983 def wps_ext_eap_identity_req(dev, hapd, bssid):
4984     logger.debug("EAP-Identity/Request")
4985     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
4986     if ev is None:
4987         raise Exception("Timeout on EAPOL-TX from hostapd")
4988     res = dev.request("EAPOL_RX " + bssid + " " + ev.split(' ')[2])
4989     if "OK" not in res:
4990         raise Exception("EAPOL_RX to wpa_supplicant failed")
4991
4992 def wps_ext_eap_identity_resp(hapd, dev, addr):
4993     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
4994     if ev is None:
4995         raise Exception("Timeout on EAPOL-TX from wpa_supplicant")
4996     res = hapd.request("EAPOL_RX " + addr + " " + ev.split(' ')[2])
4997     if "OK" not in res:
4998         raise Exception("EAPOL_RX to hostapd failed")
4999
5000 def wps_ext_eap_wsc(dst, src, src_addr, msg):
5001     logger.debug(msg)
5002     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5003     if ev is None:
5004         raise Exception("Timeout on EAPOL-TX")
5005     res = dst.request("EAPOL_RX " + src_addr + " " + ev.split(' ')[2])
5006     if "OK" not in res:
5007         raise Exception("EAPOL_RX failed")
5008
5009 def wps_start_ext(apdev, dev, pbc=False, pin=None):
5010     addr = dev.own_addr()
5011     bssid = apdev['bssid']
5012     ssid = "test-wps-conf"
5013     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5014                "wpa_passphrase": "12345678", "wpa": "2",
5015                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP"}
5016     hapd = hostapd.add_ap(apdev['ifname'], params)
5017
5018     if pbc:
5019         hapd.request("WPS_PBC")
5020     else:
5021         if pin is None:
5022             pin = dev.wps_read_pin()
5023         hapd.request("WPS_PIN any " + pin)
5024     dev.scan_for_bss(bssid, freq="2412")
5025     hapd.request("SET ext_eapol_frame_io 1")
5026     dev.request("SET ext_eapol_frame_io 1")
5027
5028     if pbc:
5029         dev.request("WPS_PBC " + bssid)
5030     else:
5031         dev.request("WPS_PIN " + bssid + " " + pin)
5032     return addr,bssid,hapd
5033
5034 def wps_auth_corrupt(dst, src, addr):
5035     ev = src.wait_event(["EAPOL-TX"], timeout=10)
5036     if ev is None:
5037         raise Exception("Timeout on EAPOL-TX")
5038     src.request("SET ext_eapol_frame_io 0")
5039     dst.request("SET ext_eapol_frame_io 0")
5040     msg = ev.split(' ')[2]
5041     if msg[-24:-16] != '10050008':
5042         raise Exception("Could not find Authenticator attribute")
5043     # Corrupt Authenticator value
5044     msg = msg[:-1] + '%x' % ((int(msg[-1], 16) + 1) % 16)
5045     res = dst.request("EAPOL_RX " + addr + " " + msg)
5046     if "OK" not in res:
5047         raise Exception("EAPOL_RX failed")
5048
5049 def wps_fail_finish(hapd, dev, fail_str):
5050     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5051     if ev is None:
5052         raise Exception("WPS-FAIL not indicated")
5053     if fail_str not in ev:
5054         raise Exception("Unexpected WPS-FAIL value: " + ev)
5055     dev.request("WPS_CANCEL")
5056     dev.wait_disconnected()
5057
5058 def wps_auth_corrupt_from_ap(dev, hapd, bssid, fail_str):
5059     wps_auth_corrupt(dev, hapd, bssid)
5060     wps_fail_finish(hapd, dev, fail_str)
5061
5062 def wps_auth_corrupt_to_ap(dev, hapd, addr, fail_str):
5063     wps_auth_corrupt(hapd, dev, addr)
5064     wps_fail_finish(hapd, dev, fail_str)
5065
5066 def test_ap_wps_authenticator_mismatch_m2(dev, apdev):
5067     """WPS and Authenticator attribute mismatch in M2"""
5068     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5069     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5070     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5071     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5072     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5073     logger.debug("M2")
5074     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=5")
5075
5076 def test_ap_wps_authenticator_mismatch_m3(dev, apdev):
5077     """WPS and Authenticator attribute mismatch in M3"""
5078     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5079     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5080     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5081     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5082     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5083     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5084     logger.debug("M3")
5085     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=7")
5086
5087 def test_ap_wps_authenticator_mismatch_m4(dev, apdev):
5088     """WPS and Authenticator attribute mismatch in M4"""
5089     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5090     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5091     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5092     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5093     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5094     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5095     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5096     logger.debug("M4")
5097     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=8")
5098
5099 def test_ap_wps_authenticator_mismatch_m5(dev, apdev):
5100     """WPS and Authenticator attribute mismatch in M5"""
5101     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5102     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5103     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5104     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5105     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5106     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5107     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5108     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5109     logger.debug("M5")
5110     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=9")
5111
5112 def test_ap_wps_authenticator_mismatch_m6(dev, apdev):
5113     """WPS and Authenticator attribute mismatch in M6"""
5114     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5115     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5116     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5117     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5118     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5119     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5120     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5121     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5122     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5123     logger.debug("M6")
5124     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=10")
5125
5126 def test_ap_wps_authenticator_mismatch_m7(dev, apdev):
5127     """WPS and Authenticator attribute mismatch in M7"""
5128     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5129     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5130     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5131     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5132     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5133     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5134     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5135     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5136     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5137     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5138     logger.debug("M7")
5139     wps_auth_corrupt_to_ap(dev[0], hapd, addr, "msg=11")
5140
5141 def test_ap_wps_authenticator_mismatch_m8(dev, apdev):
5142     """WPS and Authenticator attribute mismatch in M8"""
5143     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5144     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5145     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5146     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5147     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5148     wps_ext_eap_wsc(dev[0], hapd, bssid, "M2")
5149     wps_ext_eap_wsc(hapd, dev[0], addr, "M3")
5150     wps_ext_eap_wsc(dev[0], hapd, bssid, "M4")
5151     wps_ext_eap_wsc(hapd, dev[0], addr, "M5")
5152     wps_ext_eap_wsc(dev[0], hapd, bssid, "M6")
5153     wps_ext_eap_wsc(hapd, dev[0], addr, "M7")
5154     logger.debug("M8")
5155     wps_auth_corrupt_from_ap(dev[0], hapd, bssid, "msg=12")
5156
5157 def test_ap_wps_authenticator_missing_m2(dev, apdev):
5158     """WPS and Authenticator attribute missing from M2"""
5159     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5160     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5161     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5162     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5163     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5164     logger.debug("M2")
5165     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5166     if ev is None:
5167         raise Exception("Timeout on EAPOL-TX")
5168     hapd.request("SET ext_eapol_frame_io 0")
5169     dev[0].request("SET ext_eapol_frame_io 0")
5170     msg = ev.split(' ')[2]
5171     if msg[-24:-16] != '10050008':
5172         raise Exception("Could not find Authenticator attribute")
5173     # Remove Authenticator value
5174     msg = msg[:-24]
5175     mlen = "%04x" % (int(msg[4:8], 16) - 12)
5176     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:]
5177     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5178     if "OK" not in res:
5179         raise Exception("EAPOL_RX failed")
5180     wps_fail_finish(hapd, dev[0], "msg=5")
5181
5182 def test_ap_wps_m2_dev_passwd_id_p2p(dev, apdev):
5183     """WPS and M2 with different Device Password ID (P2P)"""
5184     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5185     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5186     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5187     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5188     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5189     logger.debug("M2")
5190     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5191     if ev is None:
5192         raise Exception("Timeout on EAPOL-TX")
5193     hapd.request("SET ext_eapol_frame_io 0")
5194     dev[0].request("SET ext_eapol_frame_io 0")
5195     msg = ev.split(' ')[2]
5196     if msg[722:730] != '10120002':
5197         raise Exception("Could not find Device Password ID attribute")
5198     # Replace Device Password ID value. This will fail Authenticator check, but
5199     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5200     # log.
5201     msg = msg[0:730] + "0005" + msg[734:]
5202     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5203     if "OK" not in res:
5204         raise Exception("EAPOL_RX failed")
5205     wps_fail_finish(hapd, dev[0], "msg=5")
5206
5207 def test_ap_wps_m2_dev_passwd_id_change_pin_to_pbc(dev, apdev):
5208     """WPS and M2 with different Device Password ID (PIN to PBC)"""
5209     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5210     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5211     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5212     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5213     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5214     logger.debug("M2")
5215     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5216     if ev is None:
5217         raise Exception("Timeout on EAPOL-TX")
5218     hapd.request("SET ext_eapol_frame_io 0")
5219     dev[0].request("SET ext_eapol_frame_io 0")
5220     msg = ev.split(' ')[2]
5221     if msg[722:730] != '10120002':
5222         raise Exception("Could not find Device Password ID attribute")
5223     # Replace Device Password ID value (PIN --> PBC). This will be rejected.
5224     msg = msg[0:730] + "0004" + msg[734:]
5225     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5226     if "OK" not in res:
5227         raise Exception("EAPOL_RX failed")
5228     wps_fail_finish(hapd, dev[0], "msg=5")
5229
5230 def test_ap_wps_m2_dev_passwd_id_change_pbc_to_pin(dev, apdev):
5231     """WPS and M2 with different Device Password ID (PBC to PIN)"""
5232     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5233     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5234     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5235     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5236     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5237     logger.debug("M2")
5238     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5239     if ev is None:
5240         raise Exception("Timeout on EAPOL-TX")
5241     hapd.request("SET ext_eapol_frame_io 0")
5242     dev[0].request("SET ext_eapol_frame_io 0")
5243     msg = ev.split(' ')[2]
5244     if msg[722:730] != '10120002':
5245         raise Exception("Could not find Device Password ID attribute")
5246     # Replace Device Password ID value. This will fail Authenticator check, but
5247     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5248     # log.
5249     msg = msg[0:730] + "0000" + msg[734:]
5250     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5251     if "OK" not in res:
5252         raise Exception("EAPOL_RX failed")
5253     wps_fail_finish(hapd, dev[0], "msg=5")
5254     dev[0].flush_scan_cache()
5255
5256 def test_ap_wps_m2_missing_dev_passwd_id(dev, apdev):
5257     """WPS and M2 without Device Password ID"""
5258     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0])
5259     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5260     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5261     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5262     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5263     logger.debug("M2")
5264     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5265     if ev is None:
5266         raise Exception("Timeout on EAPOL-TX")
5267     hapd.request("SET ext_eapol_frame_io 0")
5268     dev[0].request("SET ext_eapol_frame_io 0")
5269     msg = ev.split(' ')[2]
5270     if msg[722:730] != '10120002':
5271         raise Exception("Could not find Device Password ID attribute")
5272     # Remove Device Password ID value. This will fail Authenticator check, but
5273     # allows the code path in wps_process_dev_pw_id() to be checked from debug
5274     # log.
5275     mlen = "%04x" % (int(msg[4:8], 16) - 6)
5276     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:722] + msg[734:]
5277     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5278     if "OK" not in res:
5279         raise Exception("EAPOL_RX failed")
5280     wps_fail_finish(hapd, dev[0], "msg=5")
5281
5282 def test_ap_wps_m2_missing_registrar_nonce(dev, apdev):
5283     """WPS and M2 without Registrar Nonce"""
5284     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5285     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5286     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5287     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5288     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5289     logger.debug("M2")
5290     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5291     if ev is None:
5292         raise Exception("Timeout on EAPOL-TX")
5293     hapd.request("SET ext_eapol_frame_io 0")
5294     dev[0].request("SET ext_eapol_frame_io 0")
5295     msg = ev.split(' ')[2]
5296     if msg[96:104] != '10390010':
5297         raise Exception("Could not find Registrar Nonce attribute")
5298     # Remove Registrar Nonce. This will fail Authenticator check, but
5299     # allows the code path in wps_process_registrar_nonce() to be checked from
5300     # the debug log.
5301     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5302     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:96] + msg[136:]
5303     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5304     if "OK" not in res:
5305         raise Exception("EAPOL_RX failed")
5306     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5307     if ev is None:
5308         raise Exception("Disconnect event not seen")
5309     dev[0].request("WPS_CANCEL")
5310     dev[0].flush_scan_cache()
5311
5312 def test_ap_wps_m2_missing_enrollee_nonce(dev, apdev):
5313     """WPS and M2 without Enrollee Nonce"""
5314     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5315     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5316     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5317     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5318     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5319     logger.debug("M2")
5320     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5321     if ev is None:
5322         raise Exception("Timeout on EAPOL-TX")
5323     hapd.request("SET ext_eapol_frame_io 0")
5324     dev[0].request("SET ext_eapol_frame_io 0")
5325     msg = ev.split(' ')[2]
5326     if msg[56:64] != '101a0010':
5327         raise Exception("Could not find enrollee Nonce attribute")
5328     # Remove Enrollee Nonce. This will fail Authenticator check, but
5329     # allows the code path in wps_process_enrollee_nonce() to be checked from
5330     # the debug log.
5331     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5332     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:56] + msg[96:]
5333     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5334     if "OK" not in res:
5335         raise Exception("EAPOL_RX failed")
5336     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5337     if ev is None:
5338         raise Exception("Disconnect event not seen")
5339     dev[0].request("WPS_CANCEL")
5340     dev[0].flush_scan_cache()
5341
5342 def test_ap_wps_m2_missing_uuid_r(dev, apdev):
5343     """WPS and M2 without UUID-R"""
5344     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5345     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5346     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5347     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5348     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5349     logger.debug("M2")
5350     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5351     if ev is None:
5352         raise Exception("Timeout on EAPOL-TX")
5353     hapd.request("SET ext_eapol_frame_io 0")
5354     dev[0].request("SET ext_eapol_frame_io 0")
5355     msg = ev.split(' ')[2]
5356     if msg[136:144] != '10480010':
5357         raise Exception("Could not find enrollee Nonce attribute")
5358     # Remove UUID-R. This will fail Authenticator check, but allows the code
5359     # path in wps_process_uuid_r() to be checked from the debug log.
5360     mlen = "%04x" % (int(msg[4:8], 16) - 20)
5361     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:136] + msg[176:]
5362     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5363     if "OK" not in res:
5364         raise Exception("EAPOL_RX failed")
5365     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5366     if ev is None:
5367         raise Exception("Disconnect event not seen")
5368     dev[0].request("WPS_CANCEL")
5369     dev[0].flush_scan_cache()
5370
5371 def test_ap_wps_m2_invalid(dev, apdev):
5372     """WPS and M2 parsing failure"""
5373     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5374     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5375     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5376     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5377     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5378     logger.debug("M2")
5379     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5380     if ev is None:
5381         raise Exception("Timeout on EAPOL-TX")
5382     hapd.request("SET ext_eapol_frame_io 0")
5383     dev[0].request("SET ext_eapol_frame_io 0")
5384     msg = ev.split(' ')[2]
5385     if msg[136:144] != '10480010':
5386         raise Exception("Could not find enrollee Nonce attribute")
5387     # Remove UUID-R. This will fail Authenticator check, but allows the code
5388     # path in wps_process_uuid_r() to be checked from the debug log.
5389     mlen = "%04x" % (int(msg[4:8], 16) - 1)
5390     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:-2]
5391     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5392     if "OK" not in res:
5393         raise Exception("EAPOL_RX failed")
5394     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5395     if ev is None:
5396         raise Exception("Disconnect event not seen")
5397     dev[0].request("WPS_CANCEL")
5398     dev[0].flush_scan_cache()
5399
5400 def test_ap_wps_m2_missing_msg_type(dev, apdev):
5401     """WPS and M2 without Message Type"""
5402     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5403     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5404     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5405     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5406     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5407     logger.debug("M2")
5408     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5409     if ev is None:
5410         raise Exception("Timeout on EAPOL-TX")
5411     hapd.request("SET ext_eapol_frame_io 0")
5412     dev[0].request("SET ext_eapol_frame_io 0")
5413     msg = ev.split(' ')[2]
5414     if msg[46:54] != '10220001':
5415         raise Exception("Could not find Message Type attribute")
5416     # Remove Message Type. This will fail Authenticator check, but allows the
5417     # code path in wps_process_wsc_msg() to be checked from the debug log.
5418     mlen = "%04x" % (int(msg[4:8], 16) - 5)
5419     msg = msg[0:4] + mlen + msg[8:12] + mlen + msg[16:46] + msg[56:]
5420     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5421     if "OK" not in res:
5422         raise Exception("EAPOL_RX failed")
5423     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5424     if ev is None:
5425         raise Exception("Disconnect event not seen")
5426     dev[0].request("WPS_CANCEL")
5427     dev[0].flush_scan_cache()
5428
5429 def test_ap_wps_m2_unknown_msg_type(dev, apdev):
5430     """WPS and M2 but unknown Message Type"""
5431     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5432     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5433     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5434     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5435     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5436     logger.debug("M2")
5437     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5438     if ev is None:
5439         raise Exception("Timeout on EAPOL-TX")
5440     hapd.request("SET ext_eapol_frame_io 0")
5441     dev[0].request("SET ext_eapol_frame_io 0")
5442     msg = ev.split(' ')[2]
5443     if msg[46:54] != '10220001':
5444         raise Exception("Could not find Message Type attribute")
5445     # Replace Message Type value. This will be rejected.
5446     msg = msg[0:54] + "00" + msg[56:]
5447     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5448     if "OK" not in res:
5449         raise Exception("EAPOL_RX failed")
5450     ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECT"], timeout=5)
5451     if ev is None:
5452         raise Exception("Disconnect event not seen")
5453     dev[0].request("WPS_CANCEL")
5454     dev[0].flush_scan_cache()
5455
5456 def test_ap_wps_m2_unknown_opcode(dev, apdev):
5457     """WPS and M2 but unknown opcode"""
5458     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5459     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5460     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5461     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5462     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5463     logger.debug("M2")
5464     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5465     if ev is None:
5466         raise Exception("Timeout on EAPOL-TX")
5467     hapd.request("SET ext_eapol_frame_io 0")
5468     dev[0].request("SET ext_eapol_frame_io 0")
5469     msg = ev.split(' ')[2]
5470     # Replace opcode. This will be discarded in EAP-WSC processing.
5471     msg = msg[0:32] + "00" + msg[34:]
5472     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5473     if "OK" not in res:
5474         raise Exception("EAPOL_RX failed")
5475     dev[0].request("WPS_CANCEL")
5476     dev[0].wait_disconnected()
5477     dev[0].flush_scan_cache()
5478
5479 def test_ap_wps_m2_unknown_opcode2(dev, apdev):
5480     """WPS and M2 but unknown opcode (WSC_Start)"""
5481     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5482     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5483     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5484     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5485     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5486     logger.debug("M2")
5487     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5488     if ev is None:
5489         raise Exception("Timeout on EAPOL-TX")
5490     hapd.request("SET ext_eapol_frame_io 0")
5491     dev[0].request("SET ext_eapol_frame_io 0")
5492     msg = ev.split(' ')[2]
5493     # Replace opcode. This will be discarded in EAP-WSC processing.
5494     msg = msg[0:32] + "01" + msg[34:]
5495     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5496     if "OK" not in res:
5497         raise Exception("EAPOL_RX failed")
5498     dev[0].request("WPS_CANCEL")
5499     dev[0].wait_disconnected()
5500     dev[0].flush_scan_cache()
5501
5502 def test_ap_wps_m2_unknown_opcode3(dev, apdev):
5503     """WPS and M2 but unknown opcode (WSC_Done)"""
5504     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
5505     wps_ext_eap_identity_req(dev[0], hapd, bssid)
5506     wps_ext_eap_identity_resp(hapd, dev[0], addr)
5507     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
5508     wps_ext_eap_wsc(hapd, dev[0], addr, "M1")
5509     logger.debug("M2")
5510     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5511     if ev is None:
5512         raise Exception("Timeout on EAPOL-TX")
5513     hapd.request("SET ext_eapol_frame_io 0")
5514     dev[0].request("SET ext_eapol_frame_io 0")
5515     msg = ev.split(' ')[2]
5516     # Replace opcode. This will be discarded in WPS Enrollee processing.
5517     msg = msg[0:32] + "05" + msg[34:]
5518     res = dev[0].request("EAPOL_RX " + bssid + " " + msg)
5519     if "OK" not in res:
5520         raise Exception("EAPOL_RX failed")
5521     dev[0].request("WPS_CANCEL")
5522     dev[0].wait_disconnected()
5523     dev[0].flush_scan_cache()
5524
5525 def wps_m2_but_other(dev, apdev, title, msgtype):
5526     addr,bssid,hapd = wps_start_ext(apdev, dev)
5527     wps_ext_eap_identity_req(dev, hapd, bssid)
5528     wps_ext_eap_identity_resp(hapd, dev, addr)
5529     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5530     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5531     logger.debug(title)
5532     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5533     if ev is None:
5534         raise Exception("Timeout on EAPOL-TX")
5535     hapd.request("SET ext_eapol_frame_io 0")
5536     dev.request("SET ext_eapol_frame_io 0")
5537     msg = ev.split(' ')[2]
5538     if msg[46:54] != '10220001':
5539         raise Exception("Could not find Message Type attribute")
5540     # Replace Message Type value. This will be rejected.
5541     msg = msg[0:54] + msgtype + msg[56:]
5542     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5543     if "OK" not in res:
5544         raise Exception("EAPOL_RX failed")
5545     ev = dev.wait_event(["WPS-FAIL"], timeout=5)
5546     if ev is None:
5547         raise Exception("WPS-FAIL event not seen")
5548     dev.request("WPS_CANCEL")
5549     dev.wait_disconnected()
5550
5551 def wps_m4_but_other(dev, apdev, title, msgtype):
5552     addr,bssid,hapd = wps_start_ext(apdev, dev)
5553     wps_ext_eap_identity_req(dev, hapd, bssid)
5554     wps_ext_eap_identity_resp(hapd, dev, addr)
5555     wps_ext_eap_wsc(dev, hapd, bssid, "EAP-WSC/Start")
5556     wps_ext_eap_wsc(hapd, dev, addr, "M1")
5557     wps_ext_eap_wsc(dev, hapd, bssid, "M2")
5558     wps_ext_eap_wsc(hapd, dev, addr, "M3")
5559     logger.debug(title)
5560     ev = hapd.wait_event(["EAPOL-TX"], timeout=10)
5561     if ev is None:
5562         raise Exception("Timeout on EAPOL-TX")
5563     hapd.request("SET ext_eapol_frame_io 0")
5564     dev.request("SET ext_eapol_frame_io 0")
5565     msg = ev.split(' ')[2]
5566     if msg[46:54] != '10220001':
5567         raise Exception("Could not find Message Type attribute")
5568     # Replace Message Type value. This will be rejected.
5569     msg = msg[0:54] + msgtype + msg[56:]
5570     res = dev.request("EAPOL_RX " + bssid + " " + msg)
5571     if "OK" not in res:
5572         raise Exception("EAPOL_RX failed")
5573     ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
5574     if ev is None:
5575         raise Exception("WPS-FAIL event not seen")
5576     dev.request("WPS_CANCEL")
5577     dev.wait_disconnected()
5578
5579 def test_ap_wps_m2_msg_type_m4(dev, apdev):
5580     """WPS and M2 but Message Type M4"""
5581     wps_m2_but_other(dev[0], apdev[0], "M2/M4", "08")
5582
5583 def test_ap_wps_m2_msg_type_m6(dev, apdev):
5584     """WPS and M2 but Message Type M6"""
5585     wps_m2_but_other(dev[0], apdev[0], "M2/M6", "0a")
5586
5587 def test_ap_wps_m2_msg_type_m8(dev, apdev):
5588     """WPS and M2 but Message Type M8"""
5589     wps_m2_but_other(dev[0], apdev[0], "M2/M8", "0c")
5590
5591 def test_ap_wps_m4_msg_type_m2(dev, apdev):
5592     """WPS and M4 but Message Type M2"""
5593     wps_m4_but_other(dev[0], apdev[0], "M4/M2", "05")
5594
5595 def test_ap_wps_m4_msg_type_m2d(dev, apdev):
5596     """WPS and M4 but Message Type M2D"""
5597     wps_m4_but_other(dev[0], apdev[0], "M4/M2D", "06")
5598
5599 def test_ap_wps_config_methods(dev, apdev):
5600     """WPS configuration method parsing"""
5601     ssid = "test-wps-conf"
5602     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5603                "wpa_passphrase": "12345678", "wpa": "2",
5604                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5605                "config_methods": "ethernet display ext_nfc_token int_nfc_token physical_display physical_push_button" }
5606     hapd = hostapd.add_ap(apdev[0]['ifname'], params)
5607     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
5608                "wpa_passphrase": "12345678", "wpa": "2",
5609                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
5610                "config_methods": "display push_button" }
5611     hapd2 = hostapd.add_ap(apdev[1]['ifname'], params)
5612
5613 def test_ap_wps_set_selected_registrar_proto(dev, apdev):
5614     """WPS UPnP SetSelectedRegistrar protocol testing"""
5615     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5616     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5617
5618     location = ssdp_get_location(ap_uuid)
5619     urls = upnp_get_urls(location)
5620     eventurl = urlparse.urlparse(urls['event_sub_url'])
5621     ctrlurl = urlparse.urlparse(urls['control_url'])
5622     url = urlparse.urlparse(location)
5623     conn = httplib.HTTPConnection(url.netloc)
5624
5625     class WPSERHTTPServer(SocketServer.StreamRequestHandler):
5626         def handle(self):
5627             data = self.rfile.readline().strip()
5628             logger.debug(data)
5629             self.wfile.write(gen_wps_event())
5630
5631     server = MyTCPServer(("127.0.0.1", 12345), WPSERHTTPServer)
5632     server.timeout = 1
5633
5634     headers = { "callback": '<http://127.0.0.1:12345/event>',
5635                 "NT": "upnp:event",
5636                 "timeout": "Second-1234" }
5637     conn.request("SUBSCRIBE", eventurl.path, "\r\n\r\n", headers)
5638     resp = conn.getresponse()
5639     if resp.status != 200:
5640         raise Exception("Unexpected HTTP response: %d" % resp.status)
5641     sid = resp.getheader("sid")
5642     logger.debug("Subscription SID " + sid)
5643     server.handle_request()
5644
5645     tests = [ (500, "10"),
5646               (200, "104a000110" + "1041000101" + "101200020000" +
5647                "105300023148" +
5648                "1049002c00372a0001200124111111111111222222222222333333333333444444444444555555555555666666666666" +
5649                "10480010362db47ba53a519188fb5458b986b2e4"),
5650               (200, "104a000110" + "1041000100" + "101200020000" +
5651                "105300020000"),
5652               (200, "104a000110" + "1041000100"),
5653               (200, "104a000110") ]
5654     for status,test in tests:
5655         tlvs = binascii.unhexlify(test)
5656         newmsg = base64.b64encode(tlvs)
5657         msg = '<?xml version="1.0"?>\n'
5658         msg += '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
5659         msg += '<s:Body>'
5660         msg += '<u:SetSelectedRegistrar xmlns:u="urn:schemas-wifialliance-org:service:WFAWLANConfig:1">'
5661         msg += '<NewMessage>'
5662         msg += newmsg
5663         msg += "</NewMessage></u:SetSelectedRegistrar></s:Body></s:Envelope>"
5664         headers = { "Content-type": 'text/xml; charset="utf-8"' }
5665         headers["SOAPAction"] = '"urn:schemas-wifialliance-org:service:WFAWLANConfig:1#%s"' % "SetSelectedRegistrar"
5666         conn.request("POST", ctrlurl.path, msg, headers)
5667         resp = conn.getresponse()
5668         if resp.status != status:
5669             raise Exception("Unexpected HTTP response: %d (expected %d)" % (resp.status, status))
5670
5671 def test_ap_wps_adv_oom(dev, apdev):
5672     """WPS AP and advertisement OOM"""
5673     ap_uuid = "27ea801a-9e5c-4e73-bd82-f89cbcd10d7e"
5674     hapd = add_ssdp_ap(apdev[0]['ifname'], ap_uuid)
5675
5676     with alloc_fail(hapd, 1, "=msearchreply_state_machine_start"):
5677         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5678                           no_recv=True)
5679         time.sleep(0.2)
5680
5681     with alloc_fail(hapd, 1, "eloop_register_timeout;msearchreply_state_machine_start"):
5682         ssdp_send_msearch("urn:schemas-wifialliance-org:service:WFAWLANConfig:1",
5683                           no_recv=True)
5684         time.sleep(0.2)
5685
5686     with alloc_fail(hapd, 1,
5687                     "next_advertisement;advertisement_state_machine_stop"):
5688         hapd.disable()
5689
5690     with alloc_fail(hapd, 1, "ssdp_listener_start"):
5691         if "FAIL" not in hapd.request("ENABLE"):
5692             raise Exception("ENABLE succeeded during OOM")
5693
5694 def test_wps_config_methods(dev):
5695     """WPS config method update"""
5696     wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5')
5697     wpas.interface_add("wlan5")
5698     if "OK" not in wpas.request("SET config_methods display label"):
5699         raise Exception("Failed to set config_methods")
5700     if wpas.request("GET config_methods").strip() != "display label":
5701         raise Exception("config_methods were not updated")
5702     if "OK" not in wpas.request("SET config_methods "):
5703         raise Exception("Failed to clear config_methods")
5704     if wpas.request("GET config_methods").strip() != "":
5705         raise Exception("config_methods were not cleared")
5706
5707 WPS_VENDOR_ID_WFA = 14122
5708 WPS_VENDOR_TYPE = 1
5709
5710 # EAP-WSC Op-Code values
5711 WSC_Start = 0x01
5712 WSC_ACK = 0x02
5713 WSC_NACK = 0x03
5714 WSC_MSG = 0x04
5715 WSC_Done = 0x05
5716 WSC_FRAG_ACK = 0x06
5717
5718 ATTR_AP_CHANNEL = 0x1001
5719 ATTR_ASSOC_STATE = 0x1002
5720 ATTR_AUTH_TYPE = 0x1003
5721 ATTR_AUTH_TYPE_FLAGS = 0x1004
5722 ATTR_AUTHENTICATOR = 0x1005
5723 ATTR_CONFIG_METHODS = 0x1008
5724 ATTR_CONFIG_ERROR = 0x1009
5725 ATTR_CONFIRM_URL4 = 0x100a
5726 ATTR_CONFIRM_URL6 = 0x100b
5727 ATTR_CONN_TYPE = 0x100c
5728 ATTR_CONN_TYPE_FLAGS = 0x100d
5729 ATTR_CRED = 0x100e
5730 ATTR_ENCR_TYPE = 0x100f
5731 ATTR_ENCR_TYPE_FLAGS = 0x1010
5732 ATTR_DEV_NAME = 0x1011
5733 ATTR_DEV_PASSWORD_ID = 0x1012
5734 ATTR_E_HASH1 = 0x1014
5735 ATTR_E_HASH2 = 0x1015
5736 ATTR_E_SNONCE1 = 0x1016
5737 ATTR_E_SNONCE2 = 0x1017
5738 ATTR_ENCR_SETTINGS = 0x1018
5739 ATTR_ENROLLEE_NONCE = 0x101a
5740 ATTR_FEATURE_ID = 0x101b
5741 ATTR_IDENTITY = 0x101c
5742 ATTR_IDENTITY_PROOF = 0x101d
5743 ATTR_KEY_WRAP_AUTH = 0x101e
5744 ATTR_KEY_ID = 0x101f
5745 ATTR_MAC_ADDR = 0x1020
5746 ATTR_MANUFACTURER = 0x1021
5747 ATTR_MSG_TYPE = 0x1022
5748 ATTR_MODEL_NAME = 0x1023
5749 ATTR_MODEL_NUMBER = 0x1024
5750 ATTR_NETWORK_INDEX = 0x1026
5751 ATTR_NETWORK_KEY = 0x1027
5752 ATTR_NETWORK_KEY_INDEX = 0x1028
5753 ATTR_NEW_DEVICE_NAME = 0x1029
5754 ATTR_NEW_PASSWORD = 0x102a
5755 ATTR_OOB_DEVICE_PASSWORD = 0x102c
5756 ATTR_OS_VERSION = 0x102d
5757 ATTR_POWER_LEVEL = 0x102f
5758 ATTR_PSK_CURRENT = 0x1030
5759 ATTR_PSK_MAX = 0x1031
5760 ATTR_PUBLIC_KEY = 0x1032
5761 ATTR_RADIO_ENABLE = 0x1033
5762 ATTR_REBOOT = 0x1034
5763 ATTR_REGISTRAR_CURRENT = 0x1035
5764 ATTR_REGISTRAR_ESTABLISHED = 0x1036
5765 ATTR_REGISTRAR_LIST = 0x1037
5766 ATTR_REGISTRAR_MAX = 0x1038
5767 ATTR_REGISTRAR_NONCE = 0x1039
5768 ATTR_REQUEST_TYPE = 0x103a
5769 ATTR_RESPONSE_TYPE = 0x103b
5770 ATTR_RF_BANDS = 0x103c
5771 ATTR_R_HASH1 = 0x103d
5772 ATTR_R_HASH2 = 0x103e
5773 ATTR_R_SNONCE1 = 0x103f
5774 ATTR_R_SNONCE2 = 0x1040
5775 ATTR_SELECTED_REGISTRAR = 0x1041
5776 ATTR_SERIAL_NUMBER = 0x1042
5777 ATTR_WPS_STATE = 0x1044
5778 ATTR_SSID = 0x1045
5779 ATTR_TOTAL_NETWORKS = 0x1046
5780 ATTR_UUID_E = 0x1047
5781 ATTR_UUID_R = 0x1048
5782 ATTR_VENDOR_EXT = 0x1049
5783 ATTR_VERSION = 0x104a
5784 ATTR_X509_CERT_REQ = 0x104b
5785 ATTR_X509_CERT = 0x104c
5786 ATTR_EAP_IDENTITY = 0x104d
5787 ATTR_MSG_COUNTER = 0x104e
5788 ATTR_PUBKEY_HASH = 0x104f
5789 ATTR_REKEY_KEY = 0x1050
5790 ATTR_KEY_LIFETIME = 0x1051
5791 ATTR_PERMITTED_CFG_METHODS = 0x1052
5792 ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053
5793 ATTR_PRIMARY_DEV_TYPE = 0x1054
5794 ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055
5795 ATTR_PORTABLE_DEV = 0x1056
5796 ATTR_AP_SETUP_LOCKED = 0x1057
5797 ATTR_APPLICATION_EXT = 0x1058
5798 ATTR_EAP_TYPE = 0x1059
5799 ATTR_IV = 0x1060
5800 ATTR_KEY_PROVIDED_AUTO = 0x1061
5801 ATTR_802_1X_ENABLED = 0x1062
5802 ATTR_APPSESSIONKEY = 0x1063
5803 ATTR_WEPTRANSMITKEY = 0x1064
5804 ATTR_REQUESTED_DEV_TYPE = 0x106a
5805
5806 # Message Type
5807 WPS_Beacon = 0x01
5808 WPS_ProbeRequest = 0x02
5809 WPS_ProbeResponse = 0x03
5810 WPS_M1 = 0x04
5811 WPS_M2 = 0x05
5812 WPS_M2D = 0x06
5813 WPS_M3 = 0x07
5814 WPS_M4 = 0x08
5815 WPS_M5 = 0x09
5816 WPS_M6 = 0x0a
5817 WPS_M7 = 0x0b
5818 WPS_M8 = 0x0c
5819 WPS_WSC_ACK = 0x0d
5820 WPS_WSC_NACK = 0x0e
5821 WPS_WSC_DONE = 0x0f
5822
5823 def get_wsc_msg(dev):
5824     ev = dev.wait_event(["EAPOL-TX"], timeout=10)
5825     if ev is None:
5826         raise Exception("Timeout on EAPOL-TX")
5827     data = binascii.unhexlify(ev.split(' ')[2])
5828     msg = {}
5829
5830     # Parse EAPOL header
5831     if len(data) < 4:
5832         raise Exception("No room for EAPOL header")
5833     version,type,length = struct.unpack('>BBH', data[0:4])
5834     msg['eapol_version'] = version
5835     msg['eapol_type'] = type
5836     msg['eapol_length'] = length
5837     data = data[4:]
5838     if length != len(data):
5839         raise Exception("EAPOL header length mismatch (%d != %d)" % (length, len(data)))
5840     if type != 0:
5841         raise Exception("Unexpected EAPOL header type: %d" % type)
5842
5843     # Parse EAP header
5844     if len(data) < 4:
5845         raise Exception("No room for EAP header")
5846     code,identifier,length = struct.unpack('>BBH', data[0:4])
5847     msg['eap_code'] = code
5848     msg['eap_identifier'] = identifier
5849     msg['eap_length'] = length
5850     data = data[4:]
5851     if msg['eapol_length'] != msg['eap_length']:
5852         raise Exception("EAP header length mismatch (%d != %d)" % (msg['eapol_length'], length))
5853
5854     # Parse EAP expanded header
5855     if len(data) < 1:
5856         raise Exception("No EAP type included")
5857     msg['eap_type'], = struct.unpack('B', data[0])
5858     data = data[1:]
5859
5860     if msg['eap_type'] == 254:
5861         if len(data) < 3 + 4:
5862             raise Exception("Truncated EAP expanded header")
5863         msg['eap_vendor_id'], msg['eap_vendor_type'] = struct.unpack('>LL', '\0' + data[0:7])
5864         data = data[7:]
5865     else:
5866         raise Exception("Unexpected EAP type")
5867
5868     if msg['eap_vendor_id'] != WPS_VENDOR_ID_WFA:
5869         raise Exception("Unexpected Vendor-Id")
5870     if msg['eap_vendor_type'] != WPS_VENDOR_TYPE:
5871         raise Exception("Unexpected Vendor-Type")
5872
5873     # Parse EAP-WSC header
5874     if len(data) < 2:
5875         raise Exception("Truncated EAP-WSC header")
5876     msg['wsc_opcode'], msg['wsc_flags'] = struct.unpack('BB', data[0:2])
5877     data = data[2:]
5878
5879     # Parse WSC attributes
5880     msg['raw_attrs'] = data
5881     attrs = {}
5882     while len(data) > 0:
5883         if len(data) < 4:
5884             raise Exception("Truncated attribute header")
5885         attr,length = struct.unpack('>HH', data[0:4])
5886         data = data[4:]
5887         if length > len(data):
5888             raise Exception("Truncated attribute 0x%04x" % attr)
5889         attrs[attr] = data[0:length]
5890         data = data[length:]
5891     msg['wsc_attrs'] = attrs
5892
5893     if ATTR_MSG_TYPE in attrs:
5894         msg['wsc_msg_type'], = struct.unpack('B', attrs[ATTR_MSG_TYPE])
5895
5896     return msg
5897
5898 def recv_wsc_msg(dev, opcode, msg_type):
5899     msg = get_wsc_msg(dev)
5900     if msg['wsc_opcode'] != opcode or msg['wsc_msg_type'] != msg_type:
5901         raise Exception("Unexpected Op-Code/MsgType")
5902     return msg, msg['wsc_attrs'], msg['raw_attrs']
5903
5904 def build_wsc_attr(attr, payload):
5905     return struct.pack('>HH', attr, len(payload)) + payload
5906
5907 def build_attr_msg_type(msg_type):
5908     return build_wsc_attr(ATTR_MSG_TYPE, struct.pack('B', msg_type))
5909
5910 def build_eap_wsc(eap_code, eap_id, payload, opcode=WSC_MSG):
5911     length = 4 + 8 + 2 + len(payload)
5912     # EAPOL header
5913     msg = struct.pack('>BBH', 2, 0, length)
5914     # EAP header
5915     msg += struct.pack('>BBH', eap_code, eap_id, length)
5916     # EAP expanded header for EAP-WSC
5917     msg += struct.pack('B', 254)
5918     msg += struct.pack('>L', WPS_VENDOR_ID_WFA)[1:4]
5919     msg += struct.pack('>L', WPS_VENDOR_TYPE)
5920     # EAP-WSC header
5921     msg += struct.pack('BB', opcode, 0)
5922     # WSC attributes
5923     msg += payload
5924     return msg
5925
5926 def build_eap_success(eap_id):
5927     length = 4
5928     # EAPOL header
5929     msg = struct.pack('>BBH', 2, 0, length)
5930     # EAP header
5931     msg += struct.pack('>BBH', 3, eap_id, length)
5932     return msg
5933
5934 def build_eap_failure(eap_id):
5935     length = 4
5936     # EAPOL header
5937     msg = struct.pack('>BBH', 2, 0, length)
5938     # EAP header
5939     msg += struct.pack('>BBH', 4, eap_id, length)
5940     return msg
5941
5942 def send_wsc_msg(dev, src, msg):
5943     res = dev.request("EAPOL_RX " + src + " " + binascii.hexlify(msg))
5944     if "OK" not in res:
5945         raise Exception("EAPOL_RX failed")
5946
5947 group_5_prime = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF
5948 group_5_generator = 2
5949
5950 def wsc_kdf(key, label, bits):
5951     result = ''
5952     i = 1
5953     while len(result) * 8 < bits:
5954         data = struct.pack('>L', i) + label + struct.pack('>L', bits)
5955         m = hmac.new(key, data, hashlib.sha256)
5956         result += m.digest()
5957         i += 1
5958     return result[0:bits / 8]
5959
5960 def wsc_keys(kdk):
5961     keys = wsc_kdf(kdk, "Wi-Fi Easy and Secure Key Derivation", 640)
5962     authkey = keys[0:32]
5963     keywrapkey = keys[32:48]
5964     emsk = keys[48:80]
5965     return authkey,keywrapkey,emsk
5966
5967 def wsc_dev_pw_half_psk(authkey, dev_pw):
5968     m = hmac.new(authkey, dev_pw, hashlib.sha256)
5969     return m.digest()[0:16]
5970
5971 def wsc_dev_pw_psk(authkey, dev_pw):
5972     dev_pw_1 = dev_pw[0:len(dev_pw) / 2]
5973     dev_pw_2 = dev_pw[len(dev_pw) / 2:]
5974     psk1 = wsc_dev_pw_half_psk(authkey, dev_pw_1)
5975     psk2 = wsc_dev_pw_half_psk(authkey, dev_pw_2)
5976     return psk1,psk2
5977
5978 def build_attr_authenticator(authkey, prev_msg, curr_msg):
5979     m = hmac.new(authkey, prev_msg + curr_msg, hashlib.sha256)
5980     auth = m.digest()[0:8]
5981     return build_wsc_attr(ATTR_AUTHENTICATOR, auth)
5982
5983 def build_attr_encr_settings(authkey, keywrapkey, data):
5984     m = hmac.new(authkey, data, hashlib.sha256)
5985     kwa = m.digest()[0:8]
5986     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
5987     iv = 16*'\x99'
5988     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
5989     pad_len = 16 - len(data) % 16
5990     ps = pad_len * struct.pack('B', pad_len)
5991     data += ps
5992     wrapped = aes.encrypt(data)
5993     return build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
5994
5995 def decrypt_attr_encr_settings(authkey, keywrapkey, data):
5996     if len(data) < 32 or len(data) % 16 != 0:
5997         raise Exception("Unexpected Encrypted Settings length: %d" % len(data))
5998     iv = data[0:16]
5999     encr = data[16:]
6000     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6001     decrypted = aes.decrypt(encr)
6002     pad_len, = struct.unpack('B', decrypted[-1])
6003     if pad_len > len(decrypted):
6004         raise Exception("Invalid padding in Encrypted Settings")
6005     for i in range(-pad_len, -1):
6006         if decrypted[i] != decrypted[-1]:
6007             raise Exception("Invalid PS value in Encrypted Settings")
6008     
6009     decrypted = decrypted[0:len(decrypted) - pad_len]
6010     if len(decrypted) < 12:
6011         raise Exception("Truncated Encrypted Settings plaintext")
6012     kwa = decrypted[-12:]
6013     attr,length = struct.unpack(">HH", kwa[0:4])
6014     if attr != ATTR_KEY_WRAP_AUTH or length != 8:
6015         raise Exception("Invalid KWA header")
6016     kwa = kwa[4:]
6017     decrypted = decrypted[0:len(decrypted) - 12]
6018
6019     m = hmac.new(authkey, decrypted, hashlib.sha256)
6020     calc_kwa = m.digest()[0:8]
6021     if kwa != calc_kwa:
6022         raise Exception("KWA mismatch")
6023
6024     return decrypted
6025
6026 def zeropad_str(val, pad_len):
6027     while len(val) < pad_len * 2:
6028         val = '0' + val
6029     return val
6030
6031 def wsc_dh_init():
6032     # For now, use a hardcoded private key. In theory, this is supposed to be
6033     # randomly selected.
6034     own_private = 0x123456789
6035     own_public = pow(group_5_generator, own_private, group_5_prime)
6036     pk = binascii.unhexlify(zeropad_str(format(own_public, '02x'), 192))
6037     return own_private, pk
6038
6039 def wsc_dh_kdf(peer_pk, own_private, mac_addr, e_nonce, r_nonce):
6040     peer_public = long(binascii.hexlify(peer_pk), 16)
6041     if peer_public < 2 or peer_public >= group_5_prime:
6042         raise Exception("Invalid peer public key")
6043     if pow(peer_public, (group_5_prime - 1) / 2, group_5_prime) != 1:
6044         raise Exception("Unexpected Legendre symbol for peer public key")
6045
6046     shared_secret = pow(peer_public, own_private, group_5_prime)
6047     ss = zeropad_str(format(shared_secret, "02x"), 192)
6048     logger.debug("DH shared secret: " + ss)
6049
6050     dhkey = hashlib.sha256(binascii.unhexlify(ss)).digest()
6051     logger.debug("DHKey: " + binascii.hexlify(dhkey))
6052
6053     m = hmac.new(dhkey, e_nonce + mac_addr + r_nonce, hashlib.sha256)
6054     kdk = m.digest()
6055     logger.debug("KDK: " + binascii.hexlify(kdk))
6056     authkey,keywrapkey,emsk = wsc_keys(kdk)
6057     logger.debug("AuthKey: " + binascii.hexlify(authkey))
6058     logger.debug("KeyWrapKey: " + binascii.hexlify(keywrapkey))
6059     logger.debug("EMSK: " + binascii.hexlify(emsk))
6060     return authkey,keywrapkey
6061
6062 def wsc_dev_pw_hash(authkey, dev_pw, e_pk, r_pk):
6063     psk1,psk2 = wsc_dev_pw_psk(authkey, dev_pw)
6064     logger.debug("PSK1: " + binascii.hexlify(psk1))
6065     logger.debug("PSK2: " + binascii.hexlify(psk2))
6066
6067     # Note: Secret values are supposed to be random, but hardcoded values are
6068     # fine for testing.
6069     s1 = 16*'\x77'
6070     m = hmac.new(authkey, s1 + psk1 + e_pk + r_pk, hashlib.sha256)
6071     hash1 = m.digest()
6072     logger.debug("Hash1: " + binascii.hexlify(hash1))
6073
6074     s2 = 16*'\x88'
6075     m = hmac.new(authkey, s2 + psk2 + e_pk + r_pk, hashlib.sha256)
6076     hash2 = m.digest()
6077     logger.debug("Hash2: " + binascii.hexlify(hash2))
6078     return s1,s2,hash1,hash2
6079
6080 def build_m1(eap_id, uuid_e, mac_addr, e_nonce, e_pk,
6081              manufacturer='', model_name='', config_methods='\x00\x00'):
6082     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6083     attrs += build_attr_msg_type(WPS_M1)
6084     attrs += build_wsc_attr(ATTR_UUID_E, uuid_e)
6085     attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6086     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6087     attrs += build_wsc_attr(ATTR_PUBLIC_KEY, e_pk)
6088     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6089     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6090     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6091     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, config_methods)
6092     attrs += build_wsc_attr(ATTR_WPS_STATE, '\x00')
6093     attrs += build_wsc_attr(ATTR_MANUFACTURER, manufacturer)
6094     attrs += build_wsc_attr(ATTR_MODEL_NAME, model_name)
6095     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6096     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6097     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6098     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6099     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6100     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6101     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, '\x00\x00')
6102     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6103     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6104     m1 = build_eap_wsc(2, eap_id, attrs)
6105     return m1, attrs
6106
6107 def build_m2(authkey, m1, eap_id, e_nonce, r_nonce, uuid_r, r_pk,
6108              dev_pw_id='\x00\x00', eap_code=1):
6109     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6110     attrs += build_attr_msg_type(WPS_M2)
6111     if e_nonce:
6112         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6113     if r_nonce:
6114         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6115     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6116     if r_pk:
6117         attrs += build_wsc_attr(ATTR_PUBLIC_KEY, r_pk)
6118     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6119     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6120     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6121     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6122     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6123     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6124     attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6125     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6126     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6127     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6128     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6129     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6130     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6131     attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6132     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6133     attrs += build_attr_authenticator(authkey, m1, attrs)
6134     m2 = build_eap_wsc(eap_code, eap_id, attrs)
6135     return m2, attrs
6136
6137 def build_m2d(m1, eap_id, e_nonce, r_nonce, uuid_r, dev_pw_id=None, eap_code=1):
6138     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6139     attrs += build_attr_msg_type(WPS_M2D)
6140     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6141     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6142     attrs += build_wsc_attr(ATTR_UUID_R, uuid_r)
6143     attrs += build_wsc_attr(ATTR_AUTH_TYPE_FLAGS, '\x00\x00')
6144     attrs += build_wsc_attr(ATTR_ENCR_TYPE_FLAGS, '\x00\x00')
6145     attrs += build_wsc_attr(ATTR_CONN_TYPE_FLAGS, '\x00')
6146     attrs += build_wsc_attr(ATTR_CONFIG_METHODS, '\x00\x00')
6147     attrs += build_wsc_attr(ATTR_MANUFACTURER, '')
6148     attrs += build_wsc_attr(ATTR_MODEL_NAME, '')
6149     #attrs += build_wsc_attr(ATTR_MODEL_NUMBER, '')
6150     attrs += build_wsc_attr(ATTR_SERIAL_NUMBER, '')
6151     attrs += build_wsc_attr(ATTR_PRIMARY_DEV_TYPE, 8*'\x00')
6152     attrs += build_wsc_attr(ATTR_DEV_NAME, '')
6153     attrs += build_wsc_attr(ATTR_RF_BANDS, '\x00')
6154     attrs += build_wsc_attr(ATTR_ASSOC_STATE, '\x00\x00')
6155     attrs += build_wsc_attr(ATTR_CONFIG_ERROR, '\x00\x00')
6156     attrs += build_wsc_attr(ATTR_OS_VERSION, '\x00\x00\x00\x00')
6157     if dev_pw_id:
6158         attrs += build_wsc_attr(ATTR_DEV_PASSWORD_ID, dev_pw_id)
6159     m2d = build_eap_wsc(eap_code, eap_id, attrs)
6160     return m2d, attrs
6161
6162 def build_ack(eap_id, e_nonce, r_nonce, msg_type=WPS_WSC_ACK, eap_code=1):
6163     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6164     if msg_type is not None:
6165         attrs += build_attr_msg_type(msg_type)
6166     if e_nonce:
6167         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6168     if r_nonce:
6169         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6170     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_ACK)
6171     return msg, attrs
6172
6173 def build_nack(eap_id, e_nonce, r_nonce, config_error='\x00\x00',
6174                msg_type=WPS_WSC_NACK, eap_code=1):
6175     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6176     if msg_type is not None:
6177         attrs += build_attr_msg_type(msg_type)
6178     if e_nonce:
6179         attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6180     if r_nonce:
6181         attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
6182     if config_error:
6183         attrs += build_wsc_attr(ATTR_CONFIG_ERROR, config_error)
6184     msg = build_eap_wsc(eap_code, eap_id, attrs, opcode=WSC_NACK)
6185     return msg, attrs
6186
6187 def test_wps_ext(dev, apdev):
6188     """WPS against external implementation"""
6189     pin = "12345670"
6190     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6191     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6192     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6193
6194     logger.debug("Receive WSC/Start from AP")
6195     msg = get_wsc_msg(hapd)
6196     if msg['wsc_opcode'] != WSC_Start:
6197         raise Exception("Unexpected Op-Code for WSC/Start")
6198     wsc_start_id = msg['eap_identifier']
6199
6200     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6201     uuid_e = 16*'\x11'
6202     e_nonce = 16*'\x22'
6203     own_private, e_pk = wsc_dh_init()
6204
6205     logger.debug("Send M1 to AP")
6206     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
6207                                 e_nonce, e_pk)
6208     send_wsc_msg(hapd, addr, m1)
6209
6210     logger.debug("Receive M2 from AP")
6211     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
6212
6213     authkey,keywrapkey = wsc_dh_kdf(m2_attrs[ATTR_PUBLIC_KEY], own_private,
6214                                     mac_addr, e_nonce,
6215                                     m2_attrs[ATTR_REGISTRAR_NONCE])
6216     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk,
6217                                                 m2_attrs[ATTR_PUBLIC_KEY])
6218
6219     logger.debug("Send M3 to AP")
6220     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6221     attrs += build_attr_msg_type(WPS_M3)
6222     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6223                             m2_attrs[ATTR_REGISTRAR_NONCE])
6224     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
6225     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
6226     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
6227     raw_m3_attrs = attrs
6228     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6229     send_wsc_msg(hapd, addr, m3)
6230
6231     logger.debug("Receive M4 from AP")
6232     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
6233
6234     logger.debug("Send M5 to AP")
6235     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6236     attrs += build_attr_msg_type(WPS_M5)
6237     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6238                             m2_attrs[ATTR_REGISTRAR_NONCE])
6239     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
6240     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6241     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
6242     raw_m5_attrs = attrs
6243     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6244     send_wsc_msg(hapd, addr, m5)
6245
6246     logger.debug("Receive M6 from AP")
6247     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
6248
6249     logger.debug("Send M7 to AP")
6250     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6251     attrs += build_attr_msg_type(WPS_M7)
6252     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6253                             m2_attrs[ATTR_REGISTRAR_NONCE])
6254     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
6255     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6256     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
6257     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
6258     raw_m7_attrs = attrs
6259     send_wsc_msg(hapd, addr, m7)
6260
6261     logger.debug("Receive M8 from AP")
6262     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
6263     m8_cred = decrypt_attr_encr_settings(authkey, keywrapkey,
6264                                          m8_attrs[ATTR_ENCR_SETTINGS])
6265     logger.debug("M8 Credential: " + binascii.hexlify(m8_cred))
6266
6267     logger.debug("Prepare WSC_Done")
6268     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6269     attrs += build_attr_msg_type(WPS_WSC_DONE)
6270     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
6271     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE,
6272                             m2_attrs[ATTR_REGISTRAR_NONCE])
6273     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
6274     # Do not send WSC_Done yet to allow exchangw with STA complete before the
6275     # AP disconnects.
6276
6277     uuid_r = 16*'\x33'
6278     r_nonce = 16*'\x44'
6279
6280     eap_id = wsc_start_id
6281     logger.debug("Send WSC/Start to STA")
6282     wsc_start = build_eap_wsc(1, eap_id, "", opcode=WSC_Start)
6283     send_wsc_msg(dev[0], bssid, wsc_start)
6284     eap_id = (eap_id + 1) % 256
6285
6286     logger.debug("Receive M1 from STA")
6287     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6288
6289     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6290                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6291                                     r_nonce)
6292     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6293                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6294
6295     logger.debug("Send M2 to STA")
6296     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6297                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6298                                 r_nonce, uuid_r, e_pk)
6299     send_wsc_msg(dev[0], bssid, m2)
6300     eap_id = (eap_id + 1) % 256
6301
6302     logger.debug("Receive M3 from STA")
6303     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6304
6305     logger.debug("Send M4 to STA")
6306     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6307     attrs += build_attr_msg_type(WPS_M4)
6308     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6309     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6310     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6311     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6312     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6313     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6314     raw_m4_attrs = attrs
6315     m4 = build_eap_wsc(1, eap_id, attrs)
6316     send_wsc_msg(dev[0], bssid, m4)
6317     eap_id = (eap_id + 1) % 256
6318
6319     logger.debug("Receive M5 from STA")
6320     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6321
6322     logger.debug("Send M6 to STA")
6323     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6324     attrs += build_attr_msg_type(WPS_M6)
6325     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6326                             m1_attrs[ATTR_ENROLLEE_NONCE])
6327     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6328     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6329     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6330     raw_m6_attrs = attrs
6331     m6 = build_eap_wsc(1, eap_id, attrs)
6332     send_wsc_msg(dev[0], bssid, m6)
6333     eap_id = (eap_id + 1) % 256
6334
6335     logger.debug("Receive M7 from STA")
6336     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6337
6338     logger.debug("Send M8 to STA")
6339     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6340     attrs += build_attr_msg_type(WPS_M8)
6341     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6342                             m1_attrs[ATTR_ENROLLEE_NONCE])
6343     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6344     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6345     raw_m8_attrs = attrs
6346     m8 = build_eap_wsc(1, eap_id, attrs)
6347     send_wsc_msg(dev[0], bssid, m8)
6348     eap_id = (eap_id + 1) % 256
6349
6350     ev = dev[0].wait_event(["WPS-CRED-RECEIVED"], timeout=5)
6351     if ev is None:
6352         raise Exception("wpa_supplicant did not report credential")
6353
6354     logger.debug("Receive WSC_Done from STA")
6355     msg = get_wsc_msg(dev[0])
6356     if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6357         raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6358
6359     logger.debug("Send WSC_Done to AP")
6360     hapd.request("SET ext_eapol_frame_io 0")
6361     dev[0].request("SET ext_eapol_frame_io 0")
6362     send_wsc_msg(hapd, addr, wsc_done)
6363
6364     ev = hapd.wait_event(["WPS-REG-SUCCESS"], timeout=5)
6365     if ev is None:
6366         raise Exception("hostapd did not report WPS success")
6367
6368     dev[0].wait_connected()
6369
6370 def wps_start_kwa(dev, apdev):
6371     pin = "12345670"
6372     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6373     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6374     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6375     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6376
6377     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6378     uuid_r = 16*'\x33'
6379     r_nonce = 16*'\x44'
6380     own_private, e_pk = wsc_dh_init()
6381
6382     logger.debug("Receive M1 from STA")
6383     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6384     eap_id = (msg['eap_identifier'] + 1) % 256
6385
6386     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6387                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6388                                     r_nonce)
6389     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6390                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6391
6392     logger.debug("Send M2 to STA")
6393     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6394                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6395                                 r_nonce, uuid_r, e_pk)
6396     send_wsc_msg(dev[0], bssid, m2)
6397     eap_id = (eap_id + 1) % 256
6398
6399     logger.debug("Receive M3 from STA")
6400     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6401
6402     logger.debug("Send M4 to STA")
6403     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6404     attrs += build_attr_msg_type(WPS_M4)
6405     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6406     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6407     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6408
6409     return r_s1, keywrapkey, authkey, raw_m3_attrs, eap_id, bssid, attrs
6410
6411 def wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id):
6412     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6413     m4 = build_eap_wsc(1, eap_id, attrs)
6414     send_wsc_msg(dev[0], bssid, m4)
6415     eap_id = (eap_id + 1) % 256
6416
6417     logger.debug("Receive M5 from STA")
6418     msg = get_wsc_msg(dev[0])
6419     if msg['wsc_opcode'] != WSC_NACK:
6420         raise Exception("Unexpected message - expected WSC_Nack")
6421
6422     dev[0].request("WPS_CANCEL")
6423     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6424     dev[0].wait_disconnected()
6425
6426 def test_wps_ext_kwa_proto_no_kwa(dev, apdev):
6427     """WPS and KWA error: No KWA attribute"""
6428     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6429     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6430     # Encrypted Settings without KWA
6431     iv = 16*'\x99'
6432     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6433     pad_len = 16 - len(data) % 16
6434     ps = pad_len * struct.pack('B', pad_len)
6435     data += ps
6436     wrapped = aes.encrypt(data)
6437     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6438     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6439
6440 def test_wps_ext_kwa_proto_data_after_kwa(dev, apdev):
6441     """WPS and KWA error: Data after KWA"""
6442     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6443     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6444     # Encrypted Settings and data after KWA
6445     m = hmac.new(authkey, data, hashlib.sha256)
6446     kwa = m.digest()[0:8]
6447     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
6448     data += build_wsc_attr(ATTR_VENDOR_EXT, "1234567890")
6449     iv = 16*'\x99'
6450     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6451     pad_len = 16 - len(data) % 16
6452     ps = pad_len * struct.pack('B', pad_len)
6453     data += ps
6454     wrapped = aes.encrypt(data)
6455     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6456     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6457
6458 def test_wps_ext_kwa_proto_kwa_mismatch(dev, apdev):
6459     """WPS and KWA error: KWA mismatch"""
6460     r_s1,keywrapkey,authkey,raw_m3_attrs,eap_id,bssid,attrs = wps_start_kwa(dev, apdev)
6461     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6462     # Encrypted Settings and KWA with incorrect value
6463     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, 8*'\x00')
6464     iv = 16*'\x99'
6465     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
6466     pad_len = 16 - len(data) % 16
6467     ps = pad_len * struct.pack('B', pad_len)
6468     data += ps
6469     wrapped = aes.encrypt(data)
6470     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
6471     wps_stop_kwa(dev, bssid, attrs, authkey, raw_m3_attrs, eap_id)
6472
6473 def wps_run_cred_proto(dev, apdev, m8_cred, connect=False, no_connect=False):
6474     pin = "12345670"
6475     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6476     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6477     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6478     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6479
6480     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6481     uuid_r = 16*'\x33'
6482     r_nonce = 16*'\x44'
6483     own_private, e_pk = wsc_dh_init()
6484
6485     logger.debug("Receive M1 from STA")
6486     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6487     eap_id = (msg['eap_identifier'] + 1) % 256
6488
6489     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6490                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6491                                     r_nonce)
6492     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6493                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6494
6495     logger.debug("Send M2 to STA")
6496     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6497                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6498                                 r_nonce, uuid_r, e_pk)
6499     send_wsc_msg(dev[0], bssid, m2)
6500     eap_id = (eap_id + 1) % 256
6501
6502     logger.debug("Receive M3 from STA")
6503     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6504
6505     logger.debug("Send M4 to STA")
6506     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6507     attrs += build_attr_msg_type(WPS_M4)
6508     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6509     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6510     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6511     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6512     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6513     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6514     raw_m4_attrs = attrs
6515     m4 = build_eap_wsc(1, eap_id, attrs)
6516     send_wsc_msg(dev[0], bssid, m4)
6517     eap_id = (eap_id + 1) % 256
6518
6519     logger.debug("Receive M5 from STA")
6520     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6521
6522     logger.debug("Send M6 to STA")
6523     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6524     attrs += build_attr_msg_type(WPS_M6)
6525     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6526                             m1_attrs[ATTR_ENROLLEE_NONCE])
6527     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
6528     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6529     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
6530     raw_m6_attrs = attrs
6531     m6 = build_eap_wsc(1, eap_id, attrs)
6532     send_wsc_msg(dev[0], bssid, m6)
6533     eap_id = (eap_id + 1) % 256
6534
6535     logger.debug("Receive M7 from STA")
6536     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
6537
6538     logger.debug("Send M8 to STA")
6539     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6540     attrs += build_attr_msg_type(WPS_M8)
6541     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE,
6542                             m1_attrs[ATTR_ENROLLEE_NONCE])
6543     attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
6544     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
6545     raw_m8_attrs = attrs
6546     m8 = build_eap_wsc(1, eap_id, attrs)
6547     send_wsc_msg(dev[0], bssid, m8)
6548     eap_id = (eap_id + 1) % 256
6549
6550     if no_connect:
6551         logger.debug("Receive WSC_Done from STA")
6552         msg = get_wsc_msg(dev[0])
6553         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6554             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6555
6556         hapd.request("SET ext_eapol_frame_io 0")
6557         dev[0].request("SET ext_eapol_frame_io 0")
6558
6559         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6560
6561         dev[0].wait_disconnected()
6562         dev[0].request("REMOVE_NETWORK all")
6563     elif connect:
6564         logger.debug("Receive WSC_Done from STA")
6565         msg = get_wsc_msg(dev[0])
6566         if msg['wsc_opcode'] != WSC_Done or msg['wsc_msg_type'] != WPS_WSC_DONE:
6567             raise Exception("Unexpected Op-Code/MsgType for WSC_Done")
6568
6569         hapd.request("SET ext_eapol_frame_io 0")
6570         dev[0].request("SET ext_eapol_frame_io 0")
6571
6572         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6573
6574         dev[0].wait_connected()
6575     else:
6576         # Verify STA NACK's the credential
6577         msg = get_wsc_msg(dev[0])
6578         if msg['wsc_opcode'] != WSC_NACK:
6579             raise Exception("Unexpected message - expected WSC_Nack")
6580         dev[0].request("WPS_CANCEL")
6581         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6582         dev[0].wait_disconnected()
6583
6584 def build_cred(nw_idx='\x01', ssid='test-wps-conf', auth_type='\x00\x20',
6585                encr_type='\x00\x08', nw_key="12345678",
6586                mac_addr='\x00\x00\x00\x00\x00\x00'):
6587     attrs = ''
6588     if nw_idx is not None:
6589         attrs += build_wsc_attr(ATTR_NETWORK_INDEX, nw_idx)
6590     if ssid is not None:
6591         attrs += build_wsc_attr(ATTR_SSID, ssid)
6592     if auth_type is not None:
6593         attrs += build_wsc_attr(ATTR_AUTH_TYPE, auth_type)
6594     if encr_type is not None:
6595         attrs += build_wsc_attr(ATTR_ENCR_TYPE, encr_type)
6596     if nw_key is not None:
6597         attrs += build_wsc_attr(ATTR_NETWORK_KEY, nw_key)
6598     if mac_addr is not None:
6599         attrs += build_wsc_attr(ATTR_MAC_ADDR, mac_addr)
6600     return build_wsc_attr(ATTR_CRED, attrs)
6601
6602 def test_wps_ext_cred_proto_success(dev, apdev):
6603     """WPS and Credential: success"""
6604     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6605     m8_cred = build_cred(mac_addr=mac_addr)
6606     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6607
6608 def test_wps_ext_cred_proto_mac_addr_mismatch(dev, apdev):
6609     """WPS and Credential: MAC Address mismatch"""
6610     m8_cred = build_cred()
6611     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6612
6613 def test_wps_ext_cred_proto_zero_padding(dev, apdev):
6614     """WPS and Credential: zeropadded attributes"""
6615     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6616     m8_cred = build_cred(mac_addr=mac_addr, ssid='test-wps-conf\x00',
6617                          nw_key="12345678\x00")
6618     wps_run_cred_proto(dev, apdev, m8_cred, connect=True)
6619
6620 def test_wps_ext_cred_proto_ssid_missing(dev, apdev):
6621     """WPS and Credential: SSID missing"""
6622     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6623     m8_cred = build_cred(mac_addr=mac_addr, ssid=None)
6624     wps_run_cred_proto(dev, apdev, m8_cred)
6625
6626 def test_wps_ext_cred_proto_ssid_zero_len(dev, apdev):
6627     """WPS and Credential: Zero-length SSID"""
6628     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6629     m8_cred = build_cred(mac_addr=mac_addr, ssid="")
6630     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6631
6632 def test_wps_ext_cred_proto_auth_type_missing(dev, apdev):
6633     """WPS and Credential: Auth Type missing"""
6634     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6635     m8_cred = build_cred(mac_addr=mac_addr, auth_type=None)
6636     wps_run_cred_proto(dev, apdev, m8_cred)
6637
6638 def test_wps_ext_cred_proto_encr_type_missing(dev, apdev):
6639     """WPS and Credential: Encr Type missing"""
6640     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6641     m8_cred = build_cred(mac_addr=mac_addr, encr_type=None)
6642     wps_run_cred_proto(dev, apdev, m8_cred)
6643
6644 def test_wps_ext_cred_proto_network_key_missing(dev, apdev):
6645     """WPS and Credential: Network Key missing"""
6646     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6647     m8_cred = build_cred(mac_addr=mac_addr, nw_key=None)
6648     wps_run_cred_proto(dev, apdev, m8_cred)
6649
6650 def test_wps_ext_cred_proto_network_key_missing_open(dev, apdev):
6651     """WPS and Credential: Network Key missing (open)"""
6652     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6653     m8_cred = build_cred(mac_addr=mac_addr, auth_type='\x00\x01',
6654                          encr_type='\x00\x01', nw_key=None, ssid="foo")
6655     wps_run_cred_proto(dev, apdev, m8_cred, no_connect=True)
6656
6657 def test_wps_ext_cred_proto_mac_addr_missing(dev, apdev):
6658     """WPS and Credential: MAC Address missing"""
6659     m8_cred = build_cred(mac_addr=None)
6660     wps_run_cred_proto(dev, apdev, m8_cred)
6661
6662 def test_wps_ext_cred_proto_invalid_encr_type(dev, apdev):
6663     """WPS and Credential: Invalid Encr Type"""
6664     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6665     m8_cred = build_cred(mac_addr=mac_addr, encr_type='\x00\x00')
6666     wps_run_cred_proto(dev, apdev, m8_cred)
6667
6668 def test_wps_ext_cred_proto_missing_cred(dev, apdev):
6669     """WPS and Credential: Missing Credential"""
6670     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6671     m8_cred = ''
6672     wps_run_cred_proto(dev, apdev, m8_cred)
6673
6674 def test_wps_ext_proto_m2_no_public_key(dev, apdev):
6675     """WPS and no Public Key in M2"""
6676     pin = "12345670"
6677     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6678     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6679     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6680     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6681
6682     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6683     uuid_r = 16*'\x33'
6684     r_nonce = 16*'\x44'
6685     own_private, e_pk = wsc_dh_init()
6686
6687     logger.debug("Receive M1 from STA")
6688     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6689     eap_id = (msg['eap_identifier'] + 1) % 256
6690
6691     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6692                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6693                                     r_nonce)
6694     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6695                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6696
6697     logger.debug("Send M2 to STA")
6698     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6699                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6700                                 r_nonce, uuid_r, None)
6701     send_wsc_msg(dev[0], bssid, m2)
6702     eap_id = (eap_id + 1) % 256
6703
6704     # Verify STA NACK's the credential
6705     msg = get_wsc_msg(dev[0])
6706     if msg['wsc_opcode'] != WSC_NACK:
6707         raise Exception("Unexpected message - expected WSC_Nack")
6708     dev[0].request("WPS_CANCEL")
6709     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6710     dev[0].wait_disconnected()
6711
6712 def test_wps_ext_proto_m2_invalid_public_key(dev, apdev):
6713     """WPS and invalid Public Key in M2"""
6714     pin = "12345670"
6715     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6716     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6717     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6718     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6719
6720     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6721     uuid_r = 16*'\x33'
6722     r_nonce = 16*'\x44'
6723     own_private, e_pk = wsc_dh_init()
6724
6725     logger.debug("Receive M1 from STA")
6726     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6727     eap_id = (msg['eap_identifier'] + 1) % 256
6728
6729     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6730                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6731                                     r_nonce)
6732     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6733                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6734
6735     logger.debug("Send M2 to STA")
6736     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6737                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6738                                 r_nonce, uuid_r, 192*'\xff')
6739     send_wsc_msg(dev[0], bssid, m2)
6740     eap_id = (eap_id + 1) % 256
6741
6742     # Verify STA NACK's the credential
6743     msg = get_wsc_msg(dev[0])
6744     if msg['wsc_opcode'] != WSC_NACK:
6745         raise Exception("Unexpected message - expected WSC_Nack")
6746     dev[0].request("WPS_CANCEL")
6747     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6748     dev[0].wait_disconnected()
6749
6750 def test_wps_ext_proto_m2_public_key_oom(dev, apdev):
6751     """WPS and Public Key OOM in M2"""
6752     pin = "12345670"
6753     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6754     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6755     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6756     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6757
6758     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6759     uuid_r = 16*'\x33'
6760     r_nonce = 16*'\x44'
6761     own_private, e_pk = wsc_dh_init()
6762
6763     logger.debug("Receive M1 from STA")
6764     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6765     eap_id = (msg['eap_identifier'] + 1) % 256
6766
6767     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6768                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6769                                     r_nonce)
6770     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6771                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6772
6773     logger.debug("Send M2 to STA")
6774     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6775                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6776                                 r_nonce, uuid_r, e_pk)
6777     with alloc_fail(dev[0], 1, "wpabuf_alloc_copy;wps_process_pubkey"):
6778         send_wsc_msg(dev[0], bssid, m2)
6779         eap_id = (eap_id + 1) % 256
6780
6781         # Verify STA NACK's the credential
6782         msg = get_wsc_msg(dev[0])
6783         if msg['wsc_opcode'] != WSC_NACK:
6784             raise Exception("Unexpected message - expected WSC_Nack")
6785         dev[0].request("WPS_CANCEL")
6786         send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
6787         dev[0].wait_disconnected()
6788
6789 def test_wps_ext_proto_nack_m3(dev, apdev):
6790     """WPS and NACK M3"""
6791     pin = "12345670"
6792     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6793     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6794     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6795     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6796
6797     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6798     uuid_r = 16*'\x33'
6799     r_nonce = 16*'\x44'
6800     own_private, e_pk = wsc_dh_init()
6801
6802     logger.debug("Receive M1 from STA")
6803     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6804     eap_id = (msg['eap_identifier'] + 1) % 256
6805
6806     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6807                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6808                                     r_nonce)
6809     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6810                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6811
6812     logger.debug("Send M2 to STA")
6813     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6814                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6815                                 r_nonce, uuid_r, e_pk)
6816     send_wsc_msg(dev[0], bssid, m2)
6817     eap_id = (eap_id + 1) % 256
6818
6819     logger.debug("Receive M3 from STA")
6820     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6821
6822     logger.debug("Send NACK to STA")
6823     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
6824                             r_nonce, config_error='\x01\x23')
6825     send_wsc_msg(dev[0], bssid, msg)
6826     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
6827     if ev is None:
6828         raise Exception("Failure not reported")
6829     if "msg=7 config_error=291" not in ev:
6830         raise Exception("Unexpected failure reason: " + ev)
6831
6832 def test_wps_ext_proto_nack_m5(dev, apdev):
6833     """WPS and NACK M5"""
6834     pin = "12345670"
6835     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
6836     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6837     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6838     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6839
6840     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6841     uuid_r = 16*'\x33'
6842     r_nonce = 16*'\x44'
6843     own_private, e_pk = wsc_dh_init()
6844
6845     logger.debug("Receive M1 from STA")
6846     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6847     eap_id = (msg['eap_identifier'] + 1) % 256
6848
6849     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6850                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6851                                     r_nonce)
6852     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6853                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6854
6855     logger.debug("Send M2 to STA")
6856     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6857                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6858                                 r_nonce, uuid_r, e_pk)
6859     send_wsc_msg(dev[0], bssid, m2)
6860     eap_id = (eap_id + 1) % 256
6861
6862     logger.debug("Receive M3 from STA")
6863     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6864
6865     logger.debug("Send M4 to STA")
6866     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
6867     attrs += build_attr_msg_type(WPS_M4)
6868     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
6869     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
6870     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
6871     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
6872     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
6873     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
6874     raw_m4_attrs = attrs
6875     m4 = build_eap_wsc(1, eap_id, attrs)
6876     send_wsc_msg(dev[0], bssid, m4)
6877     eap_id = (eap_id + 1) % 256
6878
6879     logger.debug("Receive M5 from STA")
6880     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
6881
6882     logger.debug("Send NACK to STA")
6883     msg, attrs = build_nack(eap_id, m1_attrs[ATTR_ENROLLEE_NONCE],
6884                             r_nonce, config_error='\x01\x24')
6885     send_wsc_msg(dev[0], bssid, msg)
6886     ev = dev[0].wait_event(["WPS-FAIL"], timeout=5)
6887     if ev is None:
6888         raise Exception("Failure not reported")
6889     if "msg=9 config_error=292" not in ev:
6890         raise Exception("Unexpected failure reason: " + ev)
6891
6892 def wps_nack_m3(dev, apdev):
6893     pin = "00000000"
6894     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pbc=True)
6895     wps_ext_eap_identity_req(dev[0], hapd, bssid)
6896     wps_ext_eap_identity_resp(hapd, dev[0], addr)
6897     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
6898
6899     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
6900     uuid_r = 16*'\x33'
6901     r_nonce = 16*'\x44'
6902     own_private, e_pk = wsc_dh_init()
6903
6904     logger.debug("Receive M1 from STA")
6905     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
6906     eap_id = (msg['eap_identifier'] + 1) % 256
6907
6908     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
6909                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
6910                                     r_nonce)
6911     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
6912                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
6913
6914     logger.debug("Send M2 to STA")
6915     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
6916                                 m1_attrs[ATTR_ENROLLEE_NONCE],
6917                                 r_nonce, uuid_r, e_pk, dev_pw_id='\x00\x04')
6918     send_wsc_msg(dev[0], bssid, m2)
6919     eap_id = (eap_id + 1) % 256
6920
6921     logger.debug("Receive M3 from STA")
6922     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
6923     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid
6924
6925 def test_wps_ext_proto_nack_m3_no_config_error(dev, apdev):
6926     """WPS and NACK M3 missing Config Error"""
6927     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6928     logger.debug("Send NACK to STA")
6929     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, config_error=None)
6930     send_wsc_msg(dev[0], bssid, msg)
6931     dev[0].request("WPS_CANCEL")
6932     dev[0].wait_disconnected()
6933     dev[0].flush_scan_cache()
6934
6935 def test_wps_ext_proto_nack_m3_no_e_nonce(dev, apdev):
6936     """WPS and NACK M3 missing E-Nonce"""
6937     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6938     logger.debug("Send NACK to STA")
6939     msg, attrs = build_nack(eap_id, None, r_nonce)
6940     send_wsc_msg(dev[0], bssid, msg)
6941     dev[0].request("WPS_CANCEL")
6942     dev[0].wait_disconnected()
6943     dev[0].flush_scan_cache()
6944
6945 def test_wps_ext_proto_nack_m3_e_nonce_mismatch(dev, apdev):
6946     """WPS and NACK M3 E-Nonce mismatch"""
6947     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6948     logger.debug("Send NACK to STA")
6949     msg, attrs = build_nack(eap_id, 16*'\x00', r_nonce)
6950     send_wsc_msg(dev[0], bssid, msg)
6951     dev[0].request("WPS_CANCEL")
6952     dev[0].wait_disconnected()
6953     dev[0].flush_scan_cache()
6954
6955 def test_wps_ext_proto_nack_m3_no_r_nonce(dev, apdev):
6956     """WPS and NACK M3 missing R-Nonce"""
6957     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6958     logger.debug("Send NACK to STA")
6959     msg, attrs = build_nack(eap_id, e_nonce, None)
6960     send_wsc_msg(dev[0], bssid, msg)
6961     dev[0].request("WPS_CANCEL")
6962     dev[0].wait_disconnected()
6963     dev[0].flush_scan_cache()
6964
6965 def test_wps_ext_proto_nack_m3_r_nonce_mismatch(dev, apdev):
6966     """WPS and NACK M3 R-Nonce mismatch"""
6967     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6968     logger.debug("Send NACK to STA")
6969     msg, attrs = build_nack(eap_id, e_nonce, 16*'\x00')
6970     send_wsc_msg(dev[0], bssid, msg)
6971     dev[0].request("WPS_CANCEL")
6972     dev[0].wait_disconnected()
6973     dev[0].flush_scan_cache()
6974
6975 def test_wps_ext_proto_nack_m3_no_msg_type(dev, apdev):
6976     """WPS and NACK M3 no Message Type"""
6977     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6978     logger.debug("Send NACK to STA")
6979     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=None)
6980     send_wsc_msg(dev[0], bssid, msg)
6981     dev[0].request("WPS_CANCEL")
6982     dev[0].wait_disconnected()
6983     dev[0].flush_scan_cache()
6984
6985 def test_wps_ext_proto_nack_m3_invalid_msg_type(dev, apdev):
6986     """WPS and NACK M3 invalid Message Type"""
6987     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6988     logger.debug("Send NACK to STA")
6989     msg, attrs = build_nack(eap_id, e_nonce, r_nonce, msg_type=123)
6990     send_wsc_msg(dev[0], bssid, msg)
6991     dev[0].request("WPS_CANCEL")
6992     dev[0].wait_disconnected()
6993     dev[0].flush_scan_cache()
6994
6995 def test_wps_ext_proto_nack_m3_invalid_attr(dev, apdev):
6996     """WPS and NACK M3 invalid attribute"""
6997     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
6998     logger.debug("Send NACK to STA")
6999     attrs = '\x10\x10\x00'
7000     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_NACK)
7001     send_wsc_msg(dev[0], bssid, msg)
7002     dev[0].request("WPS_CANCEL")
7003     dev[0].wait_disconnected()
7004     dev[0].flush_scan_cache()
7005
7006 def test_wps_ext_proto_ack_m3_no_e_nonce(dev, apdev):
7007     """WPS and ACK M3 missing E-Nonce"""
7008     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7009     logger.debug("Send NACK to STA")
7010     msg, attrs = build_ack(eap_id, None, r_nonce)
7011     send_wsc_msg(dev[0], bssid, msg)
7012     dev[0].request("WPS_CANCEL")
7013     dev[0].wait_disconnected()
7014     dev[0].flush_scan_cache()
7015
7016 def test_wps_ext_proto_ack_m3_e_nonce_mismatch(dev, apdev):
7017     """WPS and ACK M3 E-Nonce mismatch"""
7018     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7019     logger.debug("Send NACK to STA")
7020     msg, attrs = build_ack(eap_id, 16*'\x00', r_nonce)
7021     send_wsc_msg(dev[0], bssid, msg)
7022     dev[0].request("WPS_CANCEL")
7023     dev[0].wait_disconnected()
7024     dev[0].flush_scan_cache()
7025
7026 def test_wps_ext_proto_ack_m3_no_r_nonce(dev, apdev):
7027     """WPS and ACK M3 missing R-Nonce"""
7028     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7029     logger.debug("Send NACK to STA")
7030     msg, attrs = build_ack(eap_id, e_nonce, None)
7031     send_wsc_msg(dev[0], bssid, msg)
7032     dev[0].request("WPS_CANCEL")
7033     dev[0].wait_disconnected()
7034     dev[0].flush_scan_cache()
7035
7036 def test_wps_ext_proto_ack_m3_r_nonce_mismatch(dev, apdev):
7037     """WPS and ACK M3 R-Nonce mismatch"""
7038     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7039     logger.debug("Send NACK to STA")
7040     msg, attrs = build_ack(eap_id, e_nonce, 16*'\x00')
7041     send_wsc_msg(dev[0], bssid, msg)
7042     dev[0].request("WPS_CANCEL")
7043     dev[0].wait_disconnected()
7044     dev[0].flush_scan_cache()
7045
7046 def test_wps_ext_proto_ack_m3_no_msg_type(dev, apdev):
7047     """WPS and ACK M3 no Message Type"""
7048     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7049     logger.debug("Send NACK to STA")
7050     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=None)
7051     send_wsc_msg(dev[0], bssid, msg)
7052     dev[0].request("WPS_CANCEL")
7053     dev[0].wait_disconnected()
7054     dev[0].flush_scan_cache()
7055
7056 def test_wps_ext_proto_ack_m3_invalid_msg_type(dev, apdev):
7057     """WPS and ACK M3 invalid Message Type"""
7058     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7059     logger.debug("Send NACK to STA")
7060     msg, attrs = build_ack(eap_id, e_nonce, r_nonce, msg_type=123)
7061     send_wsc_msg(dev[0], bssid, msg)
7062     dev[0].request("WPS_CANCEL")
7063     dev[0].wait_disconnected()
7064     dev[0].flush_scan_cache()
7065
7066 def test_wps_ext_proto_ack_m3_invalid_attr(dev, apdev):
7067     """WPS and ACK M3 invalid attribute"""
7068     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7069     logger.debug("Send ACK to STA")
7070     attrs = '\x10\x10\x00'
7071     msg = build_eap_wsc(1, eap_id, attrs, opcode=WSC_ACK)
7072     send_wsc_msg(dev[0], bssid, msg)
7073     dev[0].request("WPS_CANCEL")
7074     dev[0].wait_disconnected()
7075     dev[0].flush_scan_cache()
7076
7077 def test_wps_ext_proto_ack_m3(dev, apdev):
7078     """WPS and ACK M3"""
7079     eap_id, e_nonce, r_nonce, bssid = wps_nack_m3(dev, apdev)
7080     logger.debug("Send ACK to STA")
7081     msg, attrs = build_ack(eap_id, e_nonce, r_nonce)
7082     send_wsc_msg(dev[0], bssid, msg)
7083     dev[0].request("WPS_CANCEL")
7084     dev[0].wait_disconnected()
7085     dev[0].flush_scan_cache()
7086
7087 def wps_to_m3_helper(dev, apdev):
7088     pin = "12345670"
7089     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7090     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7091     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7092     wps_ext_eap_wsc(dev[0], hapd, bssid, "EAP-WSC/Start")
7093
7094     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7095     uuid_r = 16*'\x33'
7096     r_nonce = 16*'\x44'
7097     own_private, e_pk = wsc_dh_init()
7098
7099     logger.debug("Receive M1 from STA")
7100     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M1)
7101     eap_id = (msg['eap_identifier'] + 1) % 256
7102
7103     authkey,keywrapkey = wsc_dh_kdf(m1_attrs[ATTR_PUBLIC_KEY], own_private,
7104                                     mac_addr, m1_attrs[ATTR_ENROLLEE_NONCE],
7105                                     r_nonce)
7106     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, pin,
7107                                                 m1_attrs[ATTR_PUBLIC_KEY], e_pk)
7108
7109     logger.debug("Send M2 to STA")
7110     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, eap_id,
7111                                 m1_attrs[ATTR_ENROLLEE_NONCE],
7112                                 r_nonce, uuid_r, e_pk)
7113     send_wsc_msg(dev[0], bssid, m2)
7114     eap_id = (eap_id + 1) % 256
7115
7116     logger.debug("Receive M3 from STA")
7117     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M3)
7118     return eap_id, m1_attrs, r_nonce, bssid, r_hash1, r_hash2, r_s1, r_s2, raw_m3_attrs, authkey, keywrapkey
7119
7120 def wps_to_m3(dev, apdev):
7121     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)
7122     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s1, raw_m3_attrs, authkey, keywrapkey
7123
7124 def wps_to_m5(dev, apdev):
7125     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)
7126
7127     logger.debug("Send M4 to STA")
7128     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7129     attrs += build_attr_msg_type(WPS_M4)
7130     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, m1_attrs[ATTR_ENROLLEE_NONCE])
7131     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7132     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7133     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7134     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7135     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7136     raw_m4_attrs = attrs
7137     m4 = build_eap_wsc(1, eap_id, attrs)
7138     send_wsc_msg(dev[0], bssid, m4)
7139     eap_id = (eap_id + 1) % 256
7140
7141     logger.debug("Receive M5 from STA")
7142     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M5)
7143
7144     return eap_id, m1_attrs[ATTR_ENROLLEE_NONCE], r_nonce, bssid, r_hash1, r_hash2, r_s2, raw_m5_attrs, authkey, keywrapkey
7145
7146 def test_wps_ext_proto_m4_missing_r_hash1(dev, apdev):
7147     """WPS and no R-Hash1 in M4"""
7148     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7149
7150     logger.debug("Send M4 to STA")
7151     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7152     attrs += build_attr_msg_type(WPS_M4)
7153     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7154     #attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7155     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7156     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7157     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7158     attrs += build_attr_authenticator(authkey, m3, attrs)
7159     m4 = build_eap_wsc(1, eap_id, attrs)
7160     send_wsc_msg(dev[0], bssid, m4)
7161     eap_id = (eap_id + 1) % 256
7162
7163     logger.debug("Receive M5 (NACK) from STA")
7164     msg = get_wsc_msg(dev[0])
7165     if msg['wsc_opcode'] != WSC_NACK:
7166         raise Exception("Unexpected message - expected WSC_Nack")
7167
7168     dev[0].request("WPS_CANCEL")
7169     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7170     dev[0].wait_disconnected()
7171
7172 def test_wps_ext_proto_m4_missing_r_hash2(dev, apdev):
7173     """WPS and no R-Hash2 in M4"""
7174     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7175
7176     logger.debug("Send M4 to STA")
7177     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7178     attrs += build_attr_msg_type(WPS_M4)
7179     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7180     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7181     #attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7182     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7183     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7184     attrs += build_attr_authenticator(authkey, m3, attrs)
7185     m4 = build_eap_wsc(1, eap_id, attrs)
7186     send_wsc_msg(dev[0], bssid, m4)
7187     eap_id = (eap_id + 1) % 256
7188
7189     logger.debug("Receive M5 (NACK) from STA")
7190     msg = get_wsc_msg(dev[0])
7191     if msg['wsc_opcode'] != WSC_NACK:
7192         raise Exception("Unexpected message - expected WSC_Nack")
7193
7194     dev[0].request("WPS_CANCEL")
7195     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7196     dev[0].wait_disconnected()
7197
7198 def test_wps_ext_proto_m4_missing_r_snonce1(dev, apdev):
7199     """WPS and no R-SNonce1 in M4"""
7200     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7201
7202     logger.debug("Send M4 to STA")
7203     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7204     attrs += build_attr_msg_type(WPS_M4)
7205     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7206     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7207     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7208     #data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7209     data = ''
7210     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7211     attrs += build_attr_authenticator(authkey, m3, attrs)
7212     m4 = build_eap_wsc(1, eap_id, attrs)
7213     send_wsc_msg(dev[0], bssid, m4)
7214     eap_id = (eap_id + 1) % 256
7215
7216     logger.debug("Receive M5 (NACK) from STA")
7217     msg = get_wsc_msg(dev[0])
7218     if msg['wsc_opcode'] != WSC_NACK:
7219         raise Exception("Unexpected message - expected WSC_Nack")
7220
7221     dev[0].request("WPS_CANCEL")
7222     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7223     dev[0].wait_disconnected()
7224
7225 def test_wps_ext_proto_m4_invalid_pad_string(dev, apdev):
7226     """WPS and invalid pad string in M4"""
7227     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7228
7229     logger.debug("Send M4 to STA")
7230     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7231     attrs += build_attr_msg_type(WPS_M4)
7232     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7233     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7234     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7235     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7236
7237     m = hmac.new(authkey, data, hashlib.sha256)
7238     kwa = m.digest()[0:8]
7239     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7240     iv = 16*'\x99'
7241     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7242     pad_len = 16 - len(data) % 16
7243     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', pad_len - 1)
7244     data += ps
7245     wrapped = aes.encrypt(data)
7246     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7247
7248     attrs += build_attr_authenticator(authkey, m3, attrs)
7249     m4 = build_eap_wsc(1, eap_id, attrs)
7250     send_wsc_msg(dev[0], bssid, m4)
7251     eap_id = (eap_id + 1) % 256
7252
7253     logger.debug("Receive M5 (NACK) from STA")
7254     msg = get_wsc_msg(dev[0])
7255     if msg['wsc_opcode'] != WSC_NACK:
7256         raise Exception("Unexpected message - expected WSC_Nack")
7257
7258     dev[0].request("WPS_CANCEL")
7259     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7260     dev[0].wait_disconnected()
7261
7262 def test_wps_ext_proto_m4_invalid_pad_value(dev, apdev):
7263     """WPS and invalid pad value in M4"""
7264     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7265
7266     logger.debug("Send M4 to STA")
7267     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7268     attrs += build_attr_msg_type(WPS_M4)
7269     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7270     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7271     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7272     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7273
7274     m = hmac.new(authkey, data, hashlib.sha256)
7275     kwa = m.digest()[0:8]
7276     data += build_wsc_attr(ATTR_KEY_WRAP_AUTH, kwa)
7277     iv = 16*'\x99'
7278     aes = AES.new(keywrapkey, AES.MODE_CBC, iv)
7279     pad_len = 16 - len(data) % 16
7280     ps = (pad_len - 1) * struct.pack('B', pad_len) + struct.pack('B', 255)
7281     data += ps
7282     wrapped = aes.encrypt(data)
7283     attrs += build_wsc_attr(ATTR_ENCR_SETTINGS, iv + wrapped)
7284
7285     attrs += build_attr_authenticator(authkey, m3, attrs)
7286     m4 = build_eap_wsc(1, eap_id, attrs)
7287     send_wsc_msg(dev[0], bssid, m4)
7288     eap_id = (eap_id + 1) % 256
7289
7290     logger.debug("Receive M5 (NACK) from STA")
7291     msg = get_wsc_msg(dev[0])
7292     if msg['wsc_opcode'] != WSC_NACK:
7293         raise Exception("Unexpected message - expected WSC_Nack")
7294
7295     dev[0].request("WPS_CANCEL")
7296     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7297     dev[0].wait_disconnected()
7298
7299 def test_wps_ext_proto_m4_no_encr_settings(dev, apdev):
7300     """WPS and no Encr Settings in M4"""
7301     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s1, m3, authkey, keywrapkey = wps_to_m3(dev, apdev)
7302
7303     logger.debug("Send M4 to STA")
7304     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7305     attrs += build_attr_msg_type(WPS_M4)
7306     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7307     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7308     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7309     attrs += build_attr_authenticator(authkey, m3, attrs)
7310     m4 = build_eap_wsc(1, eap_id, attrs)
7311     send_wsc_msg(dev[0], bssid, m4)
7312     eap_id = (eap_id + 1) % 256
7313
7314     logger.debug("Receive M5 (NACK) from STA")
7315     msg = get_wsc_msg(dev[0])
7316     if msg['wsc_opcode'] != WSC_NACK:
7317         raise Exception("Unexpected message - expected WSC_Nack")
7318
7319     dev[0].request("WPS_CANCEL")
7320     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7321     dev[0].wait_disconnected()
7322
7323 def test_wps_ext_proto_m6_missing_r_snonce2(dev, apdev):
7324     """WPS and no R-SNonce2 in M6"""
7325     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7326
7327     logger.debug("Send M6 to STA")
7328     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7329     attrs += build_attr_msg_type(WPS_M6)
7330     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7331     #data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7332     data = ''
7333     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7334     attrs += build_attr_authenticator(authkey, m5, attrs)
7335     m6 = build_eap_wsc(1, eap_id, attrs)
7336     send_wsc_msg(dev[0], bssid, m6)
7337     eap_id = (eap_id + 1) % 256
7338
7339     logger.debug("Receive M7 (NACK) from STA")
7340     msg = get_wsc_msg(dev[0])
7341     if msg['wsc_opcode'] != WSC_NACK:
7342         raise Exception("Unexpected message - expected WSC_Nack")
7343
7344     dev[0].request("WPS_CANCEL")
7345     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7346     dev[0].wait_disconnected()
7347
7348 def test_wps_ext_proto_m6_no_encr_settings(dev, apdev):
7349     """WPS and no Encr Settings in M6"""
7350     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7351
7352     logger.debug("Send M6 to STA")
7353     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7354     attrs += build_attr_msg_type(WPS_M6)
7355     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7356     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7357     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7358     attrs += build_attr_authenticator(authkey, m5, attrs)
7359     m6 = build_eap_wsc(1, eap_id, attrs)
7360     send_wsc_msg(dev[0], bssid, m6)
7361     eap_id = (eap_id + 1) % 256
7362
7363     logger.debug("Receive M7 (NACK) from STA")
7364     msg = get_wsc_msg(dev[0])
7365     if msg['wsc_opcode'] != WSC_NACK:
7366         raise Exception("Unexpected message - expected WSC_Nack")
7367
7368     dev[0].request("WPS_CANCEL")
7369     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7370     dev[0].wait_disconnected()
7371
7372 def test_wps_ext_proto_m8_no_encr_settings(dev, apdev):
7373     """WPS and no Encr Settings in M6"""
7374     eap_id, e_nonce, r_nonce, bssid, r_hash1, r_hash2, r_s2, m5, authkey, keywrapkey = wps_to_m5(dev, apdev)
7375
7376     logger.debug("Send M6 to STA")
7377     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7378     attrs += build_attr_msg_type(WPS_M6)
7379     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7380     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7381     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7382     attrs += build_attr_authenticator(authkey, m5, attrs)
7383     raw_m6_attrs = attrs
7384     m6 = build_eap_wsc(1, eap_id, attrs)
7385     send_wsc_msg(dev[0], bssid, m6)
7386     eap_id = (eap_id + 1) % 256
7387
7388     logger.debug("Receive M7 from STA")
7389     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(dev[0], WSC_MSG, WPS_M7)
7390
7391     logger.debug("Send M8 to STA")
7392     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7393     attrs += build_attr_msg_type(WPS_M8)
7394     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7395     #attrs += build_attr_encr_settings(authkey, keywrapkey, m8_cred)
7396     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7397     raw_m8_attrs = attrs
7398     m8 = build_eap_wsc(1, eap_id, attrs)
7399     send_wsc_msg(dev[0], bssid, m8)
7400
7401     logger.debug("Receive WSC_Done (NACK) from STA")
7402     msg = get_wsc_msg(dev[0])
7403     if msg['wsc_opcode'] != WSC_NACK:
7404         raise Exception("Unexpected message - expected WSC_Nack")
7405
7406     dev[0].request("WPS_CANCEL")
7407     send_wsc_msg(dev[0], bssid, build_eap_failure(eap_id))
7408     dev[0].wait_disconnected()
7409
7410 def wps_start_ext_reg(apdev, dev):
7411     addr = dev.own_addr()
7412     bssid = apdev['bssid']
7413     ssid = "test-wps-conf"
7414     appin = "12345670"
7415     params = { "ssid": ssid, "eap_server": "1", "wps_state": "2",
7416                "wpa_passphrase": "12345678", "wpa": "2",
7417                "wpa_key_mgmt": "WPA-PSK", "rsn_pairwise": "CCMP",
7418                "ap_pin": appin }
7419     hapd = hostapd.add_ap(apdev['ifname'], params)
7420
7421     dev.scan_for_bss(bssid, freq="2412")
7422     hapd.request("SET ext_eapol_frame_io 1")
7423     dev.request("SET ext_eapol_frame_io 1")
7424
7425     dev.request("WPS_REG " + bssid + " " + appin)
7426
7427     return addr,bssid,hapd
7428
7429 def wps_run_ap_settings_proto(dev, apdev, ap_settings, success):
7430     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7431     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7432     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7433
7434     logger.debug("Receive M1 from AP")
7435     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7436     mac_addr = m1_attrs[ATTR_MAC_ADDR]
7437     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7438     e_pk = m1_attrs[ATTR_PUBLIC_KEY]
7439
7440     appin = '12345670'
7441     uuid_r = 16*'\x33'
7442     r_nonce = 16*'\x44'
7443     own_private, r_pk = wsc_dh_init()
7444     authkey,keywrapkey = wsc_dh_kdf(e_pk, own_private, mac_addr, e_nonce,
7445                                     r_nonce)
7446     r_s1,r_s2,r_hash1,r_hash2 = wsc_dev_pw_hash(authkey, appin, e_pk, r_pk)
7447
7448     logger.debug("Send M2 to AP")
7449     m2, raw_m2_attrs = build_m2(authkey, raw_m1_attrs, msg['eap_identifier'],
7450                                 e_nonce, r_nonce, uuid_r, r_pk, eap_code=2)
7451     send_wsc_msg(hapd, addr, m2)
7452
7453     logger.debug("Receive M3 from AP")
7454     msg, m3_attrs, raw_m3_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M3)
7455
7456     logger.debug("Send M4 to AP")
7457     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7458     attrs += build_attr_msg_type(WPS_M4)
7459     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7460     attrs += build_wsc_attr(ATTR_R_HASH1, r_hash1)
7461     attrs += build_wsc_attr(ATTR_R_HASH2, r_hash2)
7462     data = build_wsc_attr(ATTR_R_SNONCE1, r_s1)
7463     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7464     attrs += build_attr_authenticator(authkey, raw_m3_attrs, attrs)
7465     raw_m4_attrs = attrs
7466     m4 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7467     send_wsc_msg(hapd, addr, m4)
7468
7469     logger.debug("Receive M5 from AP")
7470     msg, m5_attrs, raw_m5_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M5)
7471
7472     logger.debug("Send M6 to STA")
7473     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7474     attrs += build_attr_msg_type(WPS_M6)
7475     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7476     data = build_wsc_attr(ATTR_R_SNONCE2, r_s2)
7477     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7478     attrs += build_attr_authenticator(authkey, raw_m5_attrs, attrs)
7479     raw_m6_attrs = attrs
7480     m6 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7481     send_wsc_msg(hapd, addr, m6)
7482
7483     logger.debug("Receive M7 from AP")
7484     msg, m7_attrs, raw_m7_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M7)
7485
7486     logger.debug("Send M8 to STA")
7487     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7488     attrs += build_attr_msg_type(WPS_M8)
7489     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
7490     if ap_settings:
7491         attrs += build_attr_encr_settings(authkey, keywrapkey, ap_settings)
7492     attrs += build_attr_authenticator(authkey, raw_m7_attrs, attrs)
7493     raw_m8_attrs = attrs
7494     m8 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7495     send_wsc_msg(hapd, addr, m8)
7496
7497     if success:
7498         ev = hapd.wait_event(["WPS-NEW-AP-SETTINGS"], timeout=5)
7499         if ev is None:
7500             raise Exception("New AP settings not reported")
7501         logger.debug("Receive WSC_Done from AP")
7502         msg = get_wsc_msg(hapd)
7503         if msg['wsc_opcode'] != WSC_Done:
7504             raise Exception("Unexpected message - expected WSC_Done")
7505
7506         logger.debug("Send WSC_ACK to AP")
7507         ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
7508                               eap_code=2)
7509         send_wsc_msg(hapd, addr, ack)
7510         dev[0].wait_disconnected()
7511     else:
7512         ev = hapd.wait_event(["WPS-FAIL"], timeout=5)
7513         if ev is None:
7514             raise Exception("WPS failure not reported")
7515         logger.debug("Receive WSC_NACK from AP")
7516         msg = get_wsc_msg(hapd)
7517         if msg['wsc_opcode'] != WSC_NACK:
7518             raise Exception("Unexpected message - expected WSC_NACK")
7519
7520         logger.debug("Send WSC_NACK to AP")
7521         nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7522                                 eap_code=2)
7523         send_wsc_msg(hapd, addr, nack)
7524         dev[0].wait_disconnected()
7525
7526 def test_wps_ext_ap_settings_success(dev, apdev):
7527     """WPS and AP Settings: success"""
7528     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7529     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7530     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7531     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7532     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7533     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7534     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7535
7536 def test_wps_ext_ap_settings_missing(dev, apdev):
7537     """WPS and AP Settings: missing"""
7538     wps_run_ap_settings_proto(dev, apdev, None, False)
7539
7540 def test_wps_ext_ap_settings_mac_addr_mismatch(dev, apdev):
7541     """WPS and AP Settings: MAC Address mismatch"""
7542     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7543     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7544     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7545     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7546     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7547     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, '\x00\x00\x00\x00\x00\x00')
7548     wps_run_ap_settings_proto(dev, apdev, ap_settings, True)
7549
7550 def test_wps_ext_ap_settings_mac_addr_missing(dev, apdev):
7551     """WPS and AP Settings: missing MAC Address"""
7552     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7553     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7554     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7555     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x01')
7556     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7557     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7558
7559 def test_wps_ext_ap_settings_reject_encr_type(dev, apdev):
7560     """WPS and AP Settings: reject Encr Type"""
7561     ap_settings = build_wsc_attr(ATTR_NETWORK_INDEX, '\x01')
7562     ap_settings += build_wsc_attr(ATTR_SSID, "test")
7563     ap_settings += build_wsc_attr(ATTR_AUTH_TYPE, '\x00\x01')
7564     ap_settings += build_wsc_attr(ATTR_ENCR_TYPE, '\x00\x00')
7565     ap_settings += build_wsc_attr(ATTR_NETWORK_KEY, '')
7566     ap_settings += build_wsc_attr(ATTR_MAC_ADDR, binascii.unhexlify(apdev[0]['bssid'].replace(':', '')))
7567     wps_run_ap_settings_proto(dev, apdev, ap_settings, False)
7568
7569 def test_wps_ext_ap_settings_m2d(dev, apdev):
7570     """WPS and AP Settings: M2D"""
7571     addr,bssid,hapd = wps_start_ext_reg(apdev[0], dev[0])
7572     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7573     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7574
7575     logger.debug("Receive M1 from AP")
7576     msg, m1_attrs, raw_m1_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M1)
7577     e_nonce = m1_attrs[ATTR_ENROLLEE_NONCE]
7578
7579     r_nonce = 16*'\x44'
7580     uuid_r = 16*'\x33'
7581
7582     logger.debug("Send M2D to AP")
7583     m2d, raw_m2d_attrs = build_m2d(raw_m1_attrs, msg['eap_identifier'],
7584                                    e_nonce, r_nonce, uuid_r,
7585                                    dev_pw_id='\x00\x00', eap_code=2)
7586     send_wsc_msg(hapd, addr, m2d)
7587
7588     ev = hapd.wait_event(["WPS-M2D"], timeout=5)
7589     if ev is None:
7590         raise Exception("M2D not reported")
7591
7592     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7593
7594 def wps_wait_ap_nack(hapd, dev, e_nonce, r_nonce):
7595     logger.debug("Receive WSC_NACK from AP")
7596     msg = get_wsc_msg(hapd)
7597     if msg['wsc_opcode'] != WSC_NACK:
7598         raise Exception("Unexpected message - expected WSC_NACK")
7599
7600     logger.debug("Send WSC_NACK to AP")
7601     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
7602                             eap_code=2)
7603     send_wsc_msg(hapd, dev.own_addr(), nack)
7604     dev.wait_disconnected()
7605
7606 def test_wps_ext_m3_missing_e_hash1(dev, apdev):
7607     """WPS proto: M3 missing E-Hash1"""
7608     pin = "12345670"
7609     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7610     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7611     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7612
7613     logger.debug("Receive WSC/Start from AP")
7614     msg = get_wsc_msg(hapd)
7615     if msg['wsc_opcode'] != WSC_Start:
7616         raise Exception("Unexpected Op-Code for WSC/Start")
7617
7618     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7619     uuid_e = 16*'\x11'
7620     e_nonce = 16*'\x22'
7621     own_private, e_pk = wsc_dh_init()
7622
7623     logger.debug("Send M1 to AP")
7624     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7625                                 e_nonce, e_pk)
7626     send_wsc_msg(hapd, addr, m1)
7627
7628     logger.debug("Receive M2 from AP")
7629     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7630     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7631     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7632
7633     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7634                                     r_nonce)
7635     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7636
7637     logger.debug("Send M3 to AP")
7638     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7639     attrs += build_attr_msg_type(WPS_M3)
7640     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7641     #attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7642     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7643     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7644     raw_m3_attrs = attrs
7645     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7646     send_wsc_msg(hapd, addr, m3)
7647
7648     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7649
7650 def test_wps_ext_m3_missing_e_hash2(dev, apdev):
7651     """WPS proto: M3 missing E-Hash2"""
7652     pin = "12345670"
7653     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7654     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7655     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7656
7657     logger.debug("Receive WSC/Start from AP")
7658     msg = get_wsc_msg(hapd)
7659     if msg['wsc_opcode'] != WSC_Start:
7660         raise Exception("Unexpected Op-Code for WSC/Start")
7661
7662     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7663     uuid_e = 16*'\x11'
7664     e_nonce = 16*'\x22'
7665     own_private, e_pk = wsc_dh_init()
7666
7667     logger.debug("Send M1 to AP")
7668     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7669                                 e_nonce, e_pk)
7670     send_wsc_msg(hapd, addr, m1)
7671
7672     logger.debug("Receive M2 from AP")
7673     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7674     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7675     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7676
7677     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7678                                     r_nonce)
7679     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7680
7681     logger.debug("Send M3 to AP")
7682     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7683     attrs += build_attr_msg_type(WPS_M3)
7684     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7685     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7686     #attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7687     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7688     raw_m3_attrs = attrs
7689     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7690     send_wsc_msg(hapd, addr, m3)
7691
7692     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7693
7694 def test_wps_ext_m5_missing_e_snonce1(dev, apdev):
7695     """WPS proto: M5 missing E-SNonce1"""
7696     pin = "12345670"
7697     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7698     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7699     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7700
7701     logger.debug("Receive WSC/Start from AP")
7702     msg = get_wsc_msg(hapd)
7703     if msg['wsc_opcode'] != WSC_Start:
7704         raise Exception("Unexpected Op-Code for WSC/Start")
7705
7706     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7707     uuid_e = 16*'\x11'
7708     e_nonce = 16*'\x22'
7709     own_private, e_pk = wsc_dh_init()
7710
7711     logger.debug("Send M1 to AP")
7712     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7713                                 e_nonce, e_pk)
7714     send_wsc_msg(hapd, addr, m1)
7715
7716     logger.debug("Receive M2 from AP")
7717     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7718     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7719     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7720
7721     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7722                                     r_nonce)
7723     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7724
7725     logger.debug("Send M3 to AP")
7726     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7727     attrs += build_attr_msg_type(WPS_M3)
7728     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7729     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7730     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7731     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7732     raw_m3_attrs = attrs
7733     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7734     send_wsc_msg(hapd, addr, m3)
7735
7736     logger.debug("Receive M4 from AP")
7737     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7738
7739     logger.debug("Send M5 to AP")
7740     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7741     attrs += build_attr_msg_type(WPS_M5)
7742     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7743     #data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7744     data = ''
7745     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7746     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7747     raw_m5_attrs = attrs
7748     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7749     send_wsc_msg(hapd, addr, m5)
7750
7751     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7752
7753 def test_wps_ext_m5_e_snonce1_mismatch(dev, apdev):
7754     """WPS proto: M5 E-SNonce1 mismatch"""
7755     pin = "12345670"
7756     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7757     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7758     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7759
7760     logger.debug("Receive WSC/Start from AP")
7761     msg = get_wsc_msg(hapd)
7762     if msg['wsc_opcode'] != WSC_Start:
7763         raise Exception("Unexpected Op-Code for WSC/Start")
7764
7765     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7766     uuid_e = 16*'\x11'
7767     e_nonce = 16*'\x22'
7768     own_private, e_pk = wsc_dh_init()
7769
7770     logger.debug("Send M1 to AP")
7771     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7772                                 e_nonce, e_pk)
7773     send_wsc_msg(hapd, addr, m1)
7774
7775     logger.debug("Receive M2 from AP")
7776     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7777     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7778     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7779
7780     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7781                                     r_nonce)
7782     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7783
7784     logger.debug("Send M3 to AP")
7785     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7786     attrs += build_attr_msg_type(WPS_M3)
7787     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7788     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7789     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7790     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7791     raw_m3_attrs = attrs
7792     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7793     send_wsc_msg(hapd, addr, m3)
7794
7795     logger.debug("Receive M4 from AP")
7796     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7797
7798     logger.debug("Send M5 to AP")
7799     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7800     attrs += build_attr_msg_type(WPS_M5)
7801     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7802     data = build_wsc_attr(ATTR_E_SNONCE1, 16*'\x00')
7803     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7804     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7805     raw_m5_attrs = attrs
7806     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7807     send_wsc_msg(hapd, addr, m5)
7808
7809     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7810
7811 def test_wps_ext_m7_missing_e_snonce2(dev, apdev):
7812     """WPS proto: M7 missing E-SNonce2"""
7813     pin = "12345670"
7814     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7815     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7816     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7817
7818     logger.debug("Receive WSC/Start from AP")
7819     msg = get_wsc_msg(hapd)
7820     if msg['wsc_opcode'] != WSC_Start:
7821         raise Exception("Unexpected Op-Code for WSC/Start")
7822
7823     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7824     uuid_e = 16*'\x11'
7825     e_nonce = 16*'\x22'
7826     own_private, e_pk = wsc_dh_init()
7827
7828     logger.debug("Send M1 to AP")
7829     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7830                                 e_nonce, e_pk)
7831     send_wsc_msg(hapd, addr, m1)
7832
7833     logger.debug("Receive M2 from AP")
7834     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7835     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7836     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7837
7838     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7839                                     r_nonce)
7840     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7841
7842     logger.debug("Send M3 to AP")
7843     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7844     attrs += build_attr_msg_type(WPS_M3)
7845     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7846     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7847     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7848     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7849     raw_m3_attrs = attrs
7850     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7851     send_wsc_msg(hapd, addr, m3)
7852
7853     logger.debug("Receive M4 from AP")
7854     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7855
7856     logger.debug("Send M5 to AP")
7857     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7858     attrs += build_attr_msg_type(WPS_M5)
7859     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7860     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7861     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7862     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7863     raw_m5_attrs = attrs
7864     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7865     send_wsc_msg(hapd, addr, m5)
7866
7867     logger.debug("Receive M6 from AP")
7868     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
7869
7870     logger.debug("Send M7 to AP")
7871     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7872     attrs += build_attr_msg_type(WPS_M7)
7873     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7874     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
7875     data = ''
7876     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7877     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
7878     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7879     raw_m7_attrs = attrs
7880     send_wsc_msg(hapd, addr, m7)
7881
7882     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7883
7884 def test_wps_ext_m7_e_snonce2_mismatch(dev, apdev):
7885     """WPS proto: M7 E-SNonce2 mismatch"""
7886     pin = "12345670"
7887     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7888     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7889     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7890
7891     logger.debug("Receive WSC/Start from AP")
7892     msg = get_wsc_msg(hapd)
7893     if msg['wsc_opcode'] != WSC_Start:
7894         raise Exception("Unexpected Op-Code for WSC/Start")
7895
7896     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7897     uuid_e = 16*'\x11'
7898     e_nonce = 16*'\x22'
7899     own_private, e_pk = wsc_dh_init()
7900
7901     logger.debug("Send M1 to AP")
7902     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7903                                 e_nonce, e_pk)
7904     send_wsc_msg(hapd, addr, m1)
7905
7906     logger.debug("Receive M2 from AP")
7907     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
7908     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
7909     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
7910
7911     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
7912                                     r_nonce)
7913     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
7914
7915     logger.debug("Send M3 to AP")
7916     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7917     attrs += build_attr_msg_type(WPS_M3)
7918     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7919     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
7920     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
7921     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
7922     raw_m3_attrs = attrs
7923     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7924     send_wsc_msg(hapd, addr, m3)
7925
7926     logger.debug("Receive M4 from AP")
7927     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
7928
7929     logger.debug("Send M5 to AP")
7930     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7931     attrs += build_attr_msg_type(WPS_M5)
7932     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7933     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
7934     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7935     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
7936     raw_m5_attrs = attrs
7937     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7938     send_wsc_msg(hapd, addr, m5)
7939
7940     logger.debug("Receive M6 from AP")
7941     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
7942
7943     logger.debug("Send M7 to AP")
7944     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
7945     attrs += build_attr_msg_type(WPS_M7)
7946     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
7947     data = build_wsc_attr(ATTR_E_SNONCE2, 16*'\x00')
7948     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
7949     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
7950     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
7951     raw_m7_attrs = attrs
7952     send_wsc_msg(hapd, addr, m7)
7953
7954     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
7955
7956 def test_wps_ext_m1_pubkey_oom(dev, apdev):
7957     """WPS proto: M1 PubKey OOM"""
7958     pin = "12345670"
7959     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7960     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7961     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7962
7963     logger.debug("Receive WSC/Start from AP")
7964     msg = get_wsc_msg(hapd)
7965     if msg['wsc_opcode'] != WSC_Start:
7966         raise Exception("Unexpected Op-Code for WSC/Start")
7967
7968     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7969     uuid_e = 16*'\x11'
7970     e_nonce = 16*'\x22'
7971     own_private, e_pk = wsc_dh_init()
7972
7973     logger.debug("Send M1 to AP")
7974     with alloc_fail(hapd, 1, "wpabuf_alloc_copy;wps_process_pubkey"):
7975         m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
7976                                     e_nonce, e_pk)
7977         send_wsc_msg(hapd, addr, m1)
7978         wps_wait_eap_failure(hapd, dev[0])
7979
7980 def wps_wait_eap_failure(hapd, dev):
7981     ev = hapd.wait_event(["CTRL-EVENT-EAP-FAILURE"], timeout=5)
7982     if ev is None:
7983         raise Exception("EAP-Failure not reported")
7984     dev.wait_disconnected()
7985
7986 def test_wps_ext_m3_m1(dev, apdev):
7987     """WPS proto: M3 replaced with M1"""
7988     pin = "12345670"
7989     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
7990     wps_ext_eap_identity_req(dev[0], hapd, bssid)
7991     wps_ext_eap_identity_resp(hapd, dev[0], addr)
7992
7993     logger.debug("Receive WSC/Start from AP")
7994     msg = get_wsc_msg(hapd)
7995     if msg['wsc_opcode'] != WSC_Start:
7996         raise Exception("Unexpected Op-Code for WSC/Start")
7997
7998     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
7999     uuid_e = 16*'\x11'
8000     e_nonce = 16*'\x22'
8001     own_private, e_pk = wsc_dh_init()
8002
8003     logger.debug("Send M1 to AP")
8004     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8005                                 e_nonce, e_pk)
8006     send_wsc_msg(hapd, addr, m1)
8007
8008     logger.debug("Receive M2 from AP")
8009     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8010     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8011     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8012
8013     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8014                                     r_nonce)
8015     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8016
8017     logger.debug("Send M3(M1) to AP")
8018     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8019     attrs += build_attr_msg_type(WPS_M1)
8020     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8021     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8022     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8023     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8024     raw_m3_attrs = attrs
8025     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8026     send_wsc_msg(hapd, addr, m3)
8027
8028     wps_wait_eap_failure(hapd, dev[0])
8029
8030 def test_wps_ext_m5_m3(dev, apdev):
8031     """WPS proto: M5 replaced with M3"""
8032     pin = "12345670"
8033     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8034     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8035     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8036
8037     logger.debug("Receive WSC/Start from AP")
8038     msg = get_wsc_msg(hapd)
8039     if msg['wsc_opcode'] != WSC_Start:
8040         raise Exception("Unexpected Op-Code for WSC/Start")
8041
8042     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8043     uuid_e = 16*'\x11'
8044     e_nonce = 16*'\x22'
8045     own_private, e_pk = wsc_dh_init()
8046
8047     logger.debug("Send M1 to AP")
8048     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8049                                 e_nonce, e_pk)
8050     send_wsc_msg(hapd, addr, m1)
8051
8052     logger.debug("Receive M2 from AP")
8053     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8054     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8055     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8056
8057     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8058                                     r_nonce)
8059     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8060
8061     logger.debug("Send M3 to AP")
8062     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8063     attrs += build_attr_msg_type(WPS_M3)
8064     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8065     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8066     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8067     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8068     raw_m3_attrs = attrs
8069     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8070     send_wsc_msg(hapd, addr, m3)
8071
8072     logger.debug("Receive M4 from AP")
8073     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8074
8075     logger.debug("Send M5(M3) to AP")
8076     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8077     attrs += build_attr_msg_type(WPS_M3)
8078     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8079     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8080     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8081     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8082     raw_m5_attrs = attrs
8083     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8084     send_wsc_msg(hapd, addr, m5)
8085
8086     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8087
8088 def test_wps_ext_m3_m2(dev, apdev):
8089     """WPS proto: M3 replaced with M2"""
8090     pin = "12345670"
8091     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8092     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8093     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8094
8095     logger.debug("Receive WSC/Start from AP")
8096     msg = get_wsc_msg(hapd)
8097     if msg['wsc_opcode'] != WSC_Start:
8098         raise Exception("Unexpected Op-Code for WSC/Start")
8099
8100     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8101     uuid_e = 16*'\x11'
8102     e_nonce = 16*'\x22'
8103     own_private, e_pk = wsc_dh_init()
8104
8105     logger.debug("Send M1 to AP")
8106     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8107                                 e_nonce, e_pk)
8108     send_wsc_msg(hapd, addr, m1)
8109
8110     logger.debug("Receive M2 from AP")
8111     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8112     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8113     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8114
8115     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8116                                     r_nonce)
8117     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8118
8119     logger.debug("Send M3(M2) to AP")
8120     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8121     attrs += build_attr_msg_type(WPS_M2)
8122     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8123     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8124     raw_m3_attrs = attrs
8125     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8126     send_wsc_msg(hapd, addr, m3)
8127
8128     wps_wait_eap_failure(hapd, dev[0])
8129
8130 def test_wps_ext_m3_m5(dev, apdev):
8131     """WPS proto: M3 replaced with M5"""
8132     pin = "12345670"
8133     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8134     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8135     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8136
8137     logger.debug("Receive WSC/Start from AP")
8138     msg = get_wsc_msg(hapd)
8139     if msg['wsc_opcode'] != WSC_Start:
8140         raise Exception("Unexpected Op-Code for WSC/Start")
8141
8142     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8143     uuid_e = 16*'\x11'
8144     e_nonce = 16*'\x22'
8145     own_private, e_pk = wsc_dh_init()
8146
8147     logger.debug("Send M1 to AP")
8148     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8149                                 e_nonce, e_pk)
8150     send_wsc_msg(hapd, addr, m1)
8151
8152     logger.debug("Receive M2 from AP")
8153     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8154     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8155     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8156
8157     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8158                                     r_nonce)
8159     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8160
8161     logger.debug("Send M3(M5) to AP")
8162     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8163     attrs += build_attr_msg_type(WPS_M5)
8164     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8165     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8166     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8167     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8168     raw_m3_attrs = attrs
8169     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8170     send_wsc_msg(hapd, addr, m3)
8171
8172     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8173
8174 def test_wps_ext_m3_m7(dev, apdev):
8175     """WPS proto: M3 replaced with M7"""
8176     pin = "12345670"
8177     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8178     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8179     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8180
8181     logger.debug("Receive WSC/Start from AP")
8182     msg = get_wsc_msg(hapd)
8183     if msg['wsc_opcode'] != WSC_Start:
8184         raise Exception("Unexpected Op-Code for WSC/Start")
8185
8186     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8187     uuid_e = 16*'\x11'
8188     e_nonce = 16*'\x22'
8189     own_private, e_pk = wsc_dh_init()
8190
8191     logger.debug("Send M1 to AP")
8192     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8193                                 e_nonce, e_pk)
8194     send_wsc_msg(hapd, addr, m1)
8195
8196     logger.debug("Receive M2 from AP")
8197     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8198     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8199     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8200
8201     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8202                                     r_nonce)
8203     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8204
8205     logger.debug("Send M3(M7) to AP")
8206     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8207     attrs += build_attr_msg_type(WPS_M7)
8208     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8209     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8210     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8211     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8212     raw_m3_attrs = attrs
8213     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8214     send_wsc_msg(hapd, addr, m3)
8215
8216     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8217
8218 def test_wps_ext_m3_done(dev, apdev):
8219     """WPS proto: M3 replaced with WSC_Done"""
8220     pin = "12345670"
8221     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8222     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8223     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8224
8225     logger.debug("Receive WSC/Start from AP")
8226     msg = get_wsc_msg(hapd)
8227     if msg['wsc_opcode'] != WSC_Start:
8228         raise Exception("Unexpected Op-Code for WSC/Start")
8229
8230     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8231     uuid_e = 16*'\x11'
8232     e_nonce = 16*'\x22'
8233     own_private, e_pk = wsc_dh_init()
8234
8235     logger.debug("Send M1 to AP")
8236     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8237                                 e_nonce, e_pk)
8238     send_wsc_msg(hapd, addr, m1)
8239
8240     logger.debug("Receive M2 from AP")
8241     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8242     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8243     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8244
8245     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8246                                     r_nonce)
8247     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8248
8249     logger.debug("Send M3(WSC_Done) to AP")
8250     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8251     attrs += build_attr_msg_type(WPS_WSC_DONE)
8252     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8253     raw_m3_attrs = attrs
8254     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8255     send_wsc_msg(hapd, addr, m3)
8256
8257     wps_wait_eap_failure(hapd, dev[0])
8258
8259 def test_wps_ext_m2_nack_invalid(dev, apdev):
8260     """WPS proto: M2 followed by invalid NACK"""
8261     pin = "12345670"
8262     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8263     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8264     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8265
8266     logger.debug("Receive WSC/Start from AP")
8267     msg = get_wsc_msg(hapd)
8268     if msg['wsc_opcode'] != WSC_Start:
8269         raise Exception("Unexpected Op-Code for WSC/Start")
8270
8271     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8272     uuid_e = 16*'\x11'
8273     e_nonce = 16*'\x22'
8274     own_private, e_pk = wsc_dh_init()
8275
8276     logger.debug("Send M1 to AP")
8277     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8278                                 e_nonce, e_pk)
8279     send_wsc_msg(hapd, addr, m1)
8280
8281     logger.debug("Receive M2 from AP")
8282     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8283     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8284     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8285
8286     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8287                                     r_nonce)
8288     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8289
8290     logger.debug("Send WSC_NACK to AP")
8291     attrs = '\x10\x00\x00'
8292     nack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_NACK)
8293     send_wsc_msg(hapd, addr, nack)
8294
8295     wps_wait_eap_failure(hapd, dev[0])
8296
8297 def test_wps_ext_m2_nack_no_msg_type(dev, apdev):
8298     """WPS proto: M2 followed by NACK without Msg Type"""
8299     pin = "12345670"
8300     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8301     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8302     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8303
8304     logger.debug("Receive WSC/Start from AP")
8305     msg = get_wsc_msg(hapd)
8306     if msg['wsc_opcode'] != WSC_Start:
8307         raise Exception("Unexpected Op-Code for WSC/Start")
8308
8309     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8310     uuid_e = 16*'\x11'
8311     e_nonce = 16*'\x22'
8312     own_private, e_pk = wsc_dh_init()
8313
8314     logger.debug("Send M1 to AP")
8315     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8316                                 e_nonce, e_pk)
8317     send_wsc_msg(hapd, addr, m1)
8318
8319     logger.debug("Receive M2 from AP")
8320     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8321     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8322     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8323
8324     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8325                                     r_nonce)
8326     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8327
8328     logger.debug("Send WSC_NACK to AP")
8329     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8330                             msg_type=None, eap_code=2)
8331     send_wsc_msg(hapd, addr, nack)
8332
8333     wps_wait_eap_failure(hapd, dev[0])
8334
8335 def test_wps_ext_m2_nack_invalid_msg_type(dev, apdev):
8336     """WPS proto: M2 followed by NACK with invalid Msg Type"""
8337     pin = "12345670"
8338     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8339     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8340     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8341
8342     logger.debug("Receive WSC/Start from AP")
8343     msg = get_wsc_msg(hapd)
8344     if msg['wsc_opcode'] != WSC_Start:
8345         raise Exception("Unexpected Op-Code for WSC/Start")
8346
8347     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8348     uuid_e = 16*'\x11'
8349     e_nonce = 16*'\x22'
8350     own_private, e_pk = wsc_dh_init()
8351
8352     logger.debug("Send M1 to AP")
8353     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8354                                 e_nonce, e_pk)
8355     send_wsc_msg(hapd, addr, m1)
8356
8357     logger.debug("Receive M2 from AP")
8358     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8359     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8360     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8361
8362     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8363                                     r_nonce)
8364     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8365
8366     logger.debug("Send WSC_NACK to AP")
8367     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8368                             msg_type=WPS_WSC_ACK, eap_code=2)
8369     send_wsc_msg(hapd, addr, nack)
8370
8371     wps_wait_eap_failure(hapd, dev[0])
8372
8373 def test_wps_ext_m2_nack_e_nonce_mismatch(dev, apdev):
8374     """WPS proto: M2 followed by NACK with e-nonce mismatch"""
8375     pin = "12345670"
8376     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8377     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8378     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8379
8380     logger.debug("Receive WSC/Start from AP")
8381     msg = get_wsc_msg(hapd)
8382     if msg['wsc_opcode'] != WSC_Start:
8383         raise Exception("Unexpected Op-Code for WSC/Start")
8384
8385     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8386     uuid_e = 16*'\x11'
8387     e_nonce = 16*'\x22'
8388     own_private, e_pk = wsc_dh_init()
8389
8390     logger.debug("Send M1 to AP")
8391     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8392                                 e_nonce, e_pk)
8393     send_wsc_msg(hapd, addr, m1)
8394
8395     logger.debug("Receive M2 from AP")
8396     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8397     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8398     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8399
8400     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8401                                     r_nonce)
8402     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8403
8404     logger.debug("Send WSC_NACK to AP")
8405     nack,attrs = build_nack(msg['eap_identifier'], 16*'\x00', r_nonce,
8406                             eap_code=2)
8407     send_wsc_msg(hapd, addr, nack)
8408
8409     wps_wait_eap_failure(hapd, dev[0])
8410
8411 def test_wps_ext_m2_nack_no_config_error(dev, apdev):
8412     """WPS proto: M2 followed by NACK without Config Error"""
8413     pin = "12345670"
8414     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8415     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8416     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8417
8418     logger.debug("Receive WSC/Start from AP")
8419     msg = get_wsc_msg(hapd)
8420     if msg['wsc_opcode'] != WSC_Start:
8421         raise Exception("Unexpected Op-Code for WSC/Start")
8422
8423     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8424     uuid_e = 16*'\x11'
8425     e_nonce = 16*'\x22'
8426     own_private, e_pk = wsc_dh_init()
8427
8428     logger.debug("Send M1 to AP")
8429     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8430                                 e_nonce, e_pk)
8431     send_wsc_msg(hapd, addr, m1)
8432
8433     logger.debug("Receive M2 from AP")
8434     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8435     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8436     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8437
8438     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8439                                     r_nonce)
8440     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8441
8442     logger.debug("Send WSC_NACK to AP")
8443     nack,attrs = build_nack(msg['eap_identifier'], e_nonce, r_nonce,
8444                             config_error=None, eap_code=2)
8445     send_wsc_msg(hapd, addr, nack)
8446
8447     wps_wait_eap_failure(hapd, dev[0])
8448
8449 def test_wps_ext_m2_ack_invalid(dev, apdev):
8450     """WPS proto: M2 followed by invalid ACK"""
8451     pin = "12345670"
8452     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8453     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8454     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8455
8456     logger.debug("Receive WSC/Start from AP")
8457     msg = get_wsc_msg(hapd)
8458     if msg['wsc_opcode'] != WSC_Start:
8459         raise Exception("Unexpected Op-Code for WSC/Start")
8460
8461     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8462     uuid_e = 16*'\x11'
8463     e_nonce = 16*'\x22'
8464     own_private, e_pk = wsc_dh_init()
8465
8466     logger.debug("Send M1 to AP")
8467     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8468                                 e_nonce, e_pk)
8469     send_wsc_msg(hapd, addr, m1)
8470
8471     logger.debug("Receive M2 from AP")
8472     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8473     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8474     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8475
8476     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8477                                     r_nonce)
8478     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8479
8480     logger.debug("Send WSC_ACK to AP")
8481     attrs = '\x10\x00\x00'
8482     ack = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_ACK)
8483     send_wsc_msg(hapd, addr, ack)
8484
8485     wps_wait_eap_failure(hapd, dev[0])
8486
8487 def test_wps_ext_m2_ack(dev, apdev):
8488     """WPS proto: M2 followed by ACK"""
8489     pin = "12345670"
8490     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8491     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8492     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8493
8494     logger.debug("Receive WSC/Start from AP")
8495     msg = get_wsc_msg(hapd)
8496     if msg['wsc_opcode'] != WSC_Start:
8497         raise Exception("Unexpected Op-Code for WSC/Start")
8498
8499     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8500     uuid_e = 16*'\x11'
8501     e_nonce = 16*'\x22'
8502     own_private, e_pk = wsc_dh_init()
8503
8504     logger.debug("Send M1 to AP")
8505     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8506                                 e_nonce, e_pk)
8507     send_wsc_msg(hapd, addr, m1)
8508
8509     logger.debug("Receive M2 from AP")
8510     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8511     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8512     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8513
8514     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8515                                     r_nonce)
8516     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8517
8518     logger.debug("Send WSC_ACK to AP")
8519     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce, eap_code=2)
8520     send_wsc_msg(hapd, addr, ack)
8521
8522     wps_wait_eap_failure(hapd, dev[0])
8523
8524 def test_wps_ext_m2_ack_no_msg_type(dev, apdev):
8525     """WPS proto: M2 followed by ACK missing Msg Type"""
8526     pin = "12345670"
8527     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8528     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8529     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8530
8531     logger.debug("Receive WSC/Start from AP")
8532     msg = get_wsc_msg(hapd)
8533     if msg['wsc_opcode'] != WSC_Start:
8534         raise Exception("Unexpected Op-Code for WSC/Start")
8535
8536     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8537     uuid_e = 16*'\x11'
8538     e_nonce = 16*'\x22'
8539     own_private, e_pk = wsc_dh_init()
8540
8541     logger.debug("Send M1 to AP")
8542     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8543                                 e_nonce, e_pk)
8544     send_wsc_msg(hapd, addr, m1)
8545
8546     logger.debug("Receive M2 from AP")
8547     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8548     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8549     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8550
8551     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8552                                     r_nonce)
8553     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8554
8555     logger.debug("Send WSC_ACK to AP")
8556     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8557                           msg_type=None, eap_code=2)
8558     send_wsc_msg(hapd, addr, ack)
8559
8560     wps_wait_eap_failure(hapd, dev[0])
8561
8562 def test_wps_ext_m2_ack_invalid_msg_type(dev, apdev):
8563     """WPS proto: M2 followed by ACK with invalid Msg Type"""
8564     pin = "12345670"
8565     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8566     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8567     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8568
8569     logger.debug("Receive WSC/Start from AP")
8570     msg = get_wsc_msg(hapd)
8571     if msg['wsc_opcode'] != WSC_Start:
8572         raise Exception("Unexpected Op-Code for WSC/Start")
8573
8574     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8575     uuid_e = 16*'\x11'
8576     e_nonce = 16*'\x22'
8577     own_private, e_pk = wsc_dh_init()
8578
8579     logger.debug("Send M1 to AP")
8580     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8581                                 e_nonce, e_pk)
8582     send_wsc_msg(hapd, addr, m1)
8583
8584     logger.debug("Receive M2 from AP")
8585     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8586     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8587     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8588
8589     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8590                                     r_nonce)
8591     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8592
8593     logger.debug("Send WSC_ACK to AP")
8594     ack,attrs = build_ack(msg['eap_identifier'], e_nonce, r_nonce,
8595                           msg_type=WPS_WSC_NACK, eap_code=2)
8596     send_wsc_msg(hapd, addr, ack)
8597
8598     wps_wait_eap_failure(hapd, dev[0])
8599
8600 def test_wps_ext_m2_ack_e_nonce_mismatch(dev, apdev):
8601     """WPS proto: M2 followed by ACK with e-nonce mismatch"""
8602     pin = "12345670"
8603     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8604     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8605     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8606
8607     logger.debug("Receive WSC/Start from AP")
8608     msg = get_wsc_msg(hapd)
8609     if msg['wsc_opcode'] != WSC_Start:
8610         raise Exception("Unexpected Op-Code for WSC/Start")
8611
8612     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8613     uuid_e = 16*'\x11'
8614     e_nonce = 16*'\x22'
8615     own_private, e_pk = wsc_dh_init()
8616
8617     logger.debug("Send M1 to AP")
8618     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8619                                 e_nonce, e_pk)
8620     send_wsc_msg(hapd, addr, m1)
8621
8622     logger.debug("Receive M2 from AP")
8623     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8624     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8625     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8626
8627     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8628                                     r_nonce)
8629     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8630
8631     logger.debug("Send WSC_ACK to AP")
8632     ack,attrs = build_ack(msg['eap_identifier'], 16*'\x00', r_nonce,
8633                           eap_code=2)
8634     send_wsc_msg(hapd, addr, ack)
8635
8636     wps_wait_eap_failure(hapd, dev[0])
8637
8638 def test_wps_ext_m1_invalid(dev, apdev):
8639     """WPS proto: M1 failing parsing"""
8640     pin = "12345670"
8641     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8642     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8643     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8644
8645     logger.debug("Receive WSC/Start from AP")
8646     msg = get_wsc_msg(hapd)
8647     if msg['wsc_opcode'] != WSC_Start:
8648         raise Exception("Unexpected Op-Code for WSC/Start")
8649
8650     logger.debug("Send M1 to AP")
8651     attrs = '\x10\x00\x00'
8652     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8653     send_wsc_msg(hapd, addr, m1)
8654
8655     wps_wait_eap_failure(hapd, dev[0])
8656
8657 def test_wps_ext_m1_missing_msg_type(dev, apdev):
8658     """WPS proto: M1 missing Msg Type"""
8659     pin = "12345670"
8660     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8661     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8662     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8663
8664     logger.debug("Receive WSC/Start from AP")
8665     msg = get_wsc_msg(hapd)
8666     if msg['wsc_opcode'] != WSC_Start:
8667         raise Exception("Unexpected Op-Code for WSC/Start")
8668
8669     logger.debug("Send M1 to AP")
8670     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8671     m1 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8672     send_wsc_msg(hapd, addr, m1)
8673
8674     wps_wait_ap_nack(hapd, dev[0], 16*'\x00', 16*'\x00')
8675
8676 def wps_ext_wsc_done(dev, apdev):
8677     pin = "12345670"
8678     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8679     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8680     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8681
8682     logger.debug("Receive WSC/Start from AP")
8683     msg = get_wsc_msg(hapd)
8684     if msg['wsc_opcode'] != WSC_Start:
8685         raise Exception("Unexpected Op-Code for WSC/Start")
8686
8687     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8688     uuid_e = 16*'\x11'
8689     e_nonce = 16*'\x22'
8690     own_private, e_pk = wsc_dh_init()
8691
8692     logger.debug("Send M1 to AP")
8693     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8694                                 e_nonce, e_pk)
8695     send_wsc_msg(hapd, addr, m1)
8696
8697     logger.debug("Receive M2 from AP")
8698     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8699     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8700     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8701
8702     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8703                                     r_nonce)
8704     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8705
8706     logger.debug("Send M3 to AP")
8707     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8708     attrs += build_attr_msg_type(WPS_M3)
8709     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8710     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8711     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8712     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8713     raw_m3_attrs = attrs
8714     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8715     send_wsc_msg(hapd, addr, m3)
8716
8717     logger.debug("Receive M4 from AP")
8718     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8719
8720     logger.debug("Send M5 to AP")
8721     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8722     attrs += build_attr_msg_type(WPS_M5)
8723     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8724     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8725     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8726     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8727     raw_m5_attrs = attrs
8728     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8729     send_wsc_msg(hapd, addr, m5)
8730
8731     logger.debug("Receive M6 from AP")
8732     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8733
8734     logger.debug("Send M7 to AP")
8735     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8736     attrs += build_attr_msg_type(WPS_M7)
8737     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8738     data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8739     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8740     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8741     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8742     raw_m7_attrs = attrs
8743     send_wsc_msg(hapd, addr, m7)
8744
8745     logger.debug("Receive M8 from AP")
8746     msg, m8_attrs, raw_m8_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M8)
8747     return hapd, msg, e_nonce, r_nonce
8748
8749 def test_wps_ext_wsc_done_invalid(dev, apdev):
8750     """WPS proto: invalid WSC_Done"""
8751     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8752
8753     logger.debug("Send WSC_Done to AP")
8754     attrs = '\x10\x00\x00'
8755     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8756     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8757
8758     wps_wait_eap_failure(hapd, dev[0])
8759
8760 def test_wps_ext_wsc_done_no_msg_type(dev, apdev):
8761     """WPS proto: invalid WSC_Done"""
8762     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8763
8764     logger.debug("Send WSC_Done to AP")
8765     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8766     #attrs += build_attr_msg_type(WPS_WSC_DONE)
8767     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8768     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8769     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8770     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8771
8772     wps_wait_eap_failure(hapd, dev[0])
8773
8774 def test_wps_ext_wsc_done_wrong_msg_type(dev, apdev):
8775     """WPS proto: WSC_Done with wrong Msg Type"""
8776     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8777
8778     logger.debug("Send WSC_Done to AP")
8779     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8780     attrs += build_attr_msg_type(WPS_WSC_ACK)
8781     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8782     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8783     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8784     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8785
8786     wps_wait_eap_failure(hapd, dev[0])
8787
8788 def test_wps_ext_wsc_done_no_e_nonce(dev, apdev):
8789     """WPS proto: WSC_Done without e_nonce"""
8790     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8791
8792     logger.debug("Send WSC_Done to AP")
8793     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8794     attrs += build_attr_msg_type(WPS_WSC_DONE)
8795     #attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8796     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8797     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8798     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8799
8800     wps_wait_eap_failure(hapd, dev[0])
8801
8802 def test_wps_ext_wsc_done_no_r_nonce(dev, apdev):
8803     """WPS proto: WSC_Done without r_nonce"""
8804     hapd, msg, e_nonce, r_nonce = wps_ext_wsc_done(dev, apdev)
8805
8806     logger.debug("Send WSC_Done to AP")
8807     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8808     attrs += build_attr_msg_type(WPS_WSC_DONE)
8809     attrs += build_wsc_attr(ATTR_ENROLLEE_NONCE, e_nonce)
8810     #attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8811     wsc_done = build_eap_wsc(2, msg['eap_identifier'], attrs, opcode=WSC_Done)
8812     send_wsc_msg(hapd, dev[0].own_addr(), wsc_done)
8813
8814     wps_wait_eap_failure(hapd, dev[0])
8815
8816 def test_wps_ext_m7_no_encr_settings(dev, apdev):
8817     """WPS proto: M7 without Encr Settings"""
8818     pin = "12345670"
8819     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8820     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8821     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8822
8823     logger.debug("Receive WSC/Start from AP")
8824     msg = get_wsc_msg(hapd)
8825     if msg['wsc_opcode'] != WSC_Start:
8826         raise Exception("Unexpected Op-Code for WSC/Start")
8827
8828     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8829     uuid_e = 16*'\x11'
8830     e_nonce = 16*'\x22'
8831     own_private, e_pk = wsc_dh_init()
8832
8833     logger.debug("Send M1 to AP")
8834     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8835                                 e_nonce, e_pk)
8836     send_wsc_msg(hapd, addr, m1)
8837
8838     logger.debug("Receive M2 from AP")
8839     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)
8840     r_nonce = m2_attrs[ATTR_REGISTRAR_NONCE]
8841     r_pk = m2_attrs[ATTR_PUBLIC_KEY]
8842
8843     authkey,keywrapkey = wsc_dh_kdf(r_pk, own_private, mac_addr, e_nonce,
8844                                     r_nonce)
8845     e_s1,e_s2,e_hash1,e_hash2 = wsc_dev_pw_hash(authkey, pin, e_pk, r_pk)
8846
8847     logger.debug("Send M3 to AP")
8848     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8849     attrs += build_attr_msg_type(WPS_M3)
8850     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8851     attrs += build_wsc_attr(ATTR_E_HASH1, e_hash1)
8852     attrs += build_wsc_attr(ATTR_E_HASH2, e_hash2)
8853     attrs += build_attr_authenticator(authkey, raw_m2_attrs, attrs)
8854     raw_m3_attrs = attrs
8855     m3 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8856     send_wsc_msg(hapd, addr, m3)
8857
8858     logger.debug("Receive M4 from AP")
8859     msg, m4_attrs, raw_m4_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M4)
8860
8861     logger.debug("Send M5 to AP")
8862     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8863     attrs += build_attr_msg_type(WPS_M5)
8864     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8865     data = build_wsc_attr(ATTR_E_SNONCE1, e_s1)
8866     attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8867     attrs += build_attr_authenticator(authkey, raw_m4_attrs, attrs)
8868     raw_m5_attrs = attrs
8869     m5 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8870     send_wsc_msg(hapd, addr, m5)
8871
8872     logger.debug("Receive M6 from AP")
8873     msg, m6_attrs, raw_m6_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M6)
8874
8875     logger.debug("Send M7 to AP")
8876     attrs = build_wsc_attr(ATTR_VERSION, '\x10')
8877     attrs += build_attr_msg_type(WPS_M7)
8878     attrs += build_wsc_attr(ATTR_REGISTRAR_NONCE, r_nonce)
8879     #data = build_wsc_attr(ATTR_E_SNONCE2, e_s2)
8880     #attrs += build_attr_encr_settings(authkey, keywrapkey, data)
8881     attrs += build_attr_authenticator(authkey, raw_m6_attrs, attrs)
8882     m7 = build_eap_wsc(2, msg['eap_identifier'], attrs)
8883     raw_m7_attrs = attrs
8884     send_wsc_msg(hapd, addr, m7)
8885
8886     wps_wait_ap_nack(hapd, dev[0], e_nonce, r_nonce)
8887
8888 def test_wps_ext_m1_workaround(dev, apdev):
8889     """WPS proto: M1 Manufacturer/Model workaround"""
8890     pin = "12345670"
8891     addr,bssid,hapd = wps_start_ext(apdev[0], dev[0], pin=pin)
8892     wps_ext_eap_identity_req(dev[0], hapd, bssid)
8893     wps_ext_eap_identity_resp(hapd, dev[0], addr)
8894
8895     logger.debug("Receive WSC/Start from AP")
8896     msg = get_wsc_msg(hapd)
8897     if msg['wsc_opcode'] != WSC_Start:
8898         raise Exception("Unexpected Op-Code for WSC/Start")
8899
8900     mac_addr = binascii.unhexlify(dev[0].own_addr().replace(':', ''))
8901     uuid_e = 16*'\x11'
8902     e_nonce = 16*'\x22'
8903     own_private, e_pk = wsc_dh_init()
8904
8905     logger.debug("Send M1 to AP")
8906     m1, raw_m1_attrs = build_m1(msg['eap_identifier'], uuid_e, mac_addr,
8907                                 e_nonce, e_pk, manufacturer='Apple TEST',
8908                                 model_name='AirPort', config_methods='\xff\xff')
8909     send_wsc_msg(hapd, addr, m1)
8910
8911     logger.debug("Receive M2 from AP")
8912     msg, m2_attrs, raw_m2_attrs = recv_wsc_msg(hapd, WSC_MSG, WPS_M2)