1# Test cases for Device Provisioning Protocol (DPP) version 3
2# Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc.
3#
4# This software may be distributed under the terms of the BSD license.
5# See README for more details.
6
7import binascii
8import os
9import time
10
11import hostapd
12from wlantest import WlantestCapture
13from test_dpp import check_dpp_capab, run_dpp_auto_connect, wait_auth_success, update_hapd_config, params1_ap_connector, params1_csign, params1_ap_netaccesskey, params1_sta_connector, params1_sta_connector, params1_sta_netaccesskey
14from utils import *
15
16def test_dpp_network_intro_version(dev, apdev):
17    """DPP Network Introduction and protocol version"""
18    check_dpp_capab(dev[0], min_ver=3)
19
20    try:
21        id, hapd = run_dpp_auto_connect(dev, apdev, 1, stop_after_prov=True)
22        dev[0].select_network(id, freq=2412)
23        dev[0].wait_connected()
24    finally:
25        dev[0].set("dpp_config_processing", "0", allow_fail=True)
26
27def test_dpp_network_intro_version_change(dev, apdev):
28    """DPP Network Introduction and protocol version change"""
29    check_dpp_capab(dev[0], min_ver=3)
30
31    try:
32        dev[0].set("dpp_version_override", "2")
33        id, hapd = run_dpp_auto_connect(dev, apdev, 1, stop_after_prov=True)
34        dev[0].set("dpp_version_override", "3")
35        dev[0].select_network(id, freq=2412)
36        dev[0].wait_connected()
37    finally:
38        dev[0].set("dpp_config_processing", "0", allow_fail=True)
39
40def test_dpp_network_intro_version_missing_req(dev, apdev):
41    """DPP Network Introduction and protocol version missing from request"""
42    check_dpp_capab(dev[0], min_ver=3)
43
44    try:
45        dev[0].set("dpp_version_override", "2")
46        id, hapd = run_dpp_auto_connect(dev, apdev, 1, stop_after_prov=True)
47        dev[0].set("dpp_version_override", "3")
48        dev[0].set("dpp_test", "92")
49        dev[0].select_network(id, freq=2412)
50        ev = dev[0].wait_event(["DPP-INTRO"], timeout=10)
51        if ev is None:
52            raise Exception("DPP network introduction result not seen on STA")
53        if "status=8" not in ev:
54            raise Exception("Unexpected network introduction result on STA: " + ev)
55    finally:
56        dev[0].set("dpp_config_processing", "0", allow_fail=True)
57
58def run_dpp_tcp_pkex(dev0, dev1, cap_lo, sae=False, status=False):
59    check_dpp_capab(dev0, min_ver=3)
60    check_dpp_capab(dev1, min_ver=3)
61
62    with WlantestCapture('lo', cap_lo):
63        run_dpp_tcp_pkex2(dev0, dev1, cap_lo, sae, status)
64
65def run_dpp_tcp_pkex2(dev0, dev1, cap_lo, sae=False, status=False):
66    # Controller
67    if sae:
68        ssid = binascii.hexlify("sae".encode()).decode()
69        password = binascii.hexlify("sae-password".encode()).decode()
70        val = "conf=sta-sae ssid=%s pass=%s" % (ssid, password)
71        if status:
72            val += " conn_status=1"
73        dev1.set("dpp_configurator_params", val)
74    else:
75        conf_id = dev1.dpp_configurator_add()
76        dev1.set("dpp_configurator_params",
77                 "conf=sta-dpp configurator=%d" % conf_id)
78
79    req = "DPP_CONTROLLER_START"
80    own = None
81    if "OK" not in dev1.request(req):
82        raise Exception("Failed to start Controller")
83
84    code = "secret"
85
86    id1 = dev1.dpp_bootstrap_gen(type="pkex")
87    cmd = "own=%d" % id1
88    cmd += " code=%s" % code
89    res = dev1.request("DPP_PKEX_ADD " + cmd)
90    if "FAIL" in res:
91        raise Exception("Failed to set PKEX data (responder)")
92
93    dev0.dpp_pkex_init(identifier=None, code=code, role="enrollee",
94                       tcp_addr="127.0.0.1")
95
96    res = wait_auth_success(dev1, dev0, configurator=dev1, enrollee=dev0,
97                            allow_enrollee_failure=True,
98                            allow_configurator_failure=True)
99    if status:
100        if 'wait_conn_status' not in res or not res['wait_conn_status']:
101            raise Exception("wait_conn_status not reported")
102
103def test_dpp_tcp_pkex(dev, apdev, params):
104    """DPP/PKEXv2 over TCP"""
105    prefix = "dpp_tcp_pkex"
106    cap_lo = os.path.join(params['logdir'], prefix + ".lo.pcap")
107    try:
108        run_dpp_tcp_pkex(dev[0], dev[1], cap_lo)
109    finally:
110        dev[1].request("DPP_CONTROLLER_STOP")
111
112def run_dpp_tcp_pkex_auto_connect_2(dev, apdev, params, status, start_ap=True):
113    check_dpp_capab(dev[0], min_ver=3)
114    check_sae_capab(dev[0])
115    dev[0].set("sae_groups", "")
116
117    cap_lo = params['prefix'] + ".lo.pcap"
118
119    params = {"ssid": "sae",
120              "wpa": "2",
121              "wpa_key_mgmt": "SAE",
122              "ieee80211w": "2",
123              "rsn_pairwise": "CCMP",
124              "sae_password": "sae-password"}
125    if start_ap:
126        hapd = hostapd.add_ap(apdev[0], params)
127    try:
128        dev[0].set("dpp_config_processing", "2")
129        run_dpp_tcp_pkex(dev[0], dev[1], cap_lo, sae=True, status=status)
130        if start_ap:
131            dev[0].wait_connected()
132        if status:
133            ev = dev[1].wait_event(["DPP-CONN-STATUS-RESULT"], timeout=16)
134            if ev is None:
135                raise Exception("Connection status resutl not reported")
136            if start_ap and "result=0" not in ev:
137                raise Exception("Unexpected result in success case: " + ev)
138            if (not start_ap) and "result=10" not in ev:
139                raise Exception("Unexpected result in failure case: " + ev)
140            if "ssid=sae " not in ev:
141                raise Exception("Missing SSID: " + ssid)
142    finally:
143        dev[0].set("dpp_config_processing", "0", allow_fail=True)
144        dev[1].request("DPP_CONTROLLER_STOP")
145
146def test_dpp_tcp_pkex_auto_connect_2(dev, apdev, params):
147    """DPP/PKEXv2 over TCP and automatic connection"""
148    run_dpp_tcp_pkex_auto_connect_2(dev, apdev, params, False)
149
150def test_dpp_tcp_pkex_auto_connect_2_status(dev, apdev, params):
151    """DPP/PKEXv2 over TCP and automatic connection status"""
152    run_dpp_tcp_pkex_auto_connect_2(dev, apdev, params, True)
153
154def test_dpp_tcp_pkex_auto_connect_2_status_fail(dev, apdev, params):
155    """DPP/PKEXv2 over TCP and automatic connection status for failure"""
156    run_dpp_tcp_pkex_auto_connect_2(dev, apdev, params, True, start_ap=False)
157
158def test_dpp_tcp_pkex_while_associated(dev, apdev, params):
159    """DPP/PKEXv2 over TCP while associated"""
160    try:
161        run_dpp_tcp_pkex_while_associated(dev, apdev, params, False)
162    finally:
163        dev[1].request("DPP_CONTROLLER_STOP")
164        dev[0].set("dpp_config_processing", "0", allow_fail=True)
165
166def test_dpp_tcp_pkex_while_associated_conn_status(dev, apdev, params):
167    """DPP/PKEXv2 over TCP while associated (conn status)"""
168    try:
169        run_dpp_tcp_pkex_while_associated(dev, apdev, params, True)
170    finally:
171        dev[1].request("DPP_CONTROLLER_STOP")
172        dev[0].set("dpp_config_processing", "0", allow_fail=True)
173
174def run_dpp_tcp_pkex_while_associated(dev, apdev, params, status):
175    check_dpp_capab(dev[0], min_ver=3)
176    check_sae_capab(dev[0])
177    cap_lo = params['prefix'] + ".lo.pcap"
178
179    params = {"ssid": "current",
180              "wpa": "2",
181              "wpa_key_mgmt": "SAE",
182              "ieee80211w": "2",
183              "rsn_pairwise": "CCMP",
184              "sae_password": "password"}
185    hapd = hostapd.add_ap(apdev[0], params)
186
187    params = {"ssid": "sae",
188              "wpa": "2",
189              "wpa_key_mgmt": "SAE",
190              "ieee80211w": "2",
191              "rsn_pairwise": "CCMP",
192              "sae_password": "sae-password"}
193    hapd2 = hostapd.add_ap(apdev[1], params)
194
195    dev[0].set("dpp_config_processing", "2")
196    dev[0].set("sae_groups", "")
197    dev[0].connect("current", psk="password", key_mgmt="SAE", ieee80211w="2",
198                   scan_freq="2412")
199    run_dpp_tcp_pkex(dev[0], dev[1], cap_lo, sae=True, status=status)
200    if status:
201        ev = dev[1].wait_event(["DPP-CONN-STATUS-RESULT"], timeout=16)
202        if ev is None:
203            raise Exception("Connection status result not reported")
204        if "result=0" not in ev:
205            raise Exception("Unexpected result in success case: " + ev)
206    dev[0].wait_connected(timeout=30)
207
208def test_dpp_controller_relay_pkex(dev, apdev, params):
209    """DPP Controller/Relay with PKEX"""
210    try:
211        run_dpp_controller_relay_pkex(dev, apdev, params)
212    finally:
213        dev[0].set("dpp_config_processing", "0", allow_fail=True)
214        dev[1].request("DPP_CONTROLLER_STOP")
215
216def run_dpp_controller_relay_pkex(dev, apdev, params):
217    check_dpp_capab(dev[0], min_ver=3)
218    check_dpp_capab(dev[1], min_ver=3)
219    prefix = "dpp_controller_relay_pkex"
220    cap_lo = os.path.join(params['logdir'], prefix + ".lo.pcap")
221
222    with WlantestCapture('lo', cap_lo):
223        run_dpp_controller_relay_pkex2(dev, apdev, params)
224
225def run_dpp_controller_relay_pkex2(dev, apdev, params):
226    # Controller
227    conf_id = dev[1].dpp_configurator_add()
228    dev[1].set("dpp_configurator_params",
229               "conf=sta-dpp configurator=%d" % conf_id)
230    id_c = dev[1].dpp_bootstrap_gen()
231    res = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id_c)
232    pkhash = None
233    for line in res.splitlines():
234        name, value = line.split('=')
235        if name == "pkhash":
236            pkhash = value
237            break
238    if not pkhash:
239        raise Exception("Could not fetch public key hash from Controller")
240    if "OK" not in dev[1].request("DPP_CONTROLLER_START"):
241        raise Exception("Failed to start Controller")
242
243    # Relay
244    params = {"ssid": "unconfigured",
245              "channel": "6",
246              "dpp_controller": "ipaddr=127.0.0.1 pkhash=" + pkhash}
247    relay = hostapd.add_ap(apdev[1], params)
248    check_dpp_capab(relay)
249
250    # Enroll Relay to the network
251    id_h = relay.dpp_bootstrap_gen(chan="81/6", mac=True)
252    uri_r = relay.request("DPP_BOOTSTRAP_GET_URI %d" % id_h)
253    dev[1].dpp_auth_init(uri=uri_r, conf="ap-dpp", configurator=conf_id)
254    wait_auth_success(relay, dev[1], configurator=dev[1], enrollee=relay)
255    update_hapd_config(relay)
256
257    code = "secret"
258    id1 = dev[1].dpp_bootstrap_gen(type="pkex")
259    cmd = "own=%d" % id1
260    cmd += " code=%s" % code
261    res = dev[1].request("DPP_PKEX_ADD " + cmd)
262    if "FAIL" in res:
263        raise Exception("Failed to set PKEX data (Controller)")
264
265    dev[0].flush_scan_cache()
266
267    # Initiate PKEX from Enrollee
268    dev[0].set("dpp_config_processing", "2")
269    dev[0].dpp_pkex_init(identifier=None, code=code, role="enrollee")
270    wait_auth_success(dev[1], dev[0], configurator=dev[1], enrollee=dev[0],
271                      allow_enrollee_failure=True,
272                      allow_configurator_failure=True)
273    ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1)
274    if ev is None:
275        raise Exception("DPP network id not reported")
276    network = int(ev.split(' ')[1])
277    dev[0].wait_connected()
278    dev[0].dump_monitor()
279
280def dpp_pb_ap(apdev):
281    params = {"ssid": "sae",
282              "dpp_configurator_connectivity": "1",
283              "wpa": "2",
284              "wpa_key_mgmt": "SAE",
285              "ieee80211w": "2",
286              "rsn_pairwise": "CCMP",
287              "sae_password": "sae-password"}
288    return hostapd.add_ap(apdev, params)
289
290def test_dpp_push_button(dev, apdev):
291    """DPP push button"""
292    check_dpp_capab(dev[0], min_ver=3)
293    check_sae_capab(dev[0])
294    dev[0].set("sae_groups", "")
295
296    hapd = dpp_pb_ap(apdev[0])
297    try:
298        dev[0].set("dpp_config_processing", "2")
299        if "OK" not in hapd.request("DPP_PUSH_BUTTON"):
300            raise Exception("Failed to press push button on the AP")
301        if "OK" not in dev[0].request("DPP_PUSH_BUTTON"):
302            raise Exception("Failed to press push button on the station")
303        ev = dev[0].wait_event(["DPP-PB-RESULT"], timeout=30)
304        if ev is None or "success" not in ev:
305            raise Exception("Push button bootstrapping did not succeed on station")
306        ev = hapd.wait_event(["DPP-PB-RESULT"], timeout=1)
307        if ev is None or "success" not in ev:
308            raise Exception("Push button bootstrapping did not succeed on AP")
309        dev[0].wait_connected()
310    finally:
311        dev[0].set("dpp_config_processing", "0", allow_fail=True)
312
313def test_dpp_push_button_unsupported_ap_conf(dev, apdev):
314    """DPP push button and unsupported AP configuration"""
315    check_dpp_capab(dev[0], min_ver=3)
316
317    params = {"ssid": "open",
318              "dpp_configurator_connectivity": "1"}
319    hapd = hostapd.add_ap(apdev[0], params)
320    if "OK" not in hapd.request("DPP_PUSH_BUTTON"):
321        raise Exception("Failed to press push button on the AP")
322    if "OK" not in dev[0].request("DPP_PUSH_BUTTON"):
323        raise Exception("Failed to press push button on the station")
324    ev = hapd.wait_event(["DPP-PB-RESULT"], timeout=30)
325    if ev is None or "failed" not in ev:
326        raise Exception("Push button bootstrapping did not fail on AP")
327    while True:
328        ev = dev[0].wait_event(["DPP-PB-RESULT", "DPP-RX", "DPP-TX"],
329                               timeout=100)
330        if ev is None:
331            raise Exception("Push button result not reported on station")
332        dev[0].dump_monitor(mon=False)
333        if "DPP-PB-RESULT failed" in ev:
334            break
335        if "type=18" in ev:
336            raise Exception("Unexpected PKEX initiation seen")
337
338def test_dpp_push_button_session_overlap_sta(dev, apdev):
339    """DPP push button and session overlap detected by STA"""
340    check_dpp_capab(dev[0], min_ver=3)
341    check_sae_capab(dev[0])
342    dev[0].set("sae_groups", "")
343
344    hapd = dpp_pb_ap(apdev[0])
345    params = {"ssid": "another",
346              "channel": "6",
347              "wpa": "2",
348              "wpa_key_mgmt": "SAE",
349              "ieee80211w": "2",
350              "rsn_pairwise": "CCMP",
351              "sae_password": "sae-password"}
352    hapd2 = hostapd.add_ap(apdev[1], params)
353
354    if "OK" not in hapd.request("DPP_PUSH_BUTTON"):
355        raise Exception("Failed to press push button on the AP")
356    if "OK" not in dev[0].request("DPP_PUSH_BUTTON"):
357        raise Exception("Failed to press push button on the station")
358    ev = dev[0].wait_event(["DPP-PB-STATUS discovered"], timeout=30)
359    if ev is None:
360        raise Exception("Push button status not reported on station")
361    # Force bootstrap key change since both instances share the same global
362    # DPP state for PB.
363    hapd.request("DPP_STOP_LISTEN")
364    if "OK" not in hapd2.request("DPP_PUSH_BUTTON"):
365        raise Exception("Failed to press push button on the AP2")
366    ev = dev[0].wait_event(["DPP-PB-RESULT"], timeout=30)
367    if ev is None:
368        raise Exception("Push button result not reported on station")
369    if "session-overlap" not in ev:
370        raise Exception("Unexpected push button result on station: " + ev)
371    ev = hapd.wait_event(["DPP-CONF-SENT"], timeout=0.1)
372    if ev:
373        raise Exception("AP sent configuration")
374    ev = hapd2.wait_event(["DPP-CONF-SENT"], timeout=0.1)
375    if ev:
376        raise Exception("AP2 sent configuration")
377
378def test_dpp_push_button_session_overlap_ap(dev, apdev):
379    """DPP push button and session overlap detected by AP"""
380    check_dpp_capab(dev[0], min_ver=3)
381    check_dpp_capab(dev[1], min_ver=3)
382    check_sae_capab(dev[0])
383    check_sae_capab(dev[1])
384    dev[0].set("sae_groups", "")
385
386    hapd = dpp_pb_ap(apdev[0])
387
388    if "OK" not in hapd.request("DPP_PUSH_BUTTON"):
389        raise Exception("Failed to press push button on the AP")
390    if "OK" not in dev[0].request("DPP_PUSH_BUTTON"):
391        raise Exception("Failed to press push button on the station(0)")
392    if "OK" not in dev[1].request("DPP_PUSH_BUTTON"):
393        raise Exception("Failed to press push button on the station(1)")
394
395    ev = hapd.wait_event(["DPP-PB-RESULT"], timeout=30)
396    if ev is None:
397        raise Exception("Push button result not reported on AP")
398    if "session-overlap" not in ev:
399        raise Exception("Unexpected push button result on AP: " + ev)
400
401    dev[0].request("DPP_STOP_LISTEN")
402    dev[1].request("DPP_STOP_LISTEN")
403
404def test_dpp_push_button_session_overlap_configurator(dev, apdev):
405    """DPP push button and session overlap detected by Configurator"""
406    check_dpp_capab(dev[0], min_ver=3)
407    check_dpp_capab(dev[1], min_ver=3)
408    check_dpp_capab(dev[2], min_ver=3)
409
410    dev[0].dpp_listen(2437)
411    conf_id = dev[1].dpp_configurator_add()
412    ssid = "example"
413    ssid_hex = binascii.hexlify(ssid.encode()).decode()
414    cmd = "DPP_PUSH_BUTTON role=configurator conf=sta-dpp ssid=%s configurator=%d" % (ssid_hex, conf_id)
415    if "OK" not in dev[0].request(cmd):
416        raise Exception("Failed to press push button on the Configurator")
417
418    if "OK" not in dev[1].request("DPP_PUSH_BUTTON"):
419        raise Exception("Failed to press push button on the station(1)")
420    if "OK" not in dev[2].request("DPP_PUSH_BUTTON"):
421        raise Exception("Failed to press push button on the station(2)")
422
423    ev = dev[0].wait_event(["DPP-PB-RESULT"], timeout=30)
424    if ev is None:
425        raise Exception("Push button result not reported on Configurator")
426    if "session-overlap" not in ev:
427        raise Exception("Unexpected push button result on Configurator: " + ev)
428
429    dev[1].request("DPP_STOP_LISTEN")
430    dev[2].request("DPP_STOP_LISTEN")
431
432def test_dpp_push_button_2sta(dev, apdev):
433    """DPP push button with two STAs"""
434    check_dpp_capab(dev[0], min_ver=3)
435    check_dpp_capab(dev[1], min_ver=3)
436    check_sae_capab(dev[0])
437    check_sae_capab(dev[1])
438    dev[0].set("sae_groups", "")
439    dev[1].set("sae_groups", "")
440
441    hapd = dpp_pb_ap(apdev[0])
442    try:
443        dev[0].set("dpp_config_processing", "2")
444        if "OK" not in hapd.request("DPP_PUSH_BUTTON"):
445            raise Exception("Failed to press push button on the AP(0)")
446        if "OK" not in dev[0].request("DPP_PUSH_BUTTON"):
447            raise Exception("Failed to press push button on the station(0)")
448        ev = dev[0].wait_event(["DPP-PB-RESULT"], timeout=30)
449        if ev is None or "success" not in ev:
450            raise Exception("Push button bootstrapping did not succeed on station(0)")
451        ev = hapd.wait_event(["DPP-PB-RESULT"], timeout=30)
452        if ev is None or "success" not in ev:
453            raise Exception("Push button bootstrapping did not succeed on AP(0)")
454        dev[0].wait_connected()
455
456        dev[1].set("dpp_config_processing", "2")
457        if "OK" not in dev[1].request("DPP_PUSH_BUTTON"):
458            raise Exception("Failed to press push button on the station(1)")
459        time.sleep(1)
460        if "OK" not in hapd.request("DPP_PUSH_BUTTON"):
461            raise Exception("Failed to press push button on the AP(1)")
462        ev = dev[1].wait_event(["DPP-PB-RESULT"], timeout=30)
463        if ev is None or "success" not in ev:
464            raise Exception("Push button bootstrapping did not succeed on station(1)")
465        ev = hapd.wait_event(["DPP-PB-RESULT"], timeout=30)
466        if ev is None or "success" not in ev:
467            raise Exception("Push button bootstrapping did not succeed on AP(0)")
468        dev[1].wait_connected()
469    finally:
470        dev[0].set("dpp_config_processing", "0", allow_fail=True)
471        dev[1].set("dpp_config_processing", "0", allow_fail=True)
472
473def test_dpp_push_button_r_hash_mismatch_sta(dev, apdev):
474    """DPP push button - Responder hash mismatch from STA"""
475    check_dpp_capab(dev[0], min_ver=3)
476    check_sae_capab(dev[0])
477    dev[0].set("sae_groups", "")
478
479    hapd = dpp_pb_ap(apdev[0])
480    if "OK" not in hapd.request("DPP_PUSH_BUTTON"):
481        raise Exception("Failed to press push button on the AP")
482    dev[0].set("dpp_test", "98")
483    if "OK" not in dev[0].request("DPP_PUSH_BUTTON"):
484        raise Exception("Failed to press push button on the station")
485    ev = hapd.wait_event(["DPP-PB-RESULT"], timeout=30)
486    if ev is None or "failed" not in ev:
487        raise Exception("Push button bootstrapping did not fail correctly on AP")
488    dev[0].request("DPP_STOP_LISTEN")
489
490def test_dpp_push_button_i_hash_mismatch_ap(dev, apdev):
491    """DPP push button - Initiator hash mismatch from AP"""
492    check_dpp_capab(dev[0], min_ver=3)
493    check_sae_capab(dev[0])
494    dev[0].set("sae_groups", "")
495
496    hapd = dpp_pb_ap(apdev[0])
497    hapd.set("dpp_test", "99")
498    if "OK" not in hapd.request("DPP_PUSH_BUTTON"):
499        raise Exception("Failed to press push button on the AP")
500    if "OK" not in dev[0].request("DPP_PUSH_BUTTON"):
501        raise Exception("Failed to press push button on the station")
502    ev = dev[0].wait_event(["DPP-PB-RESULT"], timeout=30)
503    if ev is None or "failed" not in ev:
504        raise Exception("Push button bootstrapping did not fail correctly on STA")
505
506def test_dpp_push_button_r_hash_mismatch_ap(dev, apdev):
507    """DPP push button - Responder hash mismatch from AP"""
508    check_dpp_capab(dev[0], min_ver=3)
509    check_sae_capab(dev[0])
510    dev[0].set("sae_groups", "")
511
512    hapd = dpp_pb_ap(apdev[0])
513    hapd.set("dpp_test", "100")
514    if "OK" not in hapd.request("DPP_PUSH_BUTTON"):
515        raise Exception("Failed to press push button on the AP")
516    if "OK" not in dev[0].request("DPP_PUSH_BUTTON"):
517        raise Exception("Failed to press push button on the station")
518    ev = dev[0].wait_event(["DPP-PB-RESULT"], timeout=30)
519    if ev is None or "session-overlap" not in ev:
520        raise Exception("Push button bootstrapping did not fail correctly on STA")
521
522def test_dpp_push_button_ext_conf(dev, apdev):
523    """DPP push button"""
524    check_dpp_capab(dev[0], min_ver=3)
525    check_sae_capab(dev[0])
526
527    hapd = dpp_pb_ap(apdev[0])
528    conf_id = hapd.dpp_configurator_add()
529    ssid = "example"
530    ssid_hex = binascii.hexlify(ssid.encode()).decode()
531    cmd = "DPP_PUSH_BUTTON conf=sta-dpp ssid=%s configurator=%d" % (ssid_hex, conf_id)
532    if "OK" not in hapd.request(cmd):
533        raise Exception("Failed to press push button on the AP")
534    if "OK" not in dev[0].request("DPP_PUSH_BUTTON"):
535        raise Exception("Failed to press push button on the station")
536    ev = dev[0].wait_event(["DPP-CONFOBJ-AKM"], timeout=30)
537    if ev is None or "dpp" not in ev:
538        raise Exception("Did not receive DPP AKM config")
539    ev = dev[0].wait_event(["DPP-CONFOBJ-SSID"], timeout=1)
540    if ev is None or ssid not in ev:
541        raise Exception("Did not receive correct SSID in config")
542    ev = dev[0].wait_event(["DPP-PB-RESULT"], timeout=1)
543    if ev is None or "success" not in ev:
544        raise Exception("Push button bootstrapping did not succeed on station")
545    ev = hapd.wait_event(["DPP-PB-RESULT"], timeout=1)
546    if ev is None or "success" not in ev:
547        raise Exception("Push button bootstrapping did not succeed on AP")
548
549def test_dpp_push_button_wpas_conf(dev, apdev):
550    """DPP push button with wpa_supplicant as Configurator"""
551    check_dpp_capab(dev[0], min_ver=3)
552    check_dpp_capab(dev[1], min_ver=3)
553
554    dev[1].dpp_listen(2437)
555    conf_id = dev[1].dpp_configurator_add()
556    ssid = "example"
557    ssid_hex = binascii.hexlify(ssid.encode()).decode()
558    cmd = "DPP_PUSH_BUTTON role=configurator conf=sta-dpp ssid=%s configurator=%d" % (ssid_hex, conf_id)
559    if "OK" not in dev[1].request(cmd):
560        raise Exception("Failed to press push button on the Configurator")
561
562    if "OK" not in dev[0].request("DPP_PUSH_BUTTON"):
563        raise Exception("Failed to press push button on the station")
564    ev = dev[0].wait_event(["DPP-CONFOBJ-AKM"], timeout=30)
565    if ev is None or "dpp" not in ev:
566        raise Exception("Did not receive DPP AKM config")
567    ev = dev[0].wait_event(["DPP-CONFOBJ-SSID"], timeout=1)
568    if ev is None or ssid not in ev:
569        raise Exception("Did not receive correct SSID in config")
570    ev = dev[0].wait_event(["DPP-PB-RESULT"], timeout=1)
571    if ev is None or "success" not in ev:
572        raise Exception("Push button bootstrapping did not succeed on station")
573
574    ev = dev[1].wait_event(["DPP-PB-RESULT"], timeout=1)
575    if ev is None or "success" not in ev:
576        raise Exception("Push button bootstrapping did not succeed on Configurator")
577
578def test_dpp_private_peer_introduction(dev, apdev):
579    """DPP private peer introduction"""
580    check_dpp_capab(dev[0], min_ver=3)
581    check_dpp_capab(dev[1], min_ver=3)
582
583    params = {"ssid": "dpp",
584              "wpa": "2",
585              "wpa_key_mgmt": "DPP",
586              "ieee80211w": "2",
587              "rsn_pairwise": "CCMP",
588              "dpp_connector": params1_ap_connector,
589              "dpp_csign": params1_csign,
590              "dpp_netaccesskey": params1_ap_netaccesskey}
591    try:
592        hapd = hostapd.add_ap(apdev[0], params)
593    except:
594        raise HwsimSkip("DPP not supported")
595
596    id = dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412",
597                        ieee80211w="2",
598                        dpp_csign=params1_csign,
599                        dpp_connector=params1_sta_connector,
600                        dpp_netaccesskey=params1_sta_netaccesskey,
601                        dpp_connector_privacy="1")
602    val = dev[0].get_status_field("key_mgmt")
603    if val != "DPP":
604        raise Exception("Unexpected key_mgmt: " + val)
605