]>
Commit | Line | Data |
---|---|---|
d350084d JM |
1 | # Test cases for Device Provisioning Protocol (DPP) |
2 | # Copyright (c) 2017, Qualcomm Atheros, Inc. | |
009b54be | 3 | # Copyright (c) 2018-2019, The Linux Foundation |
d350084d JM |
4 | # |
5 | # This software may be distributed under the terms of the BSD license. | |
6 | # See README for more details. | |
7 | ||
30dda44d | 8 | import base64 |
fd1534a2 JM |
9 | import binascii |
10 | import hashlib | |
d350084d JM |
11 | import logging |
12 | logger = logging.getLogger() | |
7010f4be | 13 | import os |
b4928ff9 | 14 | import socket |
fd1534a2 | 15 | import struct |
4370ffc0 | 16 | import subprocess |
d350084d JM |
17 | import time |
18 | ||
19 | import hostapd | |
bbb42bf0 | 20 | import hwsim_utils |
f94e677d | 21 | from hwsim import HWSimRadio |
818e3c94 | 22 | from utils import HwsimSkip, alloc_fail, fail_test, wait_fail_trigger |
ee8ef9ca | 23 | from wpasupplicant import WpaSupplicant |
4e9bcdeb | 24 | from wlantest import WlantestCapture |
d350084d | 25 | |
fd1534a2 JM |
26 | try: |
27 | import OpenSSL | |
28 | openssl_imported = True | |
29 | except ImportError: | |
30 | openssl_imported = False | |
31 | ||
009b54be | 32 | def check_dpp_capab(dev, brainpool=False, min_ver=1): |
d350084d JM |
33 | if "UNKNOWN COMMAND" in dev.request("DPP_BOOTSTRAP_GET_URI 0"): |
34 | raise HwsimSkip("DPP not supported") | |
d584946e JM |
35 | if brainpool: |
36 | tls = dev.request("GET tls_library") | |
37 | if not tls.startswith("OpenSSL") or "run=BoringSSL" in tls: | |
38 | raise HwsimSkip("Crypto library does not support Brainpool curves: " + tls) | |
8b6c834f | 39 | capa = dev.request("GET_CAPABILITY dpp") |
009b54be | 40 | ver = 1 |
8b6c834f | 41 | if capa.startswith("DPP="): |
009b54be JM |
42 | ver = int(capa[4:]) |
43 | if ver < min_ver: | |
44 | raise HwsimSkip("DPP version %d not supported" % min_ver) | |
45 | return ver | |
d350084d | 46 | |
203878d7 JM |
47 | def wait_dpp_fail(dev, expected=None): |
48 | ev = dev.wait_event(["DPP-FAIL"], timeout=5) | |
49 | if ev is None: | |
50 | raise Exception("Failure not reported") | |
51 | if expected and expected not in ev: | |
52 | raise Exception("Unexpected result: " + ev) | |
53 | ||
d350084d JM |
54 | def test_dpp_qr_code_parsing(dev, apdev): |
55 | """DPP QR Code parsing""" | |
56 | check_dpp_capab(dev[0]) | |
57 | id = [] | |
58 | ||
fab49f61 JM |
59 | tests = ["DPP:C:81/1,115/36;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkq/24e0rsrfMP9K1Tm8gx+ovP0I=;;", |
60 | "DPP:C:81/1,81/2,81/3,81/4,81/5,81/6,81/7,81/8,81/9,81/10,81/11,81/12,81/13,82/14,83/1,83/2,83/3,83/4,83/5,83/6,83/7,83/8,83/9,84/5,84/6,84/7,84/8,84/9,84/10,84/11,84/12,84/13,115/36;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkq/24e0rsrfMP9K1Tm8gx+ovP0I=;;", | |
35814134 JM |
61 | "DPP:C:81/1,2,3,4,5,6,7,8,9,10,11,12,13,82/14,83/1,2,3,4,5,6,7,8,9,84/5,6,7,8,9,10,11,12,13,115/36;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkq/24e0rsrfMP9K1Tm8gx+ovP0I=;;", |
62 | "DPP:C:81/1,2,3;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkq/24e0rsrfMP9K1Tm8gx+ovP0I=;;", | |
fab49f61 JM |
63 | "DPP:I:SN=4774LH2b4044;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;", |
64 | "DPP:I:;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;"] | |
d350084d | 65 | for uri in tests: |
0422d06b | 66 | id.append(dev[0].dpp_qr_code(uri)) |
d350084d JM |
67 | |
68 | uri2 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id[-1]) | |
69 | if uri != uri2: | |
70 | raise Exception("Returned URI does not match") | |
71 | ||
fab49f61 JM |
72 | tests = ["foo", |
73 | "DPP:", | |
74 | "DPP:;;", | |
75 | "DPP:C:1/2;M:;K;;", | |
76 | "DPP:I:;M:01020304050;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;", | |
77 | "DPP:K:" + base64.b64encode(b"hello").decode() + ";;", | |
78 | "DPP:K:MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEXiJuIWt1Q/CPCkuULechh37UsXPmbUANOeN5U9sOQROE4o/NEFeFEejROHYwwehF;;", | |
79 | "DPP:K:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANNZaZA4T/kRDjnmpI1ACOJhAuTIIEk2KFOpS6XPpGF+EVr/ao3XemkE0/nzXmGaLzLqTUCJknSdxTnVPeWfCVsCAwEAAQ==;;", | |
80 | "DPP:K:MIIBCjCB0wYHKoZIzj0CATCBxwIBATAkBgcqhkjOPQEBAhkA/////////////////////v//////////MEsEGP////////////////////7//////////AQYZCEFGeWcgOcPp+mrciQwSf643uzBRrmxAxUAMEWub8hCL2TtV5Uo04Eg6uEhltUEMQQYjagOsDCQ9ny/IOtDoYgA9P8K/YL/EBIHGSuV/8jaeGMQEe1rJM3Vc/l3oR55SBECGQD///////////////+Z3vg2FGvJsbTSKDECAQEDMgAEXiJuIWt1Q/CPCkuULechh37UsXPmbUANOeN5U9sOQROE4o/NEFeFEejROHYwwehF;;", | |
81 | "DPP:I:foo\tbar;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;", | |
82 | "DPP:C:1;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkqa24e0rsrfMP9K1Tm8gx+ovP0I=;;", | |
83 | "DPP:C:81/1a;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkqa24e0rsrfMP9K1Tm8gx+ovP0I=;;", | |
84 | "DPP:C:1/2000,81/-1;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkqa24e0rsrfMP9K1Tm8gx+ovP0I=;;", | |
85 | "DPP:C:-1/1;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADM2206avxHJaHXgLMkqa24e0rsrfMP9K1Tm8gx+ovP0I=;;"] | |
d350084d JM |
86 | for t in tests: |
87 | res = dev[0].request("DPP_QR_CODE " + t) | |
88 | if "FAIL" not in res: | |
89 | raise Exception("Accepted invalid QR Code: " + t) | |
90 | ||
91 | logger.info("ID: " + str(id)) | |
92 | if id[0] == id[1] or id[0] == id[2] or id[1] == id[2]: | |
93 | raise Exception("Duplicate ID returned") | |
94 | ||
95 | if "FAIL" not in dev[0].request("DPP_BOOTSTRAP_REMOVE 12345678"): | |
96 | raise Exception("DPP_BOOTSTRAP_REMOVE accepted unexpectedly") | |
97 | if "OK" not in dev[0].request("DPP_BOOTSTRAP_REMOVE %d" % id[1]): | |
98 | raise Exception("DPP_BOOTSTRAP_REMOVE failed") | |
99 | ||
a5387062 JM |
100 | id = dev[0].dpp_bootstrap_gen() |
101 | uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id) | |
d350084d JM |
102 | logger.info("Generated URI: " + uri) |
103 | ||
0422d06b | 104 | dev[0].dpp_qr_code(uri) |
d350084d | 105 | |
a5387062 JM |
106 | id = dev[0].dpp_bootstrap_gen(chan="81/1,115/36", mac="010203040506", |
107 | info="foo") | |
108 | uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id) | |
d350084d JM |
109 | logger.info("Generated URI: " + uri) |
110 | ||
0422d06b | 111 | dev[0].dpp_qr_code(uri) |
d350084d | 112 | |
d16be03b JM |
113 | def test_dpp_qr_code_parsing_fail(dev, apdev): |
114 | """DPP QR Code parsing local failure""" | |
115 | check_dpp_capab(dev[0]) | |
116 | with alloc_fail(dev[0], 1, "dpp_parse_uri_info"): | |
117 | if "FAIL" not in dev[0].request("DPP_QR_CODE DPP:I:SN=4774LH2b4044;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;"): | |
118 | raise Exception("DPP_QR_CODE failure not reported") | |
119 | ||
120 | with alloc_fail(dev[0], 1, "dpp_parse_uri_pk"): | |
121 | if "FAIL" not in dev[0].request("DPP_QR_CODE DPP:K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;"): | |
122 | raise Exception("DPP_QR_CODE failure not reported") | |
123 | ||
124 | with fail_test(dev[0], 1, "dpp_parse_uri_pk"): | |
125 | if "FAIL" not in dev[0].request("DPP_QR_CODE DPP:K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;"): | |
126 | raise Exception("DPP_QR_CODE failure not reported") | |
127 | ||
128 | with alloc_fail(dev[0], 1, "dpp_parse_uri"): | |
129 | if "FAIL" not in dev[0].request("DPP_QR_CODE DPP:I:SN=4774LH2b4044;M:010203040506;K:MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgADURzxmttZoIRIPWGoQMV00XHWCAQIhXruVWOz0NjlkIA=;;"): | |
130 | raise Exception("DPP_QR_CODE failure not reported") | |
131 | ||
fab49f61 | 132 | dpp_key_p256 = "30570201010420777fc55dc51e967c10ec051b91d860b5f1e6c934e48d5daffef98d032c64b170a00a06082a8648ce3d030107a124032200020c804188c7f85beb6e91070d2b3e5e39b90ca77b4d3c5251bc1844d6ca29dcad" |
35818d3e JM |
133 | dpp_key_p384 = "307402010104302f56fdd83b5345cacb630eb7c22fa5ad5daba37307c95191e2a75756d137003bd8b32dbcb00eb5650c1eb499ecfcaec0a00706052b81040022a13403320003615ec2141b5b77aebb6523f8a012755f9a34405a8398d2ceeeebca7f5ce868bf55056cba4c4ec62fad3ed26dd29e0f23" |
134 | dpp_key_p521 = "308198020101044200c8010d5357204c252551aaf4e210343111e503fd1dc615b257058997c49b6b643c975226e93be8181cca3d83a7072defd161dfbdf433c19abe1f2ad51867a05761a00706052b81040023a1460344000301cdf3608b1305fe34a1f976095dcf001182b9973354efe156291a66830292f9babd8f412ad462958663e7a75d1d0610abdfc3dd95d40669f7ab3bc001668cfb3b7c" | |
135 | dpp_key_bp256 = "3058020101042057133a676fb60bf2a3e6797e19833c7b0f89dc192ab99ab5fa377ae23a157765a00b06092b2403030208010107a12403220002945d9bf7ce30c9c1ac0ff21ca62b984d5bb80ff69d2be8c9716ab39a10d2caf0" | |
136 | dpp_key_bp384 = "307802010104304902df9f3033a9b7128554c0851dc7127c3573eed150671dae74c0013e9896a9b1c22b6f7d43d8a2ebb7cd474dc55039a00b06092b240303020801010ba13403320003623cb5e68787f351faababf3425161571560add2e6f9a306fcbffb507735bf955bb46dd20ba246b0d5cadce73e5bd6a6" | |
137 | dpp_key_bp512 = "30819802010104405803494226eb7e50bf0e90633f37e7e35d33f5fa502165eeba721d927f9f846caf12e925701d18e123abaaaf4a7edb4fc4de21ce18bc10c4d12e8b3439f74e40a00b06092b240303020801010da144034200033b086ccd47486522d35dc16fbb2229642c2e9e87897d45abbf21f9fb52acb5a6272b31d1b227c3e53720769cc16b4cb181b26cd0d35fe463218aaedf3b6ec00a" | |
138 | ||
139 | def test_dpp_qr_code_curves(dev, apdev): | |
140 | """DPP QR Code and supported curves""" | |
141 | check_dpp_capab(dev[0]) | |
fab49f61 JM |
142 | tests = [("prime256v1", dpp_key_p256), |
143 | ("secp384r1", dpp_key_p384), | |
144 | ("secp521r1", dpp_key_p521)] | |
35818d3e | 145 | for curve, hex in tests: |
a5387062 JM |
146 | id = dev[0].dpp_bootstrap_gen(key=hex) |
147 | info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id) | |
35818d3e JM |
148 | if "FAIL" in info: |
149 | raise Exception("Failed to get info for " + curve) | |
150 | if "curve=" + curve not in info: | |
151 | raise Exception("Curve mismatch for " + curve) | |
152 | ||
153 | def test_dpp_qr_code_curves_brainpool(dev, apdev): | |
154 | """DPP QR Code and supported Brainpool curves""" | |
155 | check_dpp_capab(dev[0], brainpool=True) | |
fab49f61 JM |
156 | tests = [("brainpoolP256r1", dpp_key_bp256), |
157 | ("brainpoolP384r1", dpp_key_bp384), | |
158 | ("brainpoolP512r1", dpp_key_bp512)] | |
35818d3e | 159 | for curve, hex in tests: |
a5387062 JM |
160 | id = dev[0].dpp_bootstrap_gen(key=hex) |
161 | info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id) | |
35818d3e JM |
162 | if "FAIL" in info: |
163 | raise Exception("Failed to get info for " + curve) | |
164 | if "curve=" + curve not in info: | |
165 | raise Exception("Curve mismatch for " + curve) | |
166 | ||
e9bca5b8 JM |
167 | def test_dpp_qr_code_unsupported_curve(dev, apdev): |
168 | """DPP QR Code and unsupported curve""" | |
169 | check_dpp_capab(dev[0]) | |
170 | ||
171 | id = dev[0].request("DPP_BOOTSTRAP_GEN type=qrcode curve=unsupported") | |
172 | if "FAIL" not in id: | |
173 | raise Exception("Unsupported curve accepted") | |
174 | ||
fab49f61 JM |
175 | tests = ["30", |
176 | "305f02010104187f723ed9e1b41979ec5cd02eb82696efc76b40e277661049a00a06082a8648ce3d030101a134033200043f292614dea97c43f500f069e79ae9fb48f8b07369180de5eec8fa2bc9eea5af7a46dc335f52f10cb1c0e9464201d41b"] | |
e9bca5b8 JM |
177 | for hex in tests: |
178 | id = dev[0].request("DPP_BOOTSTRAP_GEN type=qrcode key=" + hex) | |
179 | if "FAIL" not in id: | |
180 | raise Exception("Unsupported/invalid curve accepted") | |
181 | ||
545bf954 JM |
182 | def test_dpp_qr_code_keygen_fail(dev, apdev): |
183 | """DPP QR Code and keygen failure""" | |
184 | check_dpp_capab(dev[0]) | |
185 | ||
186 | with alloc_fail(dev[0], 1, "dpp_bootstrap_key_der;dpp_keygen"): | |
187 | if "FAIL" not in dev[0].request("DPP_BOOTSTRAP_GEN type=qrcode"): | |
188 | raise Exception("Failure not reported") | |
189 | ||
190 | with alloc_fail(dev[0], 1, "base64_gen_encode;dpp_keygen"): | |
191 | if "FAIL" not in dev[0].request("DPP_BOOTSTRAP_GEN type=qrcode"): | |
192 | raise Exception("Failure not reported") | |
193 | ||
35818d3e JM |
194 | def test_dpp_qr_code_curve_select(dev, apdev): |
195 | """DPP QR Code and curve selection""" | |
196 | check_dpp_capab(dev[0], brainpool=True) | |
197 | check_dpp_capab(dev[1], brainpool=True) | |
198 | ||
35818d3e | 199 | bi = [] |
fab49f61 JM |
200 | for key in [dpp_key_p256, dpp_key_p384, dpp_key_p521, |
201 | dpp_key_bp256, dpp_key_bp384, dpp_key_bp512]: | |
a5387062 JM |
202 | id = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True, key=key) |
203 | info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id) | |
35818d3e JM |
204 | for i in info.splitlines(): |
205 | if '=' in i: | |
206 | name, val = i.split('=') | |
207 | if name == "curve": | |
208 | curve = val | |
209 | break | |
a5387062 | 210 | uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id) |
35818d3e JM |
211 | bi.append((curve, uri)) |
212 | ||
213 | for curve, uri in bi: | |
214 | logger.info("Curve: " + curve) | |
215 | logger.info("URI: " + uri) | |
216 | ||
7e009100 | 217 | dev[0].dpp_listen(2412) |
5725b3e3 | 218 | dev[1].dpp_auth_init(uri=uri) |
517f76b1 JM |
219 | wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0], |
220 | allow_enrollee_failure=True, stop_responder=True, | |
221 | stop_initiator=True) | |
35818d3e | 222 | |
d350084d JM |
223 | def test_dpp_qr_code_auth_broadcast(dev, apdev): |
224 | """DPP QR Code and authentication exchange (broadcast)""" | |
225 | check_dpp_capab(dev[0]) | |
226 | check_dpp_capab(dev[1]) | |
227 | logger.info("dev0 displays QR Code") | |
a5387062 | 228 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1") |
d350084d | 229 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
5725b3e3 | 230 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 231 | dev[0].dpp_listen(2412) |
5725b3e3 | 232 | dev[1].dpp_auth_init(uri=uri0) |
517f76b1 | 233 | wait_auth_success(dev[0], dev[1], stop_responder=True) |
d350084d JM |
234 | |
235 | def test_dpp_qr_code_auth_unicast(dev, apdev): | |
236 | """DPP QR Code and authentication exchange (unicast)""" | |
237 | run_dpp_qr_code_auth_unicast(dev, apdev, None) | |
238 | ||
239 | def test_dpp_qr_code_auth_unicast_ap_enrollee(dev, apdev): | |
240 | """DPP QR Code and authentication exchange (AP enrollee)""" | |
241 | run_dpp_qr_code_auth_unicast(dev, apdev, None, netrole="ap") | |
242 | ||
12cdfb4d JM |
243 | def run_dpp_configurator_enrollee(dev, apdev, conf_curve=None): |
244 | run_dpp_qr_code_auth_unicast(dev, apdev, None, netrole="configurator", | |
3e4b709f JM |
245 | configurator=True, conf_curve=conf_curve, |
246 | conf="configurator") | |
12cdfb4d JM |
247 | ev = dev[0].wait_event(["DPP-CONFIGURATOR-ID"], timeout=2) |
248 | if ev is None: | |
249 | raise Exception("No Configurator instance added") | |
250 | ||
251 | def test_dpp_configurator_enrollee(dev, apdev): | |
252 | """DPP Configurator enrolling""" | |
253 | run_dpp_configurator_enrollee(dev, apdev) | |
254 | ||
255 | def test_dpp_configurator_enrollee_prime256v1(dev, apdev): | |
256 | """DPP Configurator enrolling (prime256v1)""" | |
257 | run_dpp_configurator_enrollee(dev, apdev, conf_curve="prime256v1") | |
258 | ||
259 | def test_dpp_configurator_enrollee_secp384r1(dev, apdev): | |
260 | """DPP Configurator enrolling (secp384r1)""" | |
261 | run_dpp_configurator_enrollee(dev, apdev, conf_curve="secp384r1") | |
262 | ||
263 | def test_dpp_configurator_enrollee_secp521r1(dev, apdev): | |
264 | """DPP Configurator enrolling (secp521r1)""" | |
265 | run_dpp_configurator_enrollee(dev, apdev, conf_curve="secp521r1") | |
266 | ||
267 | def test_dpp_configurator_enrollee_brainpoolP256r1(dev, apdev): | |
268 | """DPP Configurator enrolling (brainpoolP256r1)""" | |
269 | run_dpp_configurator_enrollee(dev, apdev, conf_curve="brainpoolP256r1") | |
270 | ||
271 | def test_dpp_configurator_enrollee_brainpoolP384r1(dev, apdev): | |
272 | """DPP Configurator enrolling (brainpoolP384r1)""" | |
273 | run_dpp_configurator_enrollee(dev, apdev, conf_curve="brainpoolP384r1") | |
274 | ||
275 | def test_dpp_configurator_enrollee_brainpoolP512r1(dev, apdev): | |
276 | """DPP Configurator enrolling (brainpoolP512r1)""" | |
277 | run_dpp_configurator_enrollee(dev, apdev, conf_curve="brainpoolP512r1") | |
278 | ||
d350084d JM |
279 | def test_dpp_qr_code_curve_prime256v1(dev, apdev): |
280 | """DPP QR Code and curve prime256v1""" | |
281 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1") | |
282 | ||
283 | def test_dpp_qr_code_curve_secp384r1(dev, apdev): | |
284 | """DPP QR Code and curve secp384r1""" | |
285 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1") | |
286 | ||
287 | def test_dpp_qr_code_curve_secp521r1(dev, apdev): | |
288 | """DPP QR Code and curve secp521r1""" | |
289 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1") | |
290 | ||
291 | def test_dpp_qr_code_curve_brainpoolP256r1(dev, apdev): | |
292 | """DPP QR Code and curve brainpoolP256r1""" | |
293 | run_dpp_qr_code_auth_unicast(dev, apdev, "brainpoolP256r1") | |
294 | ||
295 | def test_dpp_qr_code_curve_brainpoolP384r1(dev, apdev): | |
296 | """DPP QR Code and curve brainpoolP384r1""" | |
297 | run_dpp_qr_code_auth_unicast(dev, apdev, "brainpoolP384r1") | |
298 | ||
299 | def test_dpp_qr_code_curve_brainpoolP512r1(dev, apdev): | |
300 | """DPP QR Code and curve brainpoolP512r1""" | |
301 | run_dpp_qr_code_auth_unicast(dev, apdev, "brainpoolP512r1") | |
302 | ||
303 | def test_dpp_qr_code_set_key(dev, apdev): | |
304 | """DPP QR Code and fixed bootstrapping key""" | |
305 | run_dpp_qr_code_auth_unicast(dev, apdev, None, key="30770201010420e5143ac74682cc6869a830e8f5301a5fa569130ac329b1d7dd6f2a7495dbcbe1a00a06082a8648ce3d030107a144034200045e13e167c33dbc7d85541e5509600aa8139bbb3e39e25898992c5d01be92039ee2850f17e71506ded0d6b25677441eae249f8e225c68dd15a6354dca54006383") | |
306 | ||
307 | def run_dpp_qr_code_auth_unicast(dev, apdev, curve, netrole=None, key=None, | |
308 | require_conf_success=False, init_extra=None, | |
309 | require_conf_failure=False, | |
3e4b709f JM |
310 | configurator=False, conf_curve=None, |
311 | conf=None): | |
d584946e JM |
312 | check_dpp_capab(dev[0], curve and "brainpool" in curve) |
313 | check_dpp_capab(dev[1], curve and "brainpool" in curve) | |
d350084d | 314 | if configurator: |
e105110f | 315 | conf_id = dev[1].dpp_configurator_add(curve=conf_curve) |
5725b3e3 JM |
316 | else: |
317 | conf_id = None | |
d350084d JM |
318 | |
319 | logger.info("dev0 displays QR Code") | |
a5387062 | 320 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True, curve=curve, key=key) |
d350084d JM |
321 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
322 | ||
5725b3e3 | 323 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 324 | dev[0].dpp_listen(2412, netrole=netrole) |
3e4b709f JM |
325 | dev[1].dpp_auth_init(uri=uri0, extra=init_extra, configurator=conf_id, |
326 | conf=conf) | |
517f76b1 JM |
327 | wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0], |
328 | allow_enrollee_failure=True, | |
329 | allow_configurator_failure=not require_conf_success, | |
330 | require_configurator_failure=require_conf_failure, | |
331 | stop_responder=True) | |
d350084d JM |
332 | |
333 | def test_dpp_qr_code_auth_mutual(dev, apdev): | |
334 | """DPP QR Code and authentication exchange (mutual)""" | |
335 | check_dpp_capab(dev[0]) | |
336 | check_dpp_capab(dev[1]) | |
337 | logger.info("dev0 displays QR Code") | |
a5387062 | 338 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
d350084d JM |
339 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
340 | ||
d350084d | 341 | logger.info("dev1 displays QR Code") |
a5387062 | 342 | id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True) |
d350084d JM |
343 | uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b) |
344 | ||
345 | logger.info("dev0 scans QR Code") | |
0422d06b | 346 | id0b = dev[0].dpp_qr_code(uri1b) |
d350084d | 347 | |
5725b3e3 | 348 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 349 | dev[0].dpp_listen(2412) |
5725b3e3 | 350 | dev[1].dpp_auth_init(uri=uri0, own=id1b) |
41dafe0c JM |
351 | |
352 | ev = dev[1].wait_event(["DPP-AUTH-DIRECTION"], timeout=5) | |
353 | if ev is None: | |
354 | raise Exception("DPP authentication direction not indicated (Initiator)") | |
355 | if "mutual=1" not in ev: | |
356 | raise Exception("Mutual authentication not used") | |
357 | ||
517f76b1 | 358 | wait_auth_success(dev[0], dev[1], stop_responder=True) |
d350084d JM |
359 | |
360 | def test_dpp_qr_code_auth_mutual2(dev, apdev): | |
361 | """DPP QR Code and authentication exchange (mutual2)""" | |
362 | check_dpp_capab(dev[0]) | |
363 | check_dpp_capab(dev[1]) | |
364 | logger.info("dev0 displays QR Code") | |
a5387062 | 365 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
d350084d JM |
366 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
367 | ||
d350084d | 368 | logger.info("dev1 displays QR Code") |
a5387062 | 369 | id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True) |
d350084d JM |
370 | uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b) |
371 | ||
5725b3e3 | 372 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 373 | dev[0].dpp_listen(2412, qr="mutual") |
5725b3e3 | 374 | dev[1].dpp_auth_init(uri=uri0, own=id1b) |
d350084d JM |
375 | |
376 | ev = dev[1].wait_event(["DPP-RESPONSE-PENDING"], timeout=5) | |
377 | if ev is None: | |
378 | raise Exception("Pending response not reported") | |
379 | ev = dev[0].wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5) | |
380 | if ev is None: | |
381 | raise Exception("QR Code scan for mutual authentication not requested") | |
382 | ||
383 | logger.info("dev0 scans QR Code") | |
0422d06b | 384 | id0b = dev[0].dpp_qr_code(uri1b) |
d350084d | 385 | |
41dafe0c JM |
386 | ev = dev[1].wait_event(["DPP-AUTH-DIRECTION"], timeout=5) |
387 | if ev is None: | |
388 | raise Exception("DPP authentication direction not indicated (Initiator)") | |
389 | if "mutual=1" not in ev: | |
390 | raise Exception("Mutual authentication not used") | |
391 | ||
517f76b1 | 392 | wait_auth_success(dev[0], dev[1], stop_responder=True) |
d350084d | 393 | |
cdef4e91 JM |
394 | def test_dpp_qr_code_auth_mutual_p_256(dev, apdev): |
395 | """DPP QR Code and authentication exchange (mutual, autogen P-256)""" | |
396 | run_dpp_qr_code_auth_mutual(dev, apdev, "P-256") | |
397 | ||
398 | def test_dpp_qr_code_auth_mutual_p_384(dev, apdev): | |
399 | """DPP QR Code and authentication exchange (mutual, autogen P-384)""" | |
400 | run_dpp_qr_code_auth_mutual(dev, apdev, "P-384") | |
401 | ||
402 | def test_dpp_qr_code_auth_mutual_p_521(dev, apdev): | |
403 | """DPP QR Code and authentication exchange (mutual, autogen P-521)""" | |
404 | run_dpp_qr_code_auth_mutual(dev, apdev, "P-521") | |
405 | ||
406 | def test_dpp_qr_code_auth_mutual_bp_256(dev, apdev): | |
407 | """DPP QR Code and authentication exchange (mutual, autogen BP-256)""" | |
408 | run_dpp_qr_code_auth_mutual(dev, apdev, "BP-256") | |
409 | ||
410 | def test_dpp_qr_code_auth_mutual_bp_384(dev, apdev): | |
411 | """DPP QR Code and authentication exchange (mutual, autogen BP-384)""" | |
412 | run_dpp_qr_code_auth_mutual(dev, apdev, "BP-384") | |
413 | ||
414 | def test_dpp_qr_code_auth_mutual_bp_512(dev, apdev): | |
415 | """DPP QR Code and authentication exchange (mutual, autogen BP-512)""" | |
416 | run_dpp_qr_code_auth_mutual(dev, apdev, "BP-512") | |
417 | ||
418 | def run_dpp_qr_code_auth_mutual(dev, apdev, curve): | |
419 | check_dpp_capab(dev[0], curve and "BP-" in curve) | |
420 | check_dpp_capab(dev[1], curve and "BP-" in curve) | |
421 | logger.info("dev0 displays QR Code") | |
a5387062 | 422 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True, curve=curve) |
cdef4e91 | 423 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
5725b3e3 | 424 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 425 | dev[0].dpp_listen(2412, qr="mutual") |
5725b3e3 | 426 | dev[1].dpp_auth_init(uri=uri0) |
cdef4e91 JM |
427 | |
428 | ev = dev[1].wait_event(["DPP-RESPONSE-PENDING"], timeout=5) | |
429 | if ev is None: | |
430 | raise Exception("Pending response not reported") | |
431 | uri = ev.split(' ')[1] | |
432 | ||
433 | ev = dev[0].wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5) | |
434 | if ev is None: | |
435 | raise Exception("QR Code scan for mutual authentication not requested") | |
436 | ||
437 | logger.info("dev0 scans QR Code") | |
0422d06b | 438 | dev[0].dpp_qr_code(uri) |
cdef4e91 | 439 | |
41dafe0c JM |
440 | ev = dev[1].wait_event(["DPP-AUTH-DIRECTION"], timeout=5) |
441 | if ev is None: | |
442 | raise Exception("DPP authentication direction not indicated (Initiator)") | |
443 | if "mutual=1" not in ev: | |
444 | raise Exception("Mutual authentication not used") | |
445 | ||
517f76b1 | 446 | wait_auth_success(dev[0], dev[1], stop_responder=True) |
cdef4e91 | 447 | |
ba37ba41 JM |
448 | def test_dpp_auth_resp_retries(dev, apdev): |
449 | """DPP Authentication Response retries""" | |
450 | check_dpp_capab(dev[0]) | |
451 | check_dpp_capab(dev[1]) | |
452 | dev[0].set("dpp_resp_max_tries", "3") | |
453 | dev[0].set("dpp_resp_retry_time", "100") | |
454 | ||
455 | logger.info("dev0 displays QR Code") | |
a5387062 | 456 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
ba37ba41 | 457 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
ba37ba41 | 458 | logger.info("dev1 displays QR Code") |
a5387062 | 459 | id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True) |
ba37ba41 | 460 | uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b) |
5725b3e3 | 461 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 462 | dev[0].dpp_listen(2412, qr="mutual") |
5725b3e3 | 463 | dev[1].dpp_auth_init(uri=uri0, own=id1b) |
ba37ba41 JM |
464 | |
465 | ev = dev[1].wait_event(["DPP-RESPONSE-PENDING"], timeout=5) | |
466 | if ev is None: | |
467 | raise Exception("Pending response not reported") | |
468 | ev = dev[0].wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5) | |
469 | if ev is None: | |
470 | raise Exception("QR Code scan for mutual authentication not requested") | |
471 | ||
472 | # Stop Initiator from listening to frames to force retransmission of the | |
473 | # DPP Authentication Response frame with Status=0 | |
474 | dev[1].request("DPP_STOP_LISTEN") | |
475 | ||
476 | dev[1].dump_monitor() | |
477 | dev[0].dump_monitor() | |
478 | ||
479 | logger.info("dev0 scans QR Code") | |
0422d06b | 480 | id0b = dev[0].dpp_qr_code(uri1b) |
ba37ba41 | 481 | |
dbdd445d | 482 | ev = dev[0].wait_event(["DPP-TX "], timeout=5) |
ba37ba41 JM |
483 | if ev is None or "type=1" not in ev: |
484 | raise Exception("DPP Authentication Response not sent") | |
485 | ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=5) | |
486 | if ev is None: | |
487 | raise Exception("TX status for DPP Authentication Response not reported") | |
488 | if "result=no-ACK" not in ev: | |
489 | raise Exception("Unexpected TX status for Authentication Response: " + ev) | |
490 | ||
dbdd445d | 491 | ev = dev[0].wait_event(["DPP-TX "], timeout=15) |
ba37ba41 JM |
492 | if ev is None or "type=1" not in ev: |
493 | raise Exception("DPP Authentication Response retransmission not sent") | |
494 | ||
f7380b47 JM |
495 | def test_dpp_qr_code_auth_mutual_not_used(dev, apdev): |
496 | """DPP QR Code and authentication exchange (mutual not used)""" | |
497 | check_dpp_capab(dev[0]) | |
498 | check_dpp_capab(dev[1]) | |
499 | logger.info("dev0 displays QR Code") | |
a5387062 | 500 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
f7380b47 | 501 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
f7380b47 | 502 | logger.info("dev1 displays QR Code") |
a5387062 | 503 | id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True) |
f7380b47 | 504 | uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b) |
f7380b47 | 505 | logger.info("dev0 does not scan QR Code") |
5725b3e3 | 506 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 507 | dev[0].dpp_listen(2412) |
5725b3e3 | 508 | dev[1].dpp_auth_init(uri=uri0, own=id1b) |
41dafe0c JM |
509 | |
510 | ev = dev[1].wait_event(["DPP-AUTH-DIRECTION"], timeout=5) | |
511 | if ev is None: | |
512 | raise Exception("DPP authentication direction not indicated (Initiator)") | |
513 | if "mutual=0" not in ev: | |
514 | raise Exception("Mutual authentication not used") | |
515 | ||
517f76b1 | 516 | wait_auth_success(dev[0], dev[1], stop_responder=True) |
f7380b47 | 517 | |
d350084d JM |
518 | def test_dpp_qr_code_auth_mutual_curve_mismatch(dev, apdev): |
519 | """DPP QR Code and authentication exchange (mutual/mismatch)""" | |
520 | check_dpp_capab(dev[0]) | |
521 | check_dpp_capab(dev[1]) | |
522 | logger.info("dev0 displays QR Code") | |
a5387062 | 523 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
d350084d | 524 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
d350084d | 525 | logger.info("dev1 displays QR Code") |
a5387062 | 526 | id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True, curve="secp384r1") |
d350084d | 527 | uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b) |
d350084d | 528 | logger.info("dev0 scans QR Code") |
0422d06b | 529 | id0b = dev[0].dpp_qr_code(uri1b) |
5725b3e3 JM |
530 | logger.info("dev1 scans QR Code") |
531 | dev[1].dpp_auth_init(uri=uri0, own=id1b, expect_fail=True) | |
d350084d | 532 | |
efa77d0a JM |
533 | def test_dpp_qr_code_auth_hostapd_mutual2(dev, apdev): |
534 | """DPP QR Code and authentication exchange (hostapd mutual2)""" | |
535 | check_dpp_capab(dev[0]) | |
fab49f61 | 536 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"}) |
efa77d0a | 537 | check_dpp_capab(hapd) |
efa77d0a | 538 | logger.info("AP displays QR Code") |
a5387062 | 539 | id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True) |
efa77d0a | 540 | uri_h = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h) |
efa77d0a | 541 | logger.info("dev0 displays QR Code") |
a5387062 | 542 | id0b = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
efa77d0a | 543 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0b) |
5725b3e3 | 544 | logger.info("dev0 scans QR Code and initiates DPP Authentication") |
7e009100 | 545 | hapd.dpp_listen(2412, qr="mutual") |
5725b3e3 | 546 | dev[0].dpp_auth_init(uri=uri_h, own=id0b) |
efa77d0a JM |
547 | |
548 | ev = dev[0].wait_event(["DPP-RESPONSE-PENDING"], timeout=5) | |
549 | if ev is None: | |
550 | raise Exception("Pending response not reported") | |
551 | ev = hapd.wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5) | |
552 | if ev is None: | |
553 | raise Exception("QR Code scan for mutual authentication not requested") | |
554 | ||
555 | logger.info("AP scans QR Code") | |
0422d06b | 556 | hapd.dpp_qr_code(uri0) |
efa77d0a | 557 | |
517f76b1 | 558 | wait_auth_success(hapd, dev[0], stop_responder=True) |
efa77d0a | 559 | |
d350084d JM |
560 | def test_dpp_qr_code_listen_continue(dev, apdev): |
561 | """DPP QR Code and listen operation needing continuation""" | |
562 | check_dpp_capab(dev[0]) | |
563 | check_dpp_capab(dev[1]) | |
564 | logger.info("dev0 displays QR Code") | |
a5387062 | 565 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
d350084d | 566 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
7e009100 | 567 | dev[0].dpp_listen(2412) |
d350084d JM |
568 | logger.info("Wait for listen to expire and get restarted") |
569 | time.sleep(5.5) | |
5725b3e3 JM |
570 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
571 | dev[1].dpp_auth_init(uri=uri0) | |
517f76b1 | 572 | wait_auth_success(dev[0], dev[1], stop_responder=True) |
d350084d JM |
573 | |
574 | def test_dpp_qr_code_auth_initiator_enrollee(dev, apdev): | |
575 | """DPP QR Code and authentication exchange (Initiator in Enrollee role)""" | |
f77d1062 JM |
576 | try: |
577 | run_dpp_qr_code_auth_initiator_enrollee(dev, apdev) | |
578 | finally: | |
579 | dev[0].set("gas_address3", "0") | |
580 | dev[1].set("gas_address3", "0") | |
581 | ||
582 | def run_dpp_qr_code_auth_initiator_enrollee(dev, apdev): | |
d350084d JM |
583 | check_dpp_capab(dev[0]) |
584 | check_dpp_capab(dev[1]) | |
585 | dev[0].request("SET gas_address3 1") | |
586 | dev[1].request("SET gas_address3 1") | |
587 | logger.info("dev0 displays QR Code") | |
a5387062 | 588 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
d350084d | 589 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
5725b3e3 | 590 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 591 | dev[0].dpp_listen(2412) |
5725b3e3 | 592 | dev[1].dpp_auth_init(uri=uri0, role="enrollee") |
517f76b1 JM |
593 | wait_auth_success(dev[0], dev[1], configurator=dev[0], enrollee=dev[1], |
594 | allow_enrollee_failure=True, stop_responder=True) | |
d350084d | 595 | |
51fbcad4 JM |
596 | def test_dpp_qr_code_auth_initiator_either_1(dev, apdev): |
597 | """DPP QR Code and authentication exchange (Initiator in either role)""" | |
598 | run_dpp_qr_code_auth_initiator_either(dev, apdev, None, dev[1], dev[0]) | |
599 | ||
600 | def test_dpp_qr_code_auth_initiator_either_2(dev, apdev): | |
601 | """DPP QR Code and authentication exchange (Initiator in either role)""" | |
602 | run_dpp_qr_code_auth_initiator_either(dev, apdev, "enrollee", | |
603 | dev[1], dev[0]) | |
604 | ||
605 | def test_dpp_qr_code_auth_initiator_either_3(dev, apdev): | |
606 | """DPP QR Code and authentication exchange (Initiator in either role)""" | |
607 | run_dpp_qr_code_auth_initiator_either(dev, apdev, "configurator", | |
608 | dev[0], dev[1]) | |
609 | ||
610 | def run_dpp_qr_code_auth_initiator_either(dev, apdev, resp_role, | |
611 | conf_dev, enrollee_dev): | |
612 | check_dpp_capab(dev[0]) | |
613 | check_dpp_capab(dev[1]) | |
614 | logger.info("dev0 displays QR Code") | |
a5387062 | 615 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
51fbcad4 | 616 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
5725b3e3 | 617 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 618 | dev[0].dpp_listen(2412, role=resp_role) |
5725b3e3 | 619 | dev[1].dpp_auth_init(uri=uri0, role="either") |
517f76b1 JM |
620 | wait_auth_success(dev[0], dev[1], configurator=conf_dev, |
621 | enrollee=enrollee_dev, allow_enrollee_failure=True, | |
622 | stop_responder=True) | |
51fbcad4 | 623 | |
3710b58d | 624 | def run_init_incompatible_roles(dev, role="enrollee"): |
d350084d JM |
625 | check_dpp_capab(dev[0]) |
626 | check_dpp_capab(dev[1]) | |
627 | logger.info("dev0 displays QR Code") | |
a5387062 | 628 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
d350084d JM |
629 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
630 | ||
631 | logger.info("dev1 scans QR Code") | |
0422d06b | 632 | id1 = dev[1].dpp_qr_code(uri0) |
d350084d JM |
633 | |
634 | logger.info("dev1 initiates DPP Authentication") | |
7e009100 | 635 | dev[0].dpp_listen(2412, role=role) |
3710b58d JM |
636 | return id1 |
637 | ||
638 | def test_dpp_qr_code_auth_incompatible_roles(dev, apdev): | |
639 | """DPP QR Code and authentication exchange (incompatible roles)""" | |
640 | id1 = run_init_incompatible_roles(dev) | |
5725b3e3 | 641 | dev[1].dpp_auth_init(peer=id1, role="enrollee") |
d350084d JM |
642 | ev = dev[1].wait_event(["DPP-NOT-COMPATIBLE"], timeout=5) |
643 | if ev is None: | |
644 | raise Exception("DPP-NOT-COMPATIBLE event on initiator timed out") | |
645 | ev = dev[0].wait_event(["DPP-NOT-COMPATIBLE"], timeout=1) | |
646 | if ev is None: | |
647 | raise Exception("DPP-NOT-COMPATIBLE event on responder timed out") | |
5725b3e3 | 648 | dev[1].dpp_auth_init(peer=id1, role="configurator") |
517f76b1 | 649 | wait_auth_success(dev[0], dev[1], stop_responder=True) |
d350084d | 650 | |
3710b58d JM |
651 | def test_dpp_qr_code_auth_incompatible_roles2(dev, apdev): |
652 | """DPP QR Code and authentication exchange (incompatible roles 2)""" | |
653 | id1 = run_init_incompatible_roles(dev, role="configurator") | |
5725b3e3 | 654 | dev[1].dpp_auth_init(peer=id1, role="configurator") |
3710b58d JM |
655 | ev = dev[1].wait_event(["DPP-NOT-COMPATIBLE"], timeout=5) |
656 | if ev is None: | |
657 | raise Exception("DPP-NOT-COMPATIBLE event on initiator timed out") | |
658 | ev = dev[0].wait_event(["DPP-NOT-COMPATIBLE"], timeout=1) | |
659 | if ev is None: | |
660 | raise Exception("DPP-NOT-COMPATIBLE event on responder timed out") | |
661 | ||
662 | def test_dpp_qr_code_auth_incompatible_roles_failure(dev, apdev): | |
663 | """DPP QR Code and authentication exchange (incompatible roles failure)""" | |
664 | id1 = run_init_incompatible_roles(dev, role="configurator") | |
665 | with alloc_fail(dev[0], 1, "dpp_auth_build_resp_status"): | |
5725b3e3 | 666 | dev[1].dpp_auth_init(peer=id1, role="configurator") |
3710b58d JM |
667 | ev = dev[0].wait_event(["DPP-NOT-COMPATIBLE"], timeout=1) |
668 | if ev is None: | |
669 | raise Exception("DPP-NOT-COMPATIBLE event on responder timed out") | |
670 | ||
671 | def test_dpp_qr_code_auth_incompatible_roles_failure2(dev, apdev): | |
672 | """DPP QR Code and authentication exchange (incompatible roles failure 2)""" | |
673 | id1 = run_init_incompatible_roles(dev, role="configurator") | |
674 | with alloc_fail(dev[1], 1, "dpp_auth_resp_rx_status"): | |
5725b3e3 | 675 | dev[1].dpp_auth_init(peer=id1, role="configurator") |
3710b58d JM |
676 | wait_fail_trigger(dev[1], "GET_ALLOC_FAIL") |
677 | ||
678 | def test_dpp_qr_code_auth_incompatible_roles_failure3(dev, apdev): | |
679 | """DPP QR Code and authentication exchange (incompatible roles failure 3)""" | |
680 | id1 = run_init_incompatible_roles(dev, role="configurator") | |
681 | with fail_test(dev[1], 1, "dpp_auth_resp_rx_status"): | |
5725b3e3 | 682 | dev[1].dpp_auth_init(peer=id1, role="configurator") |
203878d7 | 683 | wait_dpp_fail(dev[1], "AES-SIV decryption failed") |
3710b58d | 684 | |
13dc368a JM |
685 | def test_dpp_qr_code_auth_neg_chan(dev, apdev): |
686 | """DPP QR Code and authentication exchange with requested different channel""" | |
687 | check_dpp_capab(dev[0]) | |
688 | check_dpp_capab(dev[1]) | |
e105110f | 689 | conf_id = dev[1].dpp_configurator_add() |
13dc368a | 690 | logger.info("dev0 displays QR Code") |
a5387062 | 691 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
13dc368a | 692 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
5725b3e3 | 693 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 694 | dev[0].dpp_listen(2412) |
5725b3e3 JM |
695 | dev[1].dpp_auth_init(uri=uri0, conf="sta-dpp", neg_freq=2462, |
696 | configurator=conf_id) | |
13dc368a | 697 | |
dbdd445d | 698 | ev = dev[1].wait_event(["DPP-TX "], timeout=5) |
13dc368a JM |
699 | if ev is None: |
700 | raise Exception("DPP Authentication Request not sent") | |
701 | if "freq=2412 type=0" not in ev: | |
702 | raise Exception("Unexpected TX data for Authentication Request: " + ev) | |
703 | ||
704 | ev = dev[0].wait_event(["DPP-RX"], timeout=5) | |
705 | if ev is None: | |
706 | raise Exception("DPP Authentication Request not received") | |
707 | if "freq=2412 type=0" not in ev: | |
708 | raise Exception("Unexpected RX data for Authentication Request: " + ev) | |
709 | ||
710 | ev = dev[1].wait_event(["DPP-TX-STATUS"], timeout=5) | |
711 | if ev is None: | |
712 | raise Exception("TX status for DPP Authentication Request not reported") | |
713 | if "freq=2412 result=SUCCESS" not in ev: | |
714 | raise Exception("Unexpected TX status for Authentication Request: " + ev) | |
715 | ||
dbdd445d | 716 | ev = dev[0].wait_event(["DPP-TX "], timeout=5) |
13dc368a JM |
717 | if ev is None: |
718 | raise Exception("DPP Authentication Response not sent") | |
719 | if "freq=2462 type=1" not in ev: | |
720 | raise Exception("Unexpected TX data for Authentication Response: " + ev) | |
721 | ||
722 | ev = dev[1].wait_event(["DPP-RX"], timeout=5) | |
723 | if ev is None: | |
724 | raise Exception("DPP Authentication Response not received") | |
725 | if "freq=2462 type=1" not in ev: | |
726 | raise Exception("Unexpected RX data for Authentication Response: " + ev) | |
727 | ||
728 | ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=5) | |
729 | if ev is None: | |
730 | raise Exception("TX status for DPP Authentication Response not reported") | |
731 | if "freq=2462 result=SUCCESS" not in ev: | |
732 | raise Exception("Unexpected TX status for Authentication Response: " + ev) | |
733 | ||
dbdd445d | 734 | ev = dev[1].wait_event(["DPP-TX "], timeout=5) |
13dc368a JM |
735 | if ev is None: |
736 | raise Exception("DPP Authentication Confirm not sent") | |
737 | if "freq=2462 type=2" not in ev: | |
738 | raise Exception("Unexpected TX data for Authentication Confirm: " + ev) | |
739 | ||
740 | ev = dev[0].wait_event(["DPP-RX"], timeout=5) | |
741 | if ev is None: | |
742 | raise Exception("DPP Authentication Confirm not received") | |
743 | if "freq=2462 type=2" not in ev: | |
744 | raise Exception("Unexpected RX data for Authentication Confirm: " + ev) | |
745 | ||
746 | ev = dev[1].wait_event(["DPP-TX-STATUS"], timeout=5) | |
747 | if ev is None: | |
748 | raise Exception("TX status for DPP Authentication Confirm not reported") | |
749 | if "freq=2462 result=SUCCESS" not in ev: | |
750 | raise Exception("Unexpected TX status for Authentication Confirm: " + ev) | |
751 | ||
517f76b1 JM |
752 | wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0], |
753 | stop_responder=True) | |
13dc368a | 754 | |
d350084d JM |
755 | def test_dpp_config_legacy(dev, apdev): |
756 | """DPP Config Object for legacy network using passphrase""" | |
757 | check_dpp_capab(dev[1]) | |
758 | conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' | |
759 | dev[1].set("dpp_config_obj_override", conf) | |
760 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
761 | require_conf_success=True) | |
762 | ||
763 | def test_dpp_config_legacy_psk_hex(dev, apdev): | |
764 | """DPP Config Object for legacy network using PSK""" | |
765 | check_dpp_capab(dev[1]) | |
766 | conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","psk_hex":"' + 32*"12" + '"}}' | |
767 | dev[1].set("dpp_config_obj_override", conf) | |
768 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
769 | require_conf_success=True) | |
770 | ||
771 | def test_dpp_config_fragmentation(dev, apdev): | |
772 | """DPP Config Object for legacy network requiring fragmentation""" | |
773 | check_dpp_capab(dev[1]) | |
774 | conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' ' | |
775 | dev[1].set("dpp_config_obj_override", conf) | |
776 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
777 | require_conf_success=True) | |
778 | ||
779 | def test_dpp_config_legacy_gen(dev, apdev): | |
780 | """Generate DPP Config Object for legacy network""" | |
781 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
54c58f29 | 782 | init_extra="conf=sta-psk pass=%s" % binascii.hexlify(b"passphrase").decode(), |
d350084d JM |
783 | require_conf_success=True) |
784 | ||
e6a6de29 JM |
785 | def test_dpp_config_legacy_gen_psk(dev, apdev): |
786 | """Generate DPP Config Object for legacy network (PSK)""" | |
787 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
788 | init_extra="conf=sta-psk psk=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", | |
789 | require_conf_success=True) | |
790 | ||
d350084d JM |
791 | def test_dpp_config_dpp_gen_prime256v1(dev, apdev): |
792 | """Generate DPP Config Object for DPP network (P-256)""" | |
793 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
794 | init_extra="conf=sta-dpp", | |
795 | require_conf_success=True, | |
796 | configurator=True) | |
797 | ||
798 | def test_dpp_config_dpp_gen_secp384r1(dev, apdev): | |
799 | """Generate DPP Config Object for DPP network (P-384)""" | |
800 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1", | |
801 | init_extra="conf=sta-dpp", | |
802 | require_conf_success=True, | |
803 | configurator=True) | |
804 | ||
805 | def test_dpp_config_dpp_gen_secp521r1(dev, apdev): | |
806 | """Generate DPP Config Object for DPP network (P-521)""" | |
807 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1", | |
808 | init_extra="conf=sta-dpp", | |
809 | require_conf_success=True, | |
810 | configurator=True) | |
811 | ||
812 | def test_dpp_config_dpp_gen_prime256v1_prime256v1(dev, apdev): | |
813 | """Generate DPP Config Object for DPP network (P-256 + P-256)""" | |
814 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
815 | init_extra="conf=sta-dpp", | |
816 | require_conf_success=True, | |
817 | configurator=True, | |
818 | conf_curve="prime256v1") | |
819 | ||
820 | def test_dpp_config_dpp_gen_prime256v1_secp384r1(dev, apdev): | |
821 | """Generate DPP Config Object for DPP network (P-256 + P-384)""" | |
822 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
823 | init_extra="conf=sta-dpp", | |
824 | require_conf_success=True, | |
825 | configurator=True, | |
826 | conf_curve="secp384r1") | |
827 | ||
828 | def test_dpp_config_dpp_gen_prime256v1_secp521r1(dev, apdev): | |
829 | """Generate DPP Config Object for DPP network (P-256 + P-521)""" | |
830 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
831 | init_extra="conf=sta-dpp", | |
832 | require_conf_success=True, | |
833 | configurator=True, | |
834 | conf_curve="secp521r1") | |
835 | ||
836 | def test_dpp_config_dpp_gen_secp384r1_prime256v1(dev, apdev): | |
837 | """Generate DPP Config Object for DPP network (P-384 + P-256)""" | |
838 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1", | |
839 | init_extra="conf=sta-dpp", | |
840 | require_conf_success=True, | |
841 | configurator=True, | |
842 | conf_curve="prime256v1") | |
843 | ||
844 | def test_dpp_config_dpp_gen_secp384r1_secp384r1(dev, apdev): | |
845 | """Generate DPP Config Object for DPP network (P-384 + P-384)""" | |
846 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1", | |
847 | init_extra="conf=sta-dpp", | |
848 | require_conf_success=True, | |
849 | configurator=True, | |
850 | conf_curve="secp384r1") | |
851 | ||
852 | def test_dpp_config_dpp_gen_secp384r1_secp521r1(dev, apdev): | |
853 | """Generate DPP Config Object for DPP network (P-384 + P-521)""" | |
854 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1", | |
855 | init_extra="conf=sta-dpp", | |
856 | require_conf_success=True, | |
857 | configurator=True, | |
858 | conf_curve="secp521r1") | |
859 | ||
860 | def test_dpp_config_dpp_gen_secp521r1_prime256v1(dev, apdev): | |
861 | """Generate DPP Config Object for DPP network (P-521 + P-256)""" | |
862 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1", | |
863 | init_extra="conf=sta-dpp", | |
864 | require_conf_success=True, | |
865 | configurator=True, | |
866 | conf_curve="prime256v1") | |
867 | ||
868 | def test_dpp_config_dpp_gen_secp521r1_secp384r1(dev, apdev): | |
869 | """Generate DPP Config Object for DPP network (P-521 + P-384)""" | |
870 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1", | |
871 | init_extra="conf=sta-dpp", | |
872 | require_conf_success=True, | |
873 | configurator=True, | |
874 | conf_curve="secp384r1") | |
875 | ||
876 | def test_dpp_config_dpp_gen_secp521r1_secp521r1(dev, apdev): | |
877 | """Generate DPP Config Object for DPP network (P-521 + P-521)""" | |
878 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1", | |
879 | init_extra="conf=sta-dpp", | |
880 | require_conf_success=True, | |
881 | configurator=True, | |
882 | conf_curve="secp521r1") | |
883 | ||
884 | def test_dpp_config_dpp_gen_expiry(dev, apdev): | |
885 | """Generate DPP Config Object for DPP network with expiry value""" | |
886 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
887 | init_extra="conf=sta-dpp expiry=%d" % (time.time() + 1000), | |
888 | require_conf_success=True, | |
889 | configurator=True) | |
890 | ||
891 | def test_dpp_config_dpp_gen_expired_key(dev, apdev): | |
892 | """Generate DPP Config Object for DPP network with expiry value""" | |
893 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
894 | init_extra="conf=sta-dpp expiry=%d" % (time.time() - 10), | |
895 | require_conf_failure=True, | |
896 | configurator=True) | |
897 | ||
898 | def test_dpp_config_dpp_override_prime256v1(dev, apdev): | |
899 | """DPP Config Object override (P-256)""" | |
900 | check_dpp_capab(dev[0]) | |
901 | check_dpp_capab(dev[1]) | |
902 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"dpp","signedConnector":"eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJUbkdLaklsTlphYXRyRUFZcmJiamlCNjdyamtMX0FHVldYTzZxOWhESktVIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6InN0YSJ9XSwibmV0QWNjZXNzS2V5Ijp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiYVRGNEpFR0lQS1NaMFh2OXpkQ01qbS10bjVYcE1zWUlWWjl3eVNBejFnSSIsInkiOiJRR2NIV0FfNnJiVTlYRFhBenRvWC1NNVEzc3VUbk1hcUVoVUx0bjdTU1h3In19._sm6YswxMf6hJLVTyYoU1uYUeY2VVkUNjrzjSiEhY42StD_RWowStEE-9CRsdCvLmsTptZ72_g40vTFwdId20A","csign":{"kty":"EC","crv":"P-256","x":"W4-Y5N1Pkos3UWb9A5qme0KUYRtY3CVUpekx_MapZ9s","y":"Et-M4NSF4NGjvh2VCh4B1sJ9eSCZ4RNzP2DBdP137VE","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU"}}}' | |
903 | dev[0].set("dpp_ignore_netaccesskey_mismatch", "1") | |
904 | dev[1].set("dpp_config_obj_override", conf) | |
905 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
906 | require_conf_success=True) | |
907 | ||
908 | def test_dpp_config_dpp_override_secp384r1(dev, apdev): | |
909 | """DPP Config Object override (P-384)""" | |
910 | check_dpp_capab(dev[0]) | |
911 | check_dpp_capab(dev[1]) | |
912 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"dpp","signedConnector":"eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJabi1iMndjbjRLM2pGQklkYmhGZkpVTHJTXzdESS0yMWxFQi02R3gxNjl3IiwiYWxnIjoiRVMzODQifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6InN0YSJ9XSwibmV0QWNjZXNzS2V5Ijp7Imt0eSI6IkVDIiwiY3J2IjoiUC0zODQiLCJ4IjoickdrSGg1UUZsOUtfWjdqYUZkVVhmbThoY1RTRjM1b25Xb1NIRXVsbVNzWW9oX1RXZGpoRjhiVGdiS0ZRN2tBViIsInkiOiJBbU1QVDA5VmFENWpGdzMwTUFKQlp2VkZXeGNlVVlKLXR5blQ0bVJ5N0xOZWxhZ0dEWHpfOExaRlpOU2FaNUdLIn19.Yn_F7m-bbOQ5PlaYQJ9-1qsuqYQ6V-rAv8nWw1COKiCYwwbt3WFBJ8DljY0dPrlg5CHJC4saXwkytpI-CpELW1yUdzYb4Lrun07d20Eo_g10ICyOl5sqQCAUElKMe_Xr","csign":{"kty":"EC","crv":"P-384","x":"dmTyXXiPV2Y8a01fujL-jo08gvzyby23XmzOtzjAiujKQZZgPJsbhfEKrZDlc6ey","y":"H5Z0av5c7bqInxYb2_OOJdNiMhVf3zlcULR0516ZZitOY4U31KhL4wl4KGV7g2XW","kid":"Zn-b2wcn4K3jFBIdbhFfJULrS_7DI-21lEB-6Gx169w"}}}' | |
913 | dev[0].set("dpp_ignore_netaccesskey_mismatch", "1") | |
914 | dev[1].set("dpp_config_obj_override", conf) | |
915 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp384r1", | |
916 | require_conf_success=True) | |
917 | ||
918 | def test_dpp_config_dpp_override_secp521r1(dev, apdev): | |
919 | """DPP Config Object override (P-521)""" | |
920 | check_dpp_capab(dev[0]) | |
921 | check_dpp_capab(dev[1]) | |
922 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"dpp","signedConnector":"eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJMZkhKY3hnV2ZKcG1uS2IwenZRT0F2VDB2b0ZKc0JjZnBmYzgxY3Y5ZXFnIiwiYWxnIjoiRVM1MTIifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6InN0YSJ9XSwibmV0QWNjZXNzS2V5Ijp7Imt0eSI6IkVDIiwiY3J2IjoiUC01MjEiLCJ4IjoiQVJlUFBrMFNISkRRR2NWbnlmM3lfbTlaQllHNjFJeElIbDN1NkdwRHVhMkU1WVd4TE1BSUtMMnZuUGtlSGFVRXljRmZaZlpYZ2JlNkViUUxMVkRVUm1VUSIsInkiOiJBWUtaYlNwUkFFNjJVYm9YZ2c1ZWRBVENzbEpzTlpwcm9RR1dUcW9Md04weXkzQkVoT3ZRZmZrOWhaR2lKZ295TzFobXFRRVRrS0pXb2tIYTBCQUpLSGZtIn19.ACEZLyPk13cM_OFScpLoCElQ2t1sxq5z2d_W_3_QslTQQe5SFiH_o8ycL4632YLAH4RV0gZcMKKRMtZdHgBYHjkzASDqgY-_aYN2SBmpfl8hw0YdDlUJWX3DJf-ofqNAlTbnGmhpSg69cEAhFn41Xgvx2MdwYcPVncxxESVOtWl5zNLK","csign":{"kty":"EC","crv":"P-521","x":"ADiOI_YJOAipEXHB-SpGl4KqokX8m8h3BVYCc8dgiwssZ061-nIIY3O1SIO6Re4Jjfy53RPgzDG6jitOgOGLtzZs","y":"AZKggKaQi0ExutSpJAU3-lqDV03sBQLA9C7KabfWoAn8qD6Vk4jU0WAJdt-wBBTF9o1nVuiqS2OxMVYrxN4lOz79","kid":"LfHJcxgWfJpmnKb0zvQOAvT0voFJsBcfpfc81cv9eqg"}}}' | |
923 | dev[0].set("dpp_ignore_netaccesskey_mismatch", "1") | |
924 | dev[1].set("dpp_config_obj_override", conf) | |
925 | run_dpp_qr_code_auth_unicast(dev, apdev, "secp521r1", | |
926 | require_conf_success=True) | |
927 | ||
928 | def test_dpp_config_override_objects(dev, apdev): | |
929 | """Generate DPP Config Object and override objects)""" | |
930 | check_dpp_capab(dev[1]) | |
2e37b5fb | 931 | discovery = '{\n"ssid":"mywifi"\n}' |
d350084d | 932 | groups = '[\n {"groupId":"home","netRole":"sta"},\n {"groupId":"cottage","netRole":"sta"}\n]' |
d350084d JM |
933 | dev[1].set("dpp_discovery_override", discovery) |
934 | dev[1].set("dpp_groups_override", groups) | |
d350084d JM |
935 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", |
936 | init_extra="conf=sta-dpp", | |
937 | require_conf_success=True, | |
938 | configurator=True) | |
939 | ||
30dda44d JM |
940 | def build_conf_obj(kty="EC", crv="P-256", |
941 | x="W4-Y5N1Pkos3UWb9A5qme0KUYRtY3CVUpekx_MapZ9s", | |
942 | y="Et-M4NSF4NGjvh2VCh4B1sJ9eSCZ4RNzP2DBdP137VE", | |
943 | kid="TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU", | |
944 | prot_hdr='{"typ":"dppCon","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU","alg":"ES256"}', | |
945 | signed_connector=None, | |
946 | no_signed_connector=False, | |
947 | csign=True): | |
948 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{' | |
949 | conf += '"akm":"dpp",' | |
950 | ||
951 | if signed_connector: | |
952 | conn = signed_connector | |
953 | conf += '"signedConnector":"%s",' % conn | |
954 | elif not no_signed_connector: | |
955 | payload = '{"groups":[{"groupId":"*","netRole":"sta"}],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}' | |
956 | sign = "_sm6YswxMf6hJLVTyYoU1uYUeY2VVkUNjrzjSiEhY42StD_RWowStEE-9CRsdCvLmsTptZ72_g40vTFwdId20A" | |
c4e333fa MH |
957 | conn = base64.urlsafe_b64encode(prot_hdr.encode()).decode().rstrip('=') + '.' |
958 | conn += base64.urlsafe_b64encode(payload.encode()).decode().rstrip('=') + '.' | |
30dda44d JM |
959 | conn += sign |
960 | conf += '"signedConnector":"%s",' % conn | |
961 | ||
962 | if csign: | |
963 | conf += '"csign":{' | |
964 | if kty: | |
965 | conf += '"kty":"%s",' % kty | |
966 | if crv: | |
967 | conf += '"crv":"%s",' % crv | |
968 | if x: | |
969 | conf += '"x":"%s",' % x | |
970 | if y: | |
971 | conf += '"y":"%s",' % y | |
972 | if kid: | |
973 | conf += '"kid":"%s"' % kid | |
974 | conf = conf.rstrip(',') | |
975 | conf += '}' | |
976 | else: | |
977 | conf = conf.rstrip(',') | |
978 | ||
979 | conf += '}}' | |
980 | ||
981 | return conf | |
982 | ||
fd1534a2 | 983 | def run_dpp_config_error(dev, apdev, conf, |
530b31ea JM |
984 | skip_net_access_key_mismatch=True, |
985 | conf_failure=True): | |
30dda44d JM |
986 | check_dpp_capab(dev[0]) |
987 | check_dpp_capab(dev[1]) | |
fd1534a2 JM |
988 | if skip_net_access_key_mismatch: |
989 | dev[0].set("dpp_ignore_netaccesskey_mismatch", "1") | |
30dda44d JM |
990 | dev[1].set("dpp_config_obj_override", conf) |
991 | run_dpp_qr_code_auth_unicast(dev, apdev, "prime256v1", | |
530b31ea JM |
992 | require_conf_success=not conf_failure, |
993 | require_conf_failure=conf_failure) | |
30dda44d JM |
994 | |
995 | def test_dpp_config_jwk_error_no_kty(dev, apdev): | |
996 | """DPP Config Object JWK error - no kty""" | |
997 | run_dpp_config_error(dev, apdev, build_conf_obj(kty=None)) | |
998 | ||
999 | def test_dpp_config_jwk_error_unexpected_kty(dev, apdev): | |
1000 | """DPP Config Object JWK error - unexpected kty""" | |
1001 | run_dpp_config_error(dev, apdev, build_conf_obj(kty="unknown")) | |
1002 | ||
1003 | def test_dpp_config_jwk_error_no_crv(dev, apdev): | |
1004 | """DPP Config Object JWK error - no crv""" | |
1005 | run_dpp_config_error(dev, apdev, build_conf_obj(crv=None)) | |
1006 | ||
1007 | def test_dpp_config_jwk_error_unsupported_crv(dev, apdev): | |
1008 | """DPP Config Object JWK error - unsupported curve""" | |
1009 | run_dpp_config_error(dev, apdev, build_conf_obj(crv="unsupported")) | |
1010 | ||
1011 | def test_dpp_config_jwk_error_no_x(dev, apdev): | |
1012 | """DPP Config Object JWK error - no x""" | |
1013 | run_dpp_config_error(dev, apdev, build_conf_obj(x=None)) | |
1014 | ||
1015 | def test_dpp_config_jwk_error_invalid_x(dev, apdev): | |
1016 | """DPP Config Object JWK error - invalid x""" | |
1017 | run_dpp_config_error(dev, apdev, build_conf_obj(x="MTIz")) | |
1018 | ||
1019 | def test_dpp_config_jwk_error_no_y(dev, apdev): | |
1020 | """DPP Config Object JWK error - no y""" | |
1021 | run_dpp_config_error(dev, apdev, build_conf_obj(y=None)) | |
1022 | ||
1023 | def test_dpp_config_jwk_error_invalid_y(dev, apdev): | |
1024 | """DPP Config Object JWK error - invalid y""" | |
1025 | run_dpp_config_error(dev, apdev, build_conf_obj(y="MTIz")) | |
1026 | ||
1027 | def test_dpp_config_jwk_error_invalid_xy(dev, apdev): | |
1028 | """DPP Config Object JWK error - invalid x,y""" | |
1029 | conf = build_conf_obj(x="MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY", | |
1030 | y="MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY") | |
1031 | run_dpp_config_error(dev, apdev, conf) | |
1032 | ||
1033 | def test_dpp_config_jwk_error_no_kid(dev, apdev): | |
1034 | """DPP Config Object JWK error - no kid""" | |
530b31ea JM |
1035 | # csign kid is optional field, so this results in success |
1036 | run_dpp_config_error(dev, apdev, build_conf_obj(kid=None), | |
1037 | conf_failure=False) | |
30dda44d JM |
1038 | |
1039 | def test_dpp_config_jws_error_prot_hdr_not_an_object(dev, apdev): | |
1040 | """DPP Config Object JWS error - protected header not an object""" | |
1041 | run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr="1")) | |
1042 | ||
1043 | def test_dpp_config_jws_error_prot_hdr_no_typ(dev, apdev): | |
1044 | """DPP Config Object JWS error - protected header - no typ""" | |
fab49f61 | 1045 | prot_hdr = '{"kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU","alg":"ES256"}' |
30dda44d JM |
1046 | run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr)) |
1047 | ||
1048 | def test_dpp_config_jws_error_prot_hdr_unsupported_typ(dev, apdev): | |
1049 | """DPP Config Object JWS error - protected header - unsupported typ""" | |
fab49f61 | 1050 | prot_hdr = '{"typ":"unsupported","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU","alg":"ES256"}' |
30dda44d JM |
1051 | run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr)) |
1052 | ||
1053 | def test_dpp_config_jws_error_prot_hdr_no_alg(dev, apdev): | |
1054 | """DPP Config Object JWS error - protected header - no alg""" | |
fab49f61 | 1055 | prot_hdr = '{"typ":"dppCon","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU"}' |
30dda44d JM |
1056 | run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr)) |
1057 | ||
1058 | def test_dpp_config_jws_error_prot_hdr_unexpected_alg(dev, apdev): | |
1059 | """DPP Config Object JWS error - protected header - unexpected alg""" | |
fab49f61 | 1060 | prot_hdr = '{"typ":"dppCon","kid":"TnGKjIlNZaatrEAYrbbjiB67rjkL_AGVWXO6q9hDJKU","alg":"unexpected"}' |
30dda44d JM |
1061 | run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr)) |
1062 | ||
1063 | def test_dpp_config_jws_error_prot_hdr_no_kid(dev, apdev): | |
1064 | """DPP Config Object JWS error - protected header - no kid""" | |
fab49f61 | 1065 | prot_hdr = '{"typ":"dppCon","alg":"ES256"}' |
30dda44d JM |
1066 | run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr)) |
1067 | ||
1068 | def test_dpp_config_jws_error_prot_hdr_unexpected_kid(dev, apdev): | |
1069 | """DPP Config Object JWS error - protected header - unexpected kid""" | |
fab49f61 | 1070 | prot_hdr = '{"typ":"dppCon","kid":"MTIz","alg":"ES256"}' |
30dda44d JM |
1071 | run_dpp_config_error(dev, apdev, build_conf_obj(prot_hdr=prot_hdr)) |
1072 | ||
1073 | def test_dpp_config_signed_connector_error_no_dot_1(dev, apdev): | |
1074 | """DPP Config Object signedConnector error - no dot(1)""" | |
1075 | conn = "MTIz" | |
1076 | run_dpp_config_error(dev, apdev, build_conf_obj(signed_connector=conn)) | |
1077 | ||
1078 | def test_dpp_config_signed_connector_error_no_dot_2(dev, apdev): | |
1079 | """DPP Config Object signedConnector error - no dot(2)""" | |
1080 | conn = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJUbkdLaklsTlphYXRyRUFZcmJiamlCNjdyamtMX0FHVldYTzZxOWhESktVIiwiYWxnIjoiRVMyNTYifQ.MTIz" | |
1081 | run_dpp_config_error(dev, apdev, build_conf_obj(signed_connector=conn)) | |
1082 | ||
1083 | def test_dpp_config_signed_connector_error_unexpected_signature_len(dev, apdev): | |
1084 | """DPP Config Object signedConnector error - unexpected signature length""" | |
1085 | conn = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJUbkdLaklsTlphYXRyRUFZcmJiamlCNjdyamtMX0FHVldYTzZxOWhESktVIiwiYWxnIjoiRVMyNTYifQ.MTIz.MTIz" | |
1086 | run_dpp_config_error(dev, apdev, build_conf_obj(signed_connector=conn)) | |
1087 | ||
1088 | def test_dpp_config_signed_connector_error_invalid_signature_der(dev, apdev): | |
1089 | """DPP Config Object signedConnector error - invalid signature DER""" | |
1090 | conn = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJUbkdLaklsTlphYXRyRUFZcmJiamlCNjdyamtMX0FHVldYTzZxOWhESktVIiwiYWxnIjoiRVMyNTYifQ.MTIz.MTI" | |
1091 | run_dpp_config_error(dev, apdev, build_conf_obj(signed_connector=conn)) | |
1092 | ||
1093 | def test_dpp_config_no_csign(dev, apdev): | |
1094 | """DPP Config Object error - no csign""" | |
1095 | run_dpp_config_error(dev, apdev, build_conf_obj(csign=False)) | |
1096 | ||
1097 | def test_dpp_config_no_signed_connector(dev, apdev): | |
1098 | """DPP Config Object error - no signedConnector""" | |
1099 | run_dpp_config_error(dev, apdev, build_conf_obj(no_signed_connector=True)) | |
1100 | ||
1101 | def test_dpp_config_unexpected_signed_connector_char(dev, apdev): | |
1102 | """DPP Config Object error - unexpected signedConnector character""" | |
1103 | run_dpp_config_error(dev, apdev, build_conf_obj(signed_connector='a\nb')) | |
1104 | ||
1105 | def test_dpp_config_root_not_an_object(dev, apdev): | |
1106 | """DPP Config Object error - root not an object""" | |
1107 | conf = "1" | |
1108 | run_dpp_config_error(dev, apdev, conf) | |
1109 | ||
1110 | def test_dpp_config_no_wi_fi_tech(dev, apdev): | |
1111 | """DPP Config Object error - no wi-fi_tech""" | |
1112 | conf = "{}" | |
1113 | run_dpp_config_error(dev, apdev, conf) | |
1114 | ||
1115 | def test_dpp_config_unsupported_wi_fi_tech(dev, apdev): | |
1116 | """DPP Config Object error - unsupported wi-fi_tech""" | |
1117 | conf = '{"wi-fi_tech":"unsupported"}' | |
1118 | run_dpp_config_error(dev, apdev, conf) | |
1119 | ||
1120 | def test_dpp_config_no_discovery(dev, apdev): | |
1121 | """DPP Config Object error - no discovery""" | |
1122 | conf = '{"wi-fi_tech":"infra"}' | |
1123 | run_dpp_config_error(dev, apdev, conf) | |
1124 | ||
1125 | def test_dpp_config_no_discovery_ssid(dev, apdev): | |
1126 | """DPP Config Object error - no discovery::ssid""" | |
1127 | conf = '{"wi-fi_tech":"infra","discovery":{}}' | |
1128 | run_dpp_config_error(dev, apdev, conf) | |
1129 | ||
1130 | def test_dpp_config_too_long_discovery_ssid(dev, apdev): | |
1131 | """DPP Config Object error - too long discovery::ssid""" | |
1132 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"%s"}}' % (33*'A') | |
1133 | run_dpp_config_error(dev, apdev, conf) | |
1134 | ||
1135 | def test_dpp_config_no_cred(dev, apdev): | |
1136 | """DPP Config Object error - no cred""" | |
1137 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"}}' | |
1138 | run_dpp_config_error(dev, apdev, conf) | |
1139 | ||
1140 | def test_dpp_config_no_cred_akm(dev, apdev): | |
1141 | """DPP Config Object error - no cred::akm""" | |
1142 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{}}' | |
1143 | run_dpp_config_error(dev, apdev, conf) | |
1144 | ||
1145 | def test_dpp_config_unsupported_cred_akm(dev, apdev): | |
1146 | """DPP Config Object error - unsupported cred::akm""" | |
1147 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"unsupported"}}' | |
1148 | run_dpp_config_error(dev, apdev, conf) | |
1149 | ||
1150 | def test_dpp_config_error_legacy_no_pass(dev, apdev): | |
1151 | """DPP Config Object legacy error - no pass/psk""" | |
1152 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk"}}' | |
1153 | run_dpp_config_error(dev, apdev, conf) | |
1154 | ||
1155 | def test_dpp_config_error_legacy_too_short_pass(dev, apdev): | |
1156 | """DPP Config Object legacy error - too short pass/psk""" | |
1157 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"1"}}' | |
1158 | run_dpp_config_error(dev, apdev, conf) | |
1159 | ||
1160 | def test_dpp_config_error_legacy_too_long_pass(dev, apdev): | |
1161 | """DPP Config Object legacy error - too long pass/psk""" | |
1162 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"%s"}}' % (64*'A') | |
1163 | run_dpp_config_error(dev, apdev, conf) | |
1164 | ||
1165 | def test_dpp_config_error_legacy_psk_with_sae(dev, apdev): | |
1166 | """DPP Config Object legacy error - psk_hex with SAE""" | |
1167 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"sae","psk_hex":"%s"}}' % (32*"12") | |
1168 | run_dpp_config_error(dev, apdev, conf) | |
1169 | ||
1170 | def test_dpp_config_error_legacy_no_pass_for_sae(dev, apdev): | |
1171 | """DPP Config Object legacy error - no pass for SAE""" | |
1172 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk+sae","psk_hex":"%s"}}' % (32*"12") | |
1173 | run_dpp_config_error(dev, apdev, conf) | |
1174 | ||
1175 | def test_dpp_config_error_legacy_invalid_psk(dev, apdev): | |
1176 | """DPP Config Object legacy error - invalid psk_hex""" | |
1177 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk","psk_hex":"%s"}}' % (32*"qa") | |
1178 | run_dpp_config_error(dev, apdev, conf) | |
1179 | ||
1180 | def test_dpp_config_error_legacy_too_short_psk(dev, apdev): | |
1181 | """DPP Config Object legacy error - too short psk_hex""" | |
1182 | conf = '{"wi-fi_tech":"infra","discovery":{"ssid":"test"},"cred":{"akm":"psk","psk_hex":"%s"}}' % (31*"12") | |
1183 | run_dpp_config_error(dev, apdev, conf) | |
1184 | ||
421d658a JM |
1185 | def get_der_int_32(val): |
1186 | a, b = struct.unpack('BB', val[0:2]) | |
1187 | if a != 0x02: | |
1188 | raise Exception("Invalid DER encoding of INTEGER") | |
1189 | if b > len(val) - 2: | |
1190 | raise Exception("Invalid length of INTEGER (truncated)") | |
1191 | val = val[2:] | |
1192 | if b == 32: | |
1193 | r = val[0:32] | |
1194 | elif b == 33: | |
1195 | if val[0] != 0: | |
1196 | raise Exception("Too large INTEGER (32)") | |
1197 | r = val[1:33] | |
1198 | elif b < 32: | |
1199 | r = (32 - b) * b'\x00' + val[0:b] | |
1200 | else: | |
1201 | raise Exception("Invalid length of INTEGER (32): %d" % b) | |
1202 | return r, val[b:] | |
1203 | ||
fd1534a2 JM |
1204 | def ecdsa_sign(pkey, message, alg="sha256"): |
1205 | sign = OpenSSL.crypto.sign(pkey, message, alg) | |
421d658a | 1206 | logger.debug("sign=" + binascii.hexlify(sign).decode()) |
fab49f61 | 1207 | a, b = struct.unpack('BB', sign[0:2]) |
fd1534a2 JM |
1208 | if a != 0x30: |
1209 | raise Exception("Invalid DER encoding of ECDSA signature") | |
1210 | if b != len(sign) - 2: | |
1211 | raise Exception("Invalid length of ECDSA signature") | |
1212 | sign = sign[2:] | |
1213 | ||
421d658a JM |
1214 | r, sign = get_der_int_32(sign) |
1215 | s, sign = get_der_int_32(sign) | |
fd1534a2 JM |
1216 | if len(sign) != 0: |
1217 | raise Exception("Extra data at the end of ECDSA signature") | |
1218 | ||
421d658a JM |
1219 | logger.info("r=" + binascii.hexlify(r).decode()) |
1220 | logger.info("s=" + binascii.hexlify(s).decode()) | |
fd1534a2 | 1221 | raw_sign = r + s |
c4e333fa | 1222 | return base64.urlsafe_b64encode(raw_sign).decode().rstrip('=') |
fd1534a2 JM |
1223 | |
1224 | p256_priv_key = """-----BEGIN EC PRIVATE KEY----- | |
1225 | MHcCAQEEIBVQij9ah629f1pu3tarDQGQvrzHgAkgYd1jHGiLxNajoAoGCCqGSM49 | |
1226 | AwEHoUQDQgAEAC9d2/JirKu72F2qLuv5jEFMD1Cqu9EiyGk7cOzn/2DJ51p2mEoW | |
1227 | n03N6XRvTC+G7WPol9Ng97NAM2sK57+F/Q== | |
1228 | -----END EC PRIVATE KEY-----""" | |
1229 | p256_pub_key_x = binascii.unhexlify("002f5ddbf262acabbbd85daa2eebf98c414c0f50aabbd122c8693b70ece7ff60") | |
1230 | p256_pub_key_y = binascii.unhexlify("c9e75a76984a169f4dcde9746f4c2f86ed63e897d360f7b340336b0ae7bf85fd") | |
1231 | ||
1232 | def run_dpp_config_connector(dev, apdev, expiry=None, payload=None, | |
530b31ea JM |
1233 | skip_net_access_key_mismatch=True, |
1234 | conf_failure=True): | |
fd1534a2 JM |
1235 | if not openssl_imported: |
1236 | raise HwsimSkip("OpenSSL python method not available") | |
1237 | pkey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, | |
1238 | p256_priv_key) | |
c4e333fa MH |
1239 | x = base64.urlsafe_b64encode(p256_pub_key_x).decode().rstrip('=') |
1240 | y = base64.urlsafe_b64encode(p256_pub_key_y).decode().rstrip('=') | |
fd1534a2 | 1241 | |
c4e333fa MH |
1242 | pubkey = b'\x04' + p256_pub_key_x + p256_pub_key_y |
1243 | kid = base64.urlsafe_b64encode(hashlib.sha256(pubkey).digest()).decode().rstrip('=') | |
fd1534a2 JM |
1244 | |
1245 | prot_hdr = '{"typ":"dppCon","kid":"%s","alg":"ES256"}' % kid | |
1246 | ||
1247 | if not payload: | |
1248 | payload = '{"groups":[{"groupId":"*","netRole":"sta"}],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}' | |
1249 | if expiry: | |
1250 | payload += ',"expiry":"%s"' % expiry | |
1251 | payload += '}' | |
c4e333fa MH |
1252 | conn = base64.urlsafe_b64encode(prot_hdr.encode()).decode().rstrip('=') + '.' |
1253 | conn += base64.urlsafe_b64encode(payload.encode()).decode().rstrip('=') | |
fd1534a2 JM |
1254 | sign = ecdsa_sign(pkey, conn) |
1255 | conn += '.' + sign | |
1256 | run_dpp_config_error(dev, apdev, | |
1257 | build_conf_obj(x=x, y=y, signed_connector=conn), | |
530b31ea JM |
1258 | skip_net_access_key_mismatch=skip_net_access_key_mismatch, |
1259 | conf_failure=conf_failure) | |
fd1534a2 JM |
1260 | |
1261 | def test_dpp_config_connector_error_ext_sign(dev, apdev): | |
1262 | """DPP Config Object connector error - external signature calculation""" | |
530b31ea | 1263 | run_dpp_config_connector(dev, apdev, conf_failure=False) |
fd1534a2 JM |
1264 | |
1265 | def test_dpp_config_connector_error_too_short_timestamp(dev, apdev): | |
1266 | """DPP Config Object connector error - too short timestamp""" | |
1267 | run_dpp_config_connector(dev, apdev, expiry="1") | |
1268 | ||
1269 | def test_dpp_config_connector_error_invalid_timestamp(dev, apdev): | |
1270 | """DPP Config Object connector error - invalid timestamp""" | |
1271 | run_dpp_config_connector(dev, apdev, expiry=19*"1") | |
1272 | ||
1273 | def test_dpp_config_connector_error_invalid_timestamp_date(dev, apdev): | |
1274 | """DPP Config Object connector error - invalid timestamp date""" | |
1275 | run_dpp_config_connector(dev, apdev, expiry="9999-99-99T99:99:99Z") | |
1276 | ||
1277 | def test_dpp_config_connector_error_invalid_time_zone(dev, apdev): | |
1278 | """DPP Config Object connector error - invalid time zone""" | |
1279 | run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00*") | |
1280 | ||
1281 | def test_dpp_config_connector_error_invalid_time_zone_2(dev, apdev): | |
1282 | """DPP Config Object connector error - invalid time zone 2""" | |
1283 | run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00+") | |
1284 | ||
1285 | def test_dpp_config_connector_error_expired_1(dev, apdev): | |
1286 | """DPP Config Object connector error - expired 1""" | |
1287 | run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00") | |
1288 | ||
1289 | def test_dpp_config_connector_error_expired_2(dev, apdev): | |
1290 | """DPP Config Object connector error - expired 2""" | |
1291 | run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00Z") | |
1292 | ||
1293 | def test_dpp_config_connector_error_expired_3(dev, apdev): | |
1294 | """DPP Config Object connector error - expired 3""" | |
1295 | run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00+01") | |
1296 | ||
1297 | def test_dpp_config_connector_error_expired_4(dev, apdev): | |
1298 | """DPP Config Object connector error - expired 4""" | |
1299 | run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00+01:02") | |
1300 | ||
1301 | def test_dpp_config_connector_error_expired_5(dev, apdev): | |
1302 | """DPP Config Object connector error - expired 5""" | |
1303 | run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00-01") | |
1304 | ||
1305 | def test_dpp_config_connector_error_expired_6(dev, apdev): | |
1306 | """DPP Config Object connector error - expired 6""" | |
1307 | run_dpp_config_connector(dev, apdev, expiry="2018-01-01T00:00:00-01:02") | |
1308 | ||
1309 | def test_dpp_config_connector_error_no_groups(dev, apdev): | |
1310 | """DPP Config Object connector error - no groups""" | |
1311 | payload = '{"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}' | |
1312 | run_dpp_config_connector(dev, apdev, payload=payload) | |
1313 | ||
1314 | def test_dpp_config_connector_error_empty_groups(dev, apdev): | |
1315 | """DPP Config Object connector error - empty groups""" | |
1316 | payload = '{"groups":[],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}' | |
1317 | run_dpp_config_connector(dev, apdev, payload=payload) | |
1318 | ||
1319 | def test_dpp_config_connector_error_missing_group_id(dev, apdev): | |
1320 | """DPP Config Object connector error - missing groupId""" | |
1321 | payload = '{"groups":[{"netRole":"sta"}],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}' | |
1322 | run_dpp_config_connector(dev, apdev, payload=payload) | |
1323 | ||
1324 | def test_dpp_config_connector_error_missing_net_role(dev, apdev): | |
1325 | """DPP Config Object connector error - missing netRole""" | |
1326 | payload = '{"groups":[{"groupId":"*"}],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}' | |
1327 | run_dpp_config_connector(dev, apdev, payload=payload) | |
1328 | ||
1329 | def test_dpp_config_connector_error_missing_net_access_key(dev, apdev): | |
1330 | """DPP Config Object connector error - missing netAccessKey""" | |
1331 | payload = '{"groups":[{"groupId":"*","netRole":"sta"}]}' | |
1332 | run_dpp_config_connector(dev, apdev, payload=payload) | |
1333 | ||
1334 | def test_dpp_config_connector_error_net_access_key_mismatch(dev, apdev): | |
1335 | """DPP Config Object connector error - netAccessKey mismatch""" | |
1336 | payload = '{"groups":[{"groupId":"*","netRole":"sta"}],"netAccessKey":{"kty":"EC","crv":"P-256","x":"aTF4JEGIPKSZ0Xv9zdCMjm-tn5XpMsYIVZ9wySAz1gI","y":"QGcHWA_6rbU9XDXAztoX-M5Q3suTnMaqEhULtn7SSXw"}}' | |
1337 | run_dpp_config_connector(dev, apdev, payload=payload, | |
1338 | skip_net_access_key_mismatch=False) | |
1339 | ||
d350084d JM |
1340 | def test_dpp_gas_timeout(dev, apdev): |
1341 | """DPP and GAS server timeout for a query""" | |
1342 | check_dpp_capab(dev[0]) | |
1343 | check_dpp_capab(dev[1]) | |
1344 | logger.info("dev0 displays QR Code") | |
a5387062 | 1345 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
d350084d JM |
1346 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
1347 | ||
5725b3e3 | 1348 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
d350084d | 1349 | dev[0].set("ext_mgmt_frame_handling", "1") |
7e009100 | 1350 | dev[0].dpp_listen(2412) |
d350084d JM |
1351 | |
1352 | # Force GAS fragmentation | |
1353 | conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' ' | |
1354 | dev[1].set("dpp_config_obj_override", conf) | |
1355 | ||
5725b3e3 | 1356 | dev[1].dpp_auth_init(uri=uri0) |
d350084d JM |
1357 | |
1358 | # DPP Authentication Request | |
1359 | msg = dev[0].mgmt_rx() | |
54c58f29 MH |
1360 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format( |
1361 | msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())): | |
d350084d JM |
1362 | raise Exception("MGMT_RX_PROCESS failed") |
1363 | ||
1364 | # DPP Authentication Confirmation | |
1365 | msg = dev[0].mgmt_rx() | |
54c58f29 MH |
1366 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format( |
1367 | msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())): | |
d350084d JM |
1368 | raise Exception("MGMT_RX_PROCESS failed") |
1369 | ||
517f76b1 | 1370 | wait_auth_success(dev[0], dev[1]) |
d350084d JM |
1371 | |
1372 | # DPP Configuration Response (GAS Initial Response frame) | |
1373 | msg = dev[0].mgmt_rx() | |
54c58f29 MH |
1374 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format( |
1375 | msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())): | |
d350084d JM |
1376 | raise Exception("MGMT_RX_PROCESS failed") |
1377 | ||
1378 | # GAS Comeback Response frame | |
1379 | msg = dev[0].mgmt_rx() | |
1380 | # Do not continue to force timeout on GAS server | |
1381 | ||
1382 | ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=10) | |
1383 | if ev is None: | |
1384 | raise Exception("GAS result not reported (Enrollee)") | |
1385 | if "result=TIMEOUT" not in ev: | |
1386 | raise Exception("Unexpected GAS result (Enrollee): " + ev) | |
1387 | dev[0].set("ext_mgmt_frame_handling", "0") | |
1388 | ||
1389 | ev = dev[1].wait_event(["DPP-CONF-FAILED"], timeout=15) | |
1390 | if ev is None: | |
1391 | raise Exception("DPP configuration failure not reported (Configurator)") | |
1392 | ||
1393 | ev = dev[0].wait_event(["DPP-CONF-FAILED"], timeout=1) | |
1394 | if ev is None: | |
1395 | raise Exception("DPP configuration failure not reported (Enrollee)") | |
1396 | ||
1397 | def test_dpp_akm_sha256(dev, apdev): | |
1398 | """DPP AKM (SHA256)""" | |
1399 | run_dpp_akm(dev, apdev, 32) | |
1400 | ||
1401 | def test_dpp_akm_sha384(dev, apdev): | |
1402 | """DPP AKM (SHA384)""" | |
1403 | run_dpp_akm(dev, apdev, 48) | |
1404 | ||
1405 | def test_dpp_akm_sha512(dev, apdev): | |
1406 | """DPP AKM (SHA512)""" | |
1407 | run_dpp_akm(dev, apdev, 64) | |
1408 | ||
1409 | def run_dpp_akm(dev, apdev, pmk_len): | |
1410 | check_dpp_capab(dev[0]) | |
1411 | check_dpp_capab(dev[1]) | |
fab49f61 JM |
1412 | params = {"ssid": "dpp", |
1413 | "wpa": "2", | |
1414 | "wpa_key_mgmt": "DPP", | |
1415 | "rsn_pairwise": "CCMP", | |
1416 | "ieee80211w": "2"} | |
d350084d JM |
1417 | try: |
1418 | hapd = hostapd.add_ap(apdev[0], params) | |
1419 | except: | |
1420 | raise HwsimSkip("DPP not supported") | |
1421 | ||
299196c4 | 1422 | id = dev[0].connect("dpp", key_mgmt="DPP", ieee80211w="2", scan_freq="2412", |
d350084d JM |
1423 | wait_connect=False) |
1424 | ev = dev[0].wait_event(["CTRL-EVENT-NETWORK-NOT-FOUND"], timeout=2) | |
1425 | if not ev: | |
1426 | raise Exception("Network mismatch not reported") | |
1427 | dev[0].request("DISCONNECT") | |
1428 | dev[0].dump_monitor() | |
1429 | ||
1430 | bssid = hapd.own_addr() | |
1431 | pmkid = 16*'11' | |
1432 | akmp = 2**23 | |
1433 | pmk = pmk_len*'22' | |
1434 | cmd = "PMKSA_ADD %d %s %s %s 30240 43200 %d 0" % (id, bssid, pmkid, pmk, akmp) | |
1435 | if "OK" not in dev[0].request(cmd): | |
1436 | raise Exception("PMKSA_ADD failed (wpa_supplicant)") | |
1437 | dev[0].select_network(id, freq="2412") | |
1438 | ev = dev[0].wait_event(["CTRL-EVENT-ASSOC-REJECT"], timeout=2) | |
1439 | dev[0].request("DISCONNECT") | |
1440 | dev[0].dump_monitor() | |
1441 | if not ev: | |
1442 | raise Exception("Association attempt was not rejected") | |
1443 | if "status_code=53" not in ev: | |
1444 | raise Exception("Unexpected status code: " + ev) | |
1445 | ||
1446 | addr = dev[0].own_addr() | |
1447 | cmd = "PMKSA_ADD %s %s %s 0 %d" % (addr, pmkid, pmk, akmp) | |
1448 | if "OK" not in hapd.request(cmd): | |
1449 | raise Exception("PMKSA_ADD failed (hostapd)") | |
1450 | ||
1451 | dev[0].select_network(id, freq="2412") | |
1452 | dev[0].wait_connected() | |
0f842044 JM |
1453 | val = dev[0].get_status_field("key_mgmt") |
1454 | if val != "DPP": | |
1455 | raise Exception("Unexpected key_mgmt: " + val) | |
d350084d | 1456 | |
7e26f1bc JM |
1457 | params1_csign = "3059301306072a8648ce3d020106082a8648ce3d03010703420004d02e5bd81a120762b5f0f2994777f5d40297238a6c294fd575cdf35fabec44c050a6421c401d98d659fd2ed13c961cc8287944dd3202f516977800d3ab2f39ee" |
1458 | params1_ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJzOEFrYjg5bTV4UGhoYk5UbTVmVVo0eVBzNU5VMkdxYXNRY3hXUWhtQVFRIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIwOHF4TlNYRzRWemdCV3BjVUdNSmc1czNvbElOVFJsRVQ1aERpNkRKY3ZjIiwieSI6IlVhaGFYQXpKRVpRQk1YaHRUQnlZZVlrOWtJYjk5UDA3UV9NcW9TVVZTVEkifX0.a5_nfMVr7Qe1SW0ZL3u6oQRm5NUCYUSfixDAJOUFN3XUfECBZ6E8fm8xjeSfdOytgRidTz0CTlIRjzPQo82dmQ" | |
1459 | params1_ap_netaccesskey = "30770201010420f6531d17f29dfab655b7c9e923478d5a345164c489aadd44a3519c3e9dcc792da00a06082a8648ce3d030107a14403420004d3cab13525c6e15ce0056a5c506309839b37a2520d4d19444f98438ba0c972f751a85a5c0cc911940131786d4c1c9879893d9086fdf4fd3b43f32aa125154932" | |
1460 | params1_sta_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJzOEFrYjg5bTV4UGhoYk5UbTVmVVo0eVBzNU5VMkdxYXNRY3hXUWhtQVFRIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6InN0YSJ9XSwibmV0QWNjZXNzS2V5Ijp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiZWMzR3NqQ3lQMzVBUUZOQUJJdEltQnN4WXVyMGJZX1dES1lfSE9zUGdjNCIsInkiOiJTRS1HVllkdWVnTFhLMU1TQXZNMEx2QWdLREpTNWoyQVhCbE9PMTdUSTRBIn19.PDK9zsGlK-e1pEOmNxVeJfCS8pNeay6ckIS1TXCQsR64AR-9wFPCNVjqOxWvVKltehyMFqVAtOcv0IrjtMJFqQ" | |
1461 | params1_sta_netaccesskey = "30770201010420bc33380c26fd2168b69cd8242ed1df07ba89aa4813f8d4e8523de6ca3f8dd28ba00a06082a8648ce3d030107a1440342000479cdc6b230b23f7e40405340048b48981b3162eaf46d8fd60ca63f1ceb0f81ce484f8655876e7a02d72b531202f3342ef020283252e63d805c194e3b5ed32380" | |
1462 | ||
d350084d JM |
1463 | def test_dpp_network_introduction(dev, apdev): |
1464 | """DPP network introduction""" | |
1465 | check_dpp_capab(dev[0]) | |
1466 | check_dpp_capab(dev[1]) | |
1467 | ||
fab49f61 JM |
1468 | params = {"ssid": "dpp", |
1469 | "wpa": "2", | |
1470 | "wpa_key_mgmt": "DPP", | |
1471 | "ieee80211w": "2", | |
1472 | "rsn_pairwise": "CCMP", | |
1473 | "dpp_connector": params1_ap_connector, | |
1474 | "dpp_csign": params1_csign, | |
1475 | "dpp_netaccesskey": params1_ap_netaccesskey} | |
d350084d JM |
1476 | try: |
1477 | hapd = hostapd.add_ap(apdev[0], params) | |
1478 | except: | |
1479 | raise HwsimSkip("DPP not supported") | |
1480 | ||
1481 | id = dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", | |
299196c4 | 1482 | ieee80211w="2", |
7e26f1bc JM |
1483 | dpp_csign=params1_csign, |
1484 | dpp_connector=params1_sta_connector, | |
1485 | dpp_netaccesskey=params1_sta_netaccesskey) | |
0f842044 JM |
1486 | val = dev[0].get_status_field("key_mgmt") |
1487 | if val != "DPP": | |
1488 | raise Exception("Unexpected key_mgmt: " + val) | |
d350084d | 1489 | |
ba2d5f36 JM |
1490 | def test_dpp_network_introduction_expired(dev, apdev): |
1491 | """DPP network introduction with expired netaccesskey""" | |
1492 | check_dpp_capab(dev[0]) | |
1493 | check_dpp_capab(dev[1]) | |
1494 | ||
1495 | params = {"ssid": "dpp", | |
1496 | "wpa": "2", | |
1497 | "wpa_key_mgmt": "DPP", | |
1498 | "ieee80211w": "2", | |
1499 | "rsn_pairwise": "CCMP", | |
1500 | "dpp_connector": params1_ap_connector, | |
1501 | "dpp_csign": params1_csign, | |
1502 | "dpp_netaccesskey": params1_ap_netaccesskey, | |
1503 | "dpp_netaccesskey_expiry": "1565530889"} | |
1504 | try: | |
1505 | hapd = hostapd.add_ap(apdev[0], params) | |
1506 | except: | |
1507 | raise HwsimSkip("DPP not supported") | |
1508 | ||
1509 | dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", | |
1510 | ieee80211w="2", | |
1511 | dpp_csign=params1_csign, | |
1512 | dpp_connector=params1_sta_connector, | |
1513 | dpp_netaccesskey=params1_sta_netaccesskey, | |
1514 | wait_connect=False) | |
1515 | ev = hapd.wait_event(["DPP-RX"], timeout=10) | |
1516 | if ev is None: | |
1517 | raise Exception("No DPP Peer Discovery Request seen") | |
1518 | if "type=5" not in ev: | |
1519 | raise Exception("Unexpected DPP message received: " + ev) | |
1520 | ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) | |
1521 | dev[0].request("DISCONNECT") | |
1522 | if ev: | |
1523 | raise Exception("Connection reported") | |
1524 | ||
1525 | hapd.disable() | |
1526 | hapd.set("dpp_netaccesskey_expiry", "2565530889") | |
1527 | hapd.enable() | |
1528 | dev[0].request("RECONNECT") | |
1529 | dev[0].wait_connected() | |
1530 | ||
e5b0b58b JM |
1531 | def test_dpp_and_sae_akm(dev, apdev): |
1532 | """DPP and SAE AKMs""" | |
1533 | check_dpp_capab(dev[0]) | |
1534 | check_dpp_capab(dev[1]) | |
1535 | if "SAE" not in dev[1].get_capability("auth_alg"): | |
1536 | raise HwsimSkip("SAE not supported") | |
1537 | ||
fab49f61 JM |
1538 | params = {"ssid": "dpp+sae", |
1539 | "wpa": "2", | |
1540 | "wpa_key_mgmt": "DPP SAE", | |
1541 | "ieee80211w": "2", | |
1542 | "rsn_pairwise": "CCMP", | |
1543 | "sae_password": "sae-password", | |
1544 | "dpp_connector": params1_ap_connector, | |
1545 | "dpp_csign": params1_csign, | |
1546 | "dpp_netaccesskey": params1_ap_netaccesskey} | |
e5b0b58b JM |
1547 | try: |
1548 | hapd = hostapd.add_ap(apdev[0], params) | |
1549 | except: | |
1550 | raise HwsimSkip("DPP not supported") | |
1551 | ||
1552 | id = dev[0].connect("dpp+sae", key_mgmt="DPP", scan_freq="2412", | |
1553 | ieee80211w="2", | |
7e26f1bc JM |
1554 | dpp_csign=params1_csign, |
1555 | dpp_connector=params1_sta_connector, | |
1556 | dpp_netaccesskey=params1_sta_netaccesskey) | |
e5b0b58b JM |
1557 | val = dev[0].get_status_field("key_mgmt") |
1558 | if val != "DPP": | |
1559 | raise Exception("Unexpected key_mgmt for DPP: " + val) | |
1560 | ||
c9ead82d | 1561 | dev[1].request("SET sae_groups ") |
e5b0b58b JM |
1562 | id = dev[1].connect("dpp+sae", key_mgmt="SAE", scan_freq="2412", |
1563 | ieee80211w="2", psk="sae-password") | |
1564 | val = dev[1].get_status_field("key_mgmt") | |
1565 | if val != "SAE": | |
1566 | raise Exception("Unexpected key_mgmt for SAE: " + val) | |
1567 | ||
d350084d JM |
1568 | def test_dpp_ap_config(dev, apdev): |
1569 | """DPP and AP configuration""" | |
1570 | run_dpp_ap_config(dev, apdev) | |
1571 | ||
1572 | def test_dpp_ap_config_p256_p256(dev, apdev): | |
1573 | """DPP and AP configuration (P-256 + P-256)""" | |
1574 | run_dpp_ap_config(dev, apdev, curve="P-256", conf_curve="P-256") | |
1575 | ||
1576 | def test_dpp_ap_config_p256_p384(dev, apdev): | |
1577 | """DPP and AP configuration (P-256 + P-384)""" | |
1578 | run_dpp_ap_config(dev, apdev, curve="P-256", conf_curve="P-384") | |
1579 | ||
1580 | def test_dpp_ap_config_p256_p521(dev, apdev): | |
1581 | """DPP and AP configuration (P-256 + P-521)""" | |
1582 | run_dpp_ap_config(dev, apdev, curve="P-256", conf_curve="P-521") | |
1583 | ||
1584 | def test_dpp_ap_config_p384_p256(dev, apdev): | |
1585 | """DPP and AP configuration (P-384 + P-256)""" | |
1586 | run_dpp_ap_config(dev, apdev, curve="P-384", conf_curve="P-256") | |
1587 | ||
1588 | def test_dpp_ap_config_p384_p384(dev, apdev): | |
1589 | """DPP and AP configuration (P-384 + P-384)""" | |
1590 | run_dpp_ap_config(dev, apdev, curve="P-384", conf_curve="P-384") | |
1591 | ||
1592 | def test_dpp_ap_config_p384_p521(dev, apdev): | |
1593 | """DPP and AP configuration (P-384 + P-521)""" | |
1594 | run_dpp_ap_config(dev, apdev, curve="P-384", conf_curve="P-521") | |
1595 | ||
1596 | def test_dpp_ap_config_p521_p256(dev, apdev): | |
1597 | """DPP and AP configuration (P-521 + P-256)""" | |
1598 | run_dpp_ap_config(dev, apdev, curve="P-521", conf_curve="P-256") | |
1599 | ||
1600 | def test_dpp_ap_config_p521_p384(dev, apdev): | |
1601 | """DPP and AP configuration (P-521 + P-384)""" | |
1602 | run_dpp_ap_config(dev, apdev, curve="P-521", conf_curve="P-384") | |
1603 | ||
1604 | def test_dpp_ap_config_p521_p521(dev, apdev): | |
1605 | """DPP and AP configuration (P-521 + P-521)""" | |
1606 | run_dpp_ap_config(dev, apdev, curve="P-521", conf_curve="P-521") | |
1607 | ||
84438350 JM |
1608 | def test_dpp_ap_config_bp256_bp256(dev, apdev): |
1609 | """DPP and AP configuration (BP-256 + BP-256)""" | |
1610 | run_dpp_ap_config(dev, apdev, curve="BP-256", conf_curve="BP-256") | |
1611 | ||
1612 | def test_dpp_ap_config_bp384_bp384(dev, apdev): | |
1613 | """DPP and AP configuration (BP-384 + BP-384)""" | |
1614 | run_dpp_ap_config(dev, apdev, curve="BP-384", conf_curve="BP-384") | |
1615 | ||
1616 | def test_dpp_ap_config_bp512_bp512(dev, apdev): | |
1617 | """DPP and AP configuration (BP-512 + BP-512)""" | |
1618 | run_dpp_ap_config(dev, apdev, curve="BP-512", conf_curve="BP-512") | |
1619 | ||
1620 | def test_dpp_ap_config_p256_bp256(dev, apdev): | |
1621 | """DPP and AP configuration (P-256 + BP-256)""" | |
1622 | run_dpp_ap_config(dev, apdev, curve="P-256", conf_curve="BP-256") | |
1623 | ||
1624 | def test_dpp_ap_config_bp256_p256(dev, apdev): | |
1625 | """DPP and AP configuration (BP-256 + P-256)""" | |
1626 | run_dpp_ap_config(dev, apdev, curve="BP-256", conf_curve="P-256") | |
1627 | ||
1628 | def test_dpp_ap_config_p521_bp512(dev, apdev): | |
1629 | """DPP and AP configuration (P-521 + BP-512)""" | |
1630 | run_dpp_ap_config(dev, apdev, curve="P-521", conf_curve="BP-512") | |
1631 | ||
1632 | def test_dpp_ap_config_bp512_p521(dev, apdev): | |
1633 | """DPP and AP configuration (BP-512 + P-521)""" | |
1634 | run_dpp_ap_config(dev, apdev, curve="BP-512", conf_curve="P-521") | |
1635 | ||
0c061630 JM |
1636 | def test_dpp_ap_config_reconfig_configurator(dev, apdev): |
1637 | """DPP and AP configuration with Configurator reconfiguration""" | |
1638 | run_dpp_ap_config(dev, apdev, reconf_configurator=True) | |
1639 | ||
854d0de3 JM |
1640 | def update_hapd_config(hapd): |
1641 | ev = hapd.wait_event(["DPP-CONFOBJ-SSID"], timeout=1) | |
1642 | if ev is None: | |
1643 | raise Exception("SSID not reported (AP)") | |
1644 | ssid = ev.split(' ')[1] | |
1645 | ||
1646 | ev = hapd.wait_event(["DPP-CONNECTOR"], timeout=1) | |
1647 | if ev is None: | |
1648 | raise Exception("Connector not reported (AP)") | |
1649 | connector = ev.split(' ')[1] | |
1650 | ||
1651 | ev = hapd.wait_event(["DPP-C-SIGN-KEY"], timeout=1) | |
1652 | if ev is None: | |
1653 | raise Exception("C-sign-key not reported (AP)") | |
1654 | p = ev.split(' ') | |
1655 | csign = p[1] | |
854d0de3 JM |
1656 | |
1657 | ev = hapd.wait_event(["DPP-NET-ACCESS-KEY"], timeout=1) | |
1658 | if ev is None: | |
1659 | raise Exception("netAccessKey not reported (AP)") | |
1660 | p = ev.split(' ') | |
1661 | net_access_key = p[1] | |
1662 | net_access_key_expiry = p[2] if len(p) > 2 else None | |
1663 | ||
1664 | logger.info("Update AP configuration to use key_mgmt=DPP") | |
1665 | hapd.disable() | |
1666 | hapd.set("ssid", ssid) | |
e0cd7172 | 1667 | hapd.set("utf8_ssid", "1") |
854d0de3 JM |
1668 | hapd.set("wpa", "2") |
1669 | hapd.set("wpa_key_mgmt", "DPP") | |
299196c4 | 1670 | hapd.set("ieee80211w", "2") |
854d0de3 JM |
1671 | hapd.set("rsn_pairwise", "CCMP") |
1672 | hapd.set("dpp_connector", connector) | |
1673 | hapd.set("dpp_csign", csign) | |
854d0de3 JM |
1674 | hapd.set("dpp_netaccesskey", net_access_key) |
1675 | if net_access_key_expiry: | |
1676 | hapd.set("dpp_netaccesskey_expiry", net_access_key_expiry) | |
1677 | hapd.enable() | |
1678 | ||
0c061630 JM |
1679 | def run_dpp_ap_config(dev, apdev, curve=None, conf_curve=None, |
1680 | reconf_configurator=False): | |
d350084d JM |
1681 | check_dpp_capab(dev[0]) |
1682 | check_dpp_capab(dev[1]) | |
fab49f61 | 1683 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"}) |
d350084d JM |
1684 | check_dpp_capab(hapd) |
1685 | ||
a5387062 | 1686 | id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True, curve=curve) |
d350084d JM |
1687 | uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h) |
1688 | ||
e105110f | 1689 | conf_id = dev[0].dpp_configurator_add(curve=conf_curve) |
d350084d | 1690 | |
0c061630 JM |
1691 | if reconf_configurator: |
1692 | csign = dev[0].request("DPP_CONFIGURATOR_GET_KEY %d" % conf_id) | |
1693 | if "FAIL" in csign or len(csign) == 0: | |
1694 | raise Exception("DPP_CONFIGURATOR_GET_KEY failed") | |
1695 | ||
5725b3e3 | 1696 | dev[0].dpp_auth_init(uri=uri, conf="ap-dpp", configurator=conf_id) |
517f76b1 | 1697 | wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd) |
854d0de3 | 1698 | update_hapd_config(hapd) |
d350084d | 1699 | |
a5387062 | 1700 | id1 = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True, curve=curve) |
d350084d JM |
1701 | uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1) |
1702 | ||
0c061630 | 1703 | if reconf_configurator: |
e105110f JM |
1704 | dev[0].dpp_configurator_remove(conf_id) |
1705 | conf_id = dev[0].dpp_configurator_add(curve=conf_curve, key=csign) | |
0c061630 | 1706 | |
7e009100 | 1707 | dev[1].dpp_listen(2412) |
5725b3e3 | 1708 | dev[0].dpp_auth_init(uri=uri1, conf="sta-dpp", configurator=conf_id) |
517f76b1 JM |
1709 | wait_auth_success(dev[1], dev[0], configurator=dev[0], enrollee=dev[1], |
1710 | stop_responder=True) | |
d350084d JM |
1711 | |
1712 | ev = dev[1].wait_event(["DPP-CONFOBJ-SSID"], timeout=1) | |
1713 | if ev is None: | |
1714 | raise Exception("SSID not reported") | |
1715 | ssid = ev.split(' ')[1] | |
1716 | ||
1717 | ev = dev[1].wait_event(["DPP-CONNECTOR"], timeout=1) | |
1718 | if ev is None: | |
1719 | raise Exception("Connector not reported") | |
1720 | connector = ev.split(' ')[1] | |
1721 | ||
1722 | ev = dev[1].wait_event(["DPP-C-SIGN-KEY"], timeout=1) | |
1723 | if ev is None: | |
1724 | raise Exception("C-sign-key not reported") | |
1725 | p = ev.split(' ') | |
1726 | csign = p[1] | |
d350084d JM |
1727 | |
1728 | ev = dev[1].wait_event(["DPP-NET-ACCESS-KEY"], timeout=1) | |
1729 | if ev is None: | |
1730 | raise Exception("netAccessKey not reported") | |
1731 | p = ev.split(' ') | |
1732 | net_access_key = p[1] | |
1733 | net_access_key_expiry = p[2] if len(p) > 2 else None | |
1734 | ||
1735 | dev[1].dump_monitor() | |
1736 | ||
299196c4 | 1737 | id = dev[1].connect(ssid, key_mgmt="DPP", ieee80211w="2", scan_freq="2412", |
d350084d JM |
1738 | only_add_network=True) |
1739 | dev[1].set_network_quoted(id, "dpp_connector", connector) | |
1740 | dev[1].set_network(id, "dpp_csign", csign) | |
d350084d JM |
1741 | dev[1].set_network(id, "dpp_netaccesskey", net_access_key) |
1742 | if net_access_key_expiry: | |
1743 | dev[1].set_network(id, "dpp_netaccess_expiry", net_access_key_expiry) | |
1744 | ||
1745 | logger.info("Check data connection") | |
1746 | dev[1].select_network(id, freq="2412") | |
1747 | dev[1].wait_connected() | |
cd29045b JM |
1748 | |
1749 | def test_dpp_auto_connect_1(dev, apdev): | |
1750 | """DPP and auto connect (1)""" | |
1751 | try: | |
1752 | run_dpp_auto_connect(dev, apdev, 1) | |
1753 | finally: | |
5bf51d38 | 1754 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
cd29045b JM |
1755 | |
1756 | def test_dpp_auto_connect_2(dev, apdev): | |
1757 | """DPP and auto connect (2)""" | |
1758 | try: | |
1759 | run_dpp_auto_connect(dev, apdev, 2) | |
1760 | finally: | |
5bf51d38 | 1761 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
cd29045b | 1762 | |
ee8ef9ca JM |
1763 | def test_dpp_auto_connect_2_connect_cmd(dev, apdev): |
1764 | """DPP and auto connect (2) using connect_cmd""" | |
1765 | wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') | |
1766 | wpas.interface_add("wlan5", drv_params="force_connect_cmd=1") | |
fab49f61 | 1767 | dev_new = [wpas, dev[1]] |
ee8ef9ca JM |
1768 | try: |
1769 | run_dpp_auto_connect(dev_new, apdev, 2) | |
1770 | finally: | |
5bf51d38 | 1771 | wpas.set("dpp_config_processing", "0", allow_fail=True) |
ee8ef9ca | 1772 | |
cd29045b JM |
1773 | def run_dpp_auto_connect(dev, apdev, processing): |
1774 | check_dpp_capab(dev[0]) | |
1775 | check_dpp_capab(dev[1]) | |
1776 | ||
1777 | csign = "30770201010420768240a3fc89d6662d9782f120527fe7fb9edc6366ab0b9c7dde96125cfd250fa00a06082a8648ce3d030107a144034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708" | |
1778 | csign_pub = "3059301306072a8648ce3d020106082a8648ce3d030107034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708" | |
1779 | ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJwYWtZbXVzd1dCdWpSYTl5OEsweDViaTVrT3VNT3dzZHRlaml2UG55ZHZzIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIybU5vNXZuRkI5bEw3d1VWb1hJbGVPYzBNSEE1QXZKbnpwZXZULVVTYzVNIiwieSI6IlhzS3dqVHJlLTg5WWdpU3pKaG9CN1haeUttTU05OTl3V2ZaSVl0bi01Q3MifX0.XhjFpZgcSa7G2lHy0OCYTvaZFRo5Hyx6b7g7oYyusLC7C_73AJ4_BxEZQVYJXAtDuGvb3dXSkHEKxREP9Q6Qeg" | |
1780 | ap_netaccesskey = "30770201010420ceba752db2ad5200fa7bc565b9c05c69b7eb006751b0b329b0279de1c19ca67ca00a06082a8648ce3d030107a14403420004da6368e6f9c507d94bef0515a1722578e73430703902f267ce97af4fe51273935ec2b08d3adefbcf588224b3261a01ed76722a630cf7df7059f64862d9fee42b" | |
1781 | ||
fab49f61 JM |
1782 | params = {"ssid": "test", |
1783 | "wpa": "2", | |
1784 | "wpa_key_mgmt": "DPP", | |
1785 | "ieee80211w": "2", | |
1786 | "rsn_pairwise": "CCMP", | |
1787 | "dpp_connector": ap_connector, | |
1788 | "dpp_csign": csign_pub, | |
1789 | "dpp_netaccesskey": ap_netaccesskey} | |
cd29045b JM |
1790 | try: |
1791 | hapd = hostapd.add_ap(apdev[0], params) | |
1792 | except: | |
1793 | raise HwsimSkip("DPP not supported") | |
1794 | ||
e105110f | 1795 | conf_id = dev[1].dpp_configurator_add(key=csign) |
cd29045b | 1796 | dev[0].set("dpp_config_processing", str(processing)) |
a5387062 | 1797 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
cd29045b | 1798 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
7e009100 | 1799 | dev[0].dpp_listen(2412) |
5725b3e3 JM |
1800 | dev[1].dpp_auth_init(uri=uri0, conf="sta-dpp", configurator=conf_id) |
1801 | wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0]) | |
cd29045b JM |
1802 | ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1) |
1803 | if ev is None: | |
1804 | raise Exception("DPP network profile not generated") | |
1805 | id = ev.split(' ')[1] | |
1806 | ||
1807 | if processing == 1: | |
1808 | dev[0].select_network(id, freq=2412) | |
1809 | ||
1810 | dev[0].wait_connected() | |
bbb42bf0 | 1811 | hwsim_utils.test_connectivity(dev[0], hapd) |
cd29045b JM |
1812 | |
1813 | def test_dpp_auto_connect_legacy(dev, apdev): | |
1814 | """DPP and auto connect (legacy)""" | |
1815 | try: | |
1816 | run_dpp_auto_connect_legacy(dev, apdev) | |
1817 | finally: | |
5bf51d38 | 1818 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
cd29045b | 1819 | |
ca6a2ac7 JM |
1820 | def test_dpp_auto_connect_legacy_ssid_charset(dev, apdev): |
1821 | """DPP and auto connect (legacy, ssid_charset)""" | |
1822 | try: | |
1823 | run_dpp_auto_connect_legacy(dev, apdev, ssid_charset=12345) | |
1824 | finally: | |
5bf51d38 | 1825 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
ca6a2ac7 | 1826 | |
fce412d3 JM |
1827 | def test_dpp_auto_connect_legacy_sae_1(dev, apdev): |
1828 | """DPP and auto connect (legacy SAE)""" | |
1829 | try: | |
1830 | run_dpp_auto_connect_legacy(dev, apdev, conf='sta-sae', psk_sae=True) | |
1831 | finally: | |
5bf51d38 | 1832 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
fce412d3 JM |
1833 | |
1834 | def test_dpp_auto_connect_legacy_sae_2(dev, apdev): | |
1835 | """DPP and auto connect (legacy SAE)""" | |
1836 | try: | |
1837 | run_dpp_auto_connect_legacy(dev, apdev, conf='sta-sae', sae_only=True) | |
1838 | finally: | |
5bf51d38 | 1839 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
fce412d3 JM |
1840 | |
1841 | def test_dpp_auto_connect_legacy_psk_sae_1(dev, apdev): | |
1842 | """DPP and auto connect (legacy PSK+SAE)""" | |
1843 | try: | |
1844 | run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk-sae', | |
1845 | psk_sae=True) | |
1846 | finally: | |
5bf51d38 | 1847 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
fce412d3 JM |
1848 | |
1849 | def test_dpp_auto_connect_legacy_psk_sae_2(dev, apdev): | |
1850 | """DPP and auto connect (legacy PSK+SAE)""" | |
1851 | try: | |
1852 | run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk-sae', | |
1853 | sae_only=True) | |
1854 | finally: | |
5bf51d38 | 1855 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
fce412d3 JM |
1856 | |
1857 | def test_dpp_auto_connect_legacy_psk_sae_3(dev, apdev): | |
1858 | """DPP and auto connect (legacy PSK+SAE)""" | |
1859 | try: | |
1860 | run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk-sae') | |
1861 | finally: | |
5bf51d38 | 1862 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
fce412d3 JM |
1863 | |
1864 | def run_dpp_auto_connect_legacy(dev, apdev, conf='sta-psk', | |
ca6a2ac7 | 1865 | ssid_charset=None, |
fce412d3 | 1866 | psk_sae=False, sae_only=False): |
cd29045b JM |
1867 | check_dpp_capab(dev[0]) |
1868 | check_dpp_capab(dev[1]) | |
1869 | ||
ede1f791 JM |
1870 | params = hostapd.wpa2_params(ssid="dpp-legacy", |
1871 | passphrase="secret passphrase") | |
fce412d3 JM |
1872 | if sae_only: |
1873 | params['wpa_key_mgmt'] = 'SAE' | |
2fec710a | 1874 | params['ieee80211w'] = '2' |
fce412d3 JM |
1875 | elif psk_sae: |
1876 | params['wpa_key_mgmt'] = 'WPA-PSK SAE' | |
2fec710a JM |
1877 | params['ieee80211w'] = '1' |
1878 | params['sae_require_mfp'] = '1' | |
fce412d3 | 1879 | |
cd29045b JM |
1880 | hapd = hostapd.add_ap(apdev[0], params) |
1881 | ||
c9ead82d | 1882 | dev[0].request("SET sae_groups ") |
cd29045b | 1883 | dev[0].set("dpp_config_processing", "2") |
a5387062 | 1884 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
299196c4 JM |
1885 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
1886 | ||
7e009100 | 1887 | dev[0].dpp_listen(2412) |
5725b3e3 | 1888 | dev[1].dpp_auth_init(uri=uri0, conf=conf, ssid="dpp-legacy", |
ca6a2ac7 | 1889 | ssid_charset=ssid_charset, |
5725b3e3 JM |
1890 | passphrase="secret passphrase") |
1891 | wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0]) | |
ca6a2ac7 JM |
1892 | if ssid_charset: |
1893 | ev = dev[0].wait_event(["DPP-CONFOBJ-SSID-CHARSET"], timeout=1) | |
1894 | if ev is None: | |
1895 | raise Exception("ssid_charset not reported") | |
1896 | charset = ev.split(' ')[1] | |
1897 | if charset != str(ssid_charset): | |
1898 | raise Exception("Incorrect ssid_charset reported: " + ev) | |
299196c4 JM |
1899 | ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1) |
1900 | if ev is None: | |
1901 | raise Exception("DPP network profile not generated") | |
1902 | id = ev.split(' ')[1] | |
1903 | ||
1904 | dev[0].wait_connected() | |
1905 | ||
1906 | def test_dpp_auto_connect_legacy_pmf_required(dev, apdev): | |
1907 | """DPP and auto connect (legacy, PMF required)""" | |
1908 | try: | |
1909 | run_dpp_auto_connect_legacy_pmf_required(dev, apdev) | |
1910 | finally: | |
5bf51d38 | 1911 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
299196c4 JM |
1912 | |
1913 | def run_dpp_auto_connect_legacy_pmf_required(dev, apdev): | |
1914 | check_dpp_capab(dev[0]) | |
1915 | check_dpp_capab(dev[1]) | |
1916 | ||
1917 | params = hostapd.wpa2_params(ssid="dpp-legacy", | |
1918 | passphrase="secret passphrase") | |
1919 | params['wpa_key_mgmt'] = "WPA-PSK-SHA256" | |
1920 | params['ieee80211w'] = "2" | |
1921 | hapd = hostapd.add_ap(apdev[0], params) | |
1922 | ||
1923 | dev[0].set("dpp_config_processing", "2") | |
a5387062 | 1924 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
cd29045b | 1925 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
7e009100 | 1926 | dev[0].dpp_listen(2412) |
5725b3e3 JM |
1927 | dev[1].dpp_auth_init(uri=uri0, conf="sta-psk", ssid="dpp-legacy", |
1928 | passphrase="secret passphrase") | |
1929 | wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0]) | |
cd29045b JM |
1930 | ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1) |
1931 | if ev is None: | |
1932 | raise Exception("DPP network profile not generated") | |
cd29045b | 1933 | dev[0].wait_connected() |
34a5c762 | 1934 | |
d86b86d0 JM |
1935 | def test_dpp_qr_code_auth_responder_configurator(dev, apdev): |
1936 | """DPP QR Code and responder as the configurator""" | |
2697e85e JM |
1937 | run_dpp_qr_code_auth_responder_configurator(dev, apdev, "") |
1938 | ||
1939 | def test_dpp_qr_code_auth_responder_configurator_group_id(dev, apdev): | |
1940 | """DPP QR Code and responder as the configurator with group_id)""" | |
1941 | run_dpp_qr_code_auth_responder_configurator(dev, apdev, | |
1942 | " group_id=test-group") | |
1943 | ||
1944 | def run_dpp_qr_code_auth_responder_configurator(dev, apdev, extra): | |
d86b86d0 JM |
1945 | check_dpp_capab(dev[0]) |
1946 | check_dpp_capab(dev[1]) | |
e105110f | 1947 | conf_id = dev[0].dpp_configurator_add() |
a5387062 | 1948 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
d86b86d0 | 1949 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
2697e85e | 1950 | dev[0].set("dpp_configurator_params", |
58be42b2 | 1951 | " conf=sta-dpp configurator=%d%s" % (conf_id, extra)) |
7e009100 | 1952 | dev[0].dpp_listen(2412, role="configurator") |
5725b3e3 | 1953 | dev[1].dpp_auth_init(uri=uri0, role="enrollee") |
517f76b1 JM |
1954 | wait_auth_success(dev[0], dev[1], configurator=dev[0], enrollee=dev[1], |
1955 | stop_responder=True) | |
d86b86d0 | 1956 | |
359dc93d JM |
1957 | def test_dpp_qr_code_hostapd_init(dev, apdev): |
1958 | """DPP QR Code and hostapd as initiator""" | |
1959 | check_dpp_capab(dev[0]) | |
fab49f61 JM |
1960 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured", |
1961 | "channel": "6"}) | |
359dc93d | 1962 | check_dpp_capab(hapd) |
e105110f | 1963 | conf_id = dev[0].dpp_configurator_add() |
a5387062 | 1964 | id0 = dev[0].dpp_bootstrap_gen(chan="81/6", mac=True) |
359dc93d | 1965 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
359dc93d | 1966 | dev[0].set("dpp_configurator_params", |
58be42b2 | 1967 | " conf=ap-dpp configurator=%d" % conf_id) |
7e009100 | 1968 | dev[0].dpp_listen(2437, role="configurator") |
5725b3e3 | 1969 | hapd.dpp_auth_init(uri=uri0, role="enrollee") |
517f76b1 JM |
1970 | wait_auth_success(dev[0], hapd, configurator=dev[0], enrollee=hapd, |
1971 | stop_responder=True) | |
c8b19de2 JM |
1972 | |
1973 | def test_dpp_qr_code_hostapd_init_offchannel(dev, apdev): | |
1974 | """DPP QR Code and hostapd as initiator (offchannel)""" | |
1975 | run_dpp_qr_code_hostapd_init_offchannel(dev, apdev, None) | |
1976 | ||
1977 | def test_dpp_qr_code_hostapd_init_offchannel_neg_freq(dev, apdev): | |
1978 | """DPP QR Code and hostapd as initiator (offchannel, neg_freq)""" | |
1979 | run_dpp_qr_code_hostapd_init_offchannel(dev, apdev, "neg_freq=2437") | |
1980 | ||
1981 | def run_dpp_qr_code_hostapd_init_offchannel(dev, apdev, extra): | |
1982 | check_dpp_capab(dev[0]) | |
fab49f61 JM |
1983 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured", |
1984 | "channel": "6"}) | |
c8b19de2 | 1985 | check_dpp_capab(hapd) |
e105110f | 1986 | conf_id = dev[0].dpp_configurator_add() |
a5387062 | 1987 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1,81/11", mac=True) |
c8b19de2 | 1988 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
c8b19de2 | 1989 | dev[0].set("dpp_configurator_params", |
58be42b2 | 1990 | " conf=ap-dpp configurator=%d" % conf_id) |
7e009100 | 1991 | dev[0].dpp_listen(2462, role="configurator") |
5725b3e3 | 1992 | hapd.dpp_auth_init(uri=uri0, role="enrollee", extra=extra) |
517f76b1 JM |
1993 | wait_auth_success(dev[0], hapd, configurator=dev[0], enrollee=hapd, |
1994 | stop_responder=True) | |
359dc93d | 1995 | |
055cd397 JM |
1996 | def test_dpp_test_vector_p_256(dev, apdev): |
1997 | """DPP P-256 test vector (mutual auth)""" | |
1998 | check_dpp_capab(dev[0]) | |
1999 | check_dpp_capab(dev[1]) | |
2000 | ||
2001 | # Responder bootstrapping key | |
2002 | priv = "54ce181a98525f217216f59b245f60e9df30ac7f6b26c939418cfc3c42d1afa0" | |
a5387062 | 2003 | id0 = dev[0].dpp_bootstrap_gen(chan="81/11", mac=True, key="30310201010420" + priv + "a00a06082a8648ce3d030107") |
055cd397 JM |
2004 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
2005 | ||
2006 | # Responder protocol keypair override | |
2007 | priv = "f798ed2e19286f6a6efe210b1863badb99af2a14b497634dbfd2a97394fb5aa5" | |
2008 | dev[0].set("dpp_protocol_key_override", | |
2009 | "30310201010420" + priv + "a00a06082a8648ce3d030107") | |
2010 | ||
2011 | dev[0].set("dpp_nonce_override", "3d0cfb011ca916d796f7029ff0b43393") | |
2012 | ||
2013 | # Initiator bootstrapping key | |
2014 | priv = "15b2a83c5a0a38b61f2aa8200ee4994b8afdc01c58507d10d0a38f7eedf051bb" | |
a5387062 | 2015 | id1 = dev[1].dpp_bootstrap_gen(key="30310201010420" + priv + "a00a06082a8648ce3d030107") |
055cd397 JM |
2016 | uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1) |
2017 | ||
2018 | # Initiator protocol keypair override | |
2019 | priv = "a87de9afbb406c96e5f79a3df895ecac3ad406f95da66314c8cb3165e0c61783" | |
2020 | dev[1].set("dpp_protocol_key_override", | |
2021 | "30310201010420" + priv + "a00a06082a8648ce3d030107") | |
2022 | ||
2023 | dev[1].set("dpp_nonce_override", "13f4602a16daeb69712263b9c46cba31") | |
2024 | ||
5725b3e3 | 2025 | dev[0].dpp_qr_code(uri1) |
7e009100 | 2026 | dev[0].dpp_listen(2462, qr="mutual") |
5725b3e3 | 2027 | dev[1].dpp_auth_init(uri=uri0, own=id1, neg_freq=2412) |
517f76b1 | 2028 | wait_auth_success(dev[0], dev[1]) |
055cd397 JM |
2029 | |
2030 | def test_dpp_test_vector_p_256_b(dev, apdev): | |
2031 | """DPP P-256 test vector (Responder-only auth)""" | |
2032 | check_dpp_capab(dev[0]) | |
2033 | check_dpp_capab(dev[1]) | |
2034 | ||
2035 | # Responder bootstrapping key | |
2036 | priv = "54ce181a98525f217216f59b245f60e9df30ac7f6b26c939418cfc3c42d1afa0" | |
a5387062 | 2037 | id0 = dev[0].dpp_bootstrap_gen(chan="81/11", mac=True, key="30310201010420" + priv + "a00a06082a8648ce3d030107") |
055cd397 JM |
2038 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
2039 | ||
2040 | # Responder protocol keypair override | |
2041 | priv = "f798ed2e19286f6a6efe210b1863badb99af2a14b497634dbfd2a97394fb5aa5" | |
2042 | dev[0].set("dpp_protocol_key_override", | |
2043 | "30310201010420" + priv + "a00a06082a8648ce3d030107") | |
2044 | ||
2045 | dev[0].set("dpp_nonce_override", "3d0cfb011ca916d796f7029ff0b43393") | |
2046 | ||
2047 | # Initiator bootstrapping key | |
2048 | priv = "15b2a83c5a0a38b61f2aa8200ee4994b8afdc01c58507d10d0a38f7eedf051bb" | |
a5387062 | 2049 | id1 = dev[1].dpp_bootstrap_gen(key="30310201010420" + priv + "a00a06082a8648ce3d030107") |
055cd397 JM |
2050 | uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1) |
2051 | ||
2052 | # Initiator protocol keypair override | |
2053 | priv = "a87de9afbb406c96e5f79a3df895ecac3ad406f95da66314c8cb3165e0c61783" | |
2054 | dev[1].set("dpp_protocol_key_override", | |
2055 | "30310201010420" + priv + "a00a06082a8648ce3d030107") | |
2056 | ||
2057 | dev[1].set("dpp_nonce_override", "13f4602a16daeb69712263b9c46cba31") | |
2058 | ||
7e009100 | 2059 | dev[0].dpp_listen(2462) |
5725b3e3 | 2060 | dev[1].dpp_auth_init(uri=uri0, own=id1, neg_freq=2412) |
517f76b1 | 2061 | wait_auth_success(dev[0], dev[1]) |
055cd397 | 2062 | |
9a3acf43 JM |
2063 | def der_priv_key_p_521(priv): |
2064 | if len(priv) != 2 * 66: | |
2065 | raise Exception("Unexpected der_priv_key_p_521 parameter: " + priv) | |
2066 | der_prefix = "3081500201010442" | |
2067 | der_postfix = "a00706052b81040023" | |
2068 | return der_prefix + priv + der_postfix | |
2069 | ||
2070 | def test_dpp_test_vector_p_521(dev, apdev): | |
2071 | """DPP P-521 test vector (mutual auth)""" | |
2072 | check_dpp_capab(dev[0]) | |
2073 | check_dpp_capab(dev[1]) | |
2074 | ||
2075 | # Responder bootstrapping key | |
2076 | priv = "0061e54f518cdf859735da3dd64c6f72c2f086f41a6fd52915152ea2fe0f24ddaecd8883730c9c9fd82cf7c043a41021696388cf5190b731dd83638bcd56d8b6c743" | |
a5387062 JM |
2077 | id0 = dev[0].dpp_bootstrap_gen(chan="81/11", mac=True, |
2078 | key=der_priv_key_p_521(priv)) | |
9a3acf43 JM |
2079 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
2080 | ||
2081 | # Responder protocol keypair override | |
2082 | priv = "01d8b7b17cd1b0a33f7c66fb4220999329cdaf4f8b44b2ffadde8ab8ed8abffa9f5358c5b1caae26709ca4fb78e52a4d08f2e4f24111a36a6f440d20a0000ff51597" | |
2083 | dev[0].set("dpp_protocol_key_override", der_priv_key_p_521(priv)) | |
2084 | ||
2085 | dev[0].set("dpp_nonce_override", | |
2086 | "d749a782012eb0a8595af30b2dfc8d0880d004ebddb55ecc5afbdef18c400e01") | |
2087 | ||
2088 | # Initiator bootstrapping key | |
2089 | priv = "0060c10df14af5ef27f6e362d31bdd9eeb44be77a323ba64b08f3f03d58b92cbfe05c182a91660caa081ca344243c47b5aa088bcdf738840eb35f0218b9f26881e02" | |
a5387062 | 2090 | id1 = dev[1].dpp_bootstrap_gen(key=der_priv_key_p_521(priv)) |
9a3acf43 JM |
2091 | uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1) |
2092 | ||
2093 | # Initiator protocol keypair override | |
2094 | priv = "019c1c08caaeec38fb931894699b095bc3ab8c1ec7ef0622d2e3eba821477c8c6fca41774f21166ad98aebda37c067d9aa08a8a2e1b5c44c61f2bae02a61f85d9661" | |
2095 | dev[1].set("dpp_protocol_key_override", der_priv_key_p_521(priv)) | |
2096 | ||
2097 | dev[1].set("dpp_nonce_override", | |
2098 | "de972af3847bec3ba2aedd9f5c21cfdec7bf0bc5fe8b276cbcd0267807fb15b0") | |
2099 | ||
5725b3e3 | 2100 | dev[0].dpp_qr_code(uri1) |
7e009100 | 2101 | dev[0].dpp_listen(2462, qr="mutual") |
5725b3e3 | 2102 | dev[1].dpp_auth_init(uri=uri0, own=id1, neg_freq=2412) |
517f76b1 | 2103 | wait_auth_success(dev[0], dev[1]) |
9a3acf43 | 2104 | |
34a5c762 JM |
2105 | def test_dpp_pkex(dev, apdev): |
2106 | """DPP and PKEX""" | |
2107 | run_dpp_pkex(dev, apdev) | |
2108 | ||
2109 | def test_dpp_pkex_p256(dev, apdev): | |
2110 | """DPP and PKEX (P-256)""" | |
2111 | run_dpp_pkex(dev, apdev, "P-256") | |
2112 | ||
2113 | def test_dpp_pkex_p384(dev, apdev): | |
2114 | """DPP and PKEX (P-384)""" | |
2115 | run_dpp_pkex(dev, apdev, "P-384") | |
2116 | ||
2117 | def test_dpp_pkex_p521(dev, apdev): | |
2118 | """DPP and PKEX (P-521)""" | |
2119 | run_dpp_pkex(dev, apdev, "P-521") | |
2120 | ||
2121 | def test_dpp_pkex_bp256(dev, apdev): | |
2122 | """DPP and PKEX (BP-256)""" | |
2123 | run_dpp_pkex(dev, apdev, "brainpoolP256r1") | |
2124 | ||
2125 | def test_dpp_pkex_bp384(dev, apdev): | |
2126 | """DPP and PKEX (BP-384)""" | |
2127 | run_dpp_pkex(dev, apdev, "brainpoolP384r1") | |
2128 | ||
2129 | def test_dpp_pkex_bp512(dev, apdev): | |
2130 | """DPP and PKEX (BP-512)""" | |
2131 | run_dpp_pkex(dev, apdev, "brainpoolP512r1") | |
2132 | ||
2133 | def test_dpp_pkex_config(dev, apdev): | |
2134 | """DPP and PKEX with initiator as the configurator""" | |
4874f5ba | 2135 | check_dpp_capab(dev[1]) |
e105110f | 2136 | conf_id = dev[1].dpp_configurator_add() |
34a5c762 JM |
2137 | run_dpp_pkex(dev, apdev, |
2138 | init_extra="conf=sta-dpp configurator=%d" % (conf_id), | |
2139 | check_config=True) | |
2140 | ||
eb390abb JM |
2141 | def test_dpp_pkex_no_identifier(dev, apdev): |
2142 | """DPP and PKEX without identifier""" | |
2143 | run_dpp_pkex(dev, apdev, identifier_i=None, identifier_r=None) | |
2144 | ||
2145 | def test_dpp_pkex_identifier_mismatch(dev, apdev): | |
2146 | """DPP and PKEX with different identifiers""" | |
2147 | run_dpp_pkex(dev, apdev, identifier_i="foo", identifier_r="bar", | |
2148 | expect_no_resp=True) | |
2149 | ||
2150 | def test_dpp_pkex_identifier_mismatch2(dev, apdev): | |
2151 | """DPP and PKEX with initiator using identifier and the responder not""" | |
2152 | run_dpp_pkex(dev, apdev, identifier_i="foo", identifier_r=None, | |
2153 | expect_no_resp=True) | |
2154 | ||
2155 | def test_dpp_pkex_identifier_mismatch3(dev, apdev): | |
2156 | """DPP and PKEX with responder using identifier and the initiator not""" | |
2157 | run_dpp_pkex(dev, apdev, identifier_i=None, identifier_r="bar", | |
2158 | expect_no_resp=True) | |
2159 | ||
6d196e59 | 2160 | def run_dpp_pkex(dev, apdev, curve=None, init_extra=None, check_config=False, |
eb390abb JM |
2161 | identifier_i="test", identifier_r="test", |
2162 | expect_no_resp=False): | |
d584946e JM |
2163 | check_dpp_capab(dev[0], curve and "brainpool" in curve) |
2164 | check_dpp_capab(dev[1], curve and "brainpool" in curve) | |
6d196e59 JM |
2165 | dev[0].dpp_pkex_resp(2437, identifier=identifier_r, code="secret", |
2166 | curve=curve) | |
2167 | dev[1].dpp_pkex_init(identifier=identifier_i, code="secret", curve=curve, | |
2168 | extra=init_extra) | |
34a5c762 | 2169 | |
eb390abb JM |
2170 | if expect_no_resp: |
2171 | ev = dev[0].wait_event(["DPP-RX"], timeout=10) | |
2172 | if ev is None: | |
2173 | raise Exception("DPP PKEX frame not received") | |
2174 | ev = dev[1].wait_event(["DPP-AUTH-SUCCESS"], timeout=1) | |
2175 | if ev is not None: | |
2176 | raise Exception("DPP authentication succeeded") | |
2177 | ev = dev[0].wait_event(["DPP-AUTH-SUCCESS"], timeout=0.1) | |
2178 | if ev is not None: | |
2179 | raise Exception("DPP authentication succeeded") | |
2180 | return | |
2181 | ||
517f76b1 JM |
2182 | wait_auth_success(dev[0], dev[1], |
2183 | configurator=dev[1] if check_config else None, | |
2184 | enrollee=dev[0] if check_config else None) | |
34a5c762 | 2185 | |
4370ffc0 JM |
2186 | def test_dpp_pkex_5ghz(dev, apdev): |
2187 | """DPP and PKEX on 5 GHz""" | |
2188 | try: | |
2189 | dev[0].request("SET country US") | |
2190 | dev[1].request("SET country US") | |
2191 | ev = dev[0].wait_event(["CTRL-EVENT-REGDOM-CHANGE"], timeout=1) | |
2192 | if ev is None: | |
2193 | ev = dev[0].wait_global_event(["CTRL-EVENT-REGDOM-CHANGE"], | |
2194 | timeout=1) | |
2195 | run_dpp_pkex_5ghz(dev, apdev) | |
2196 | finally: | |
2197 | dev[0].request("SET country 00") | |
2198 | dev[1].request("SET country 00") | |
2199 | subprocess.call(['iw', 'reg', 'set', '00']) | |
ba3146e1 | 2200 | time.sleep(0.1) |
4370ffc0 JM |
2201 | |
2202 | def run_dpp_pkex_5ghz(dev, apdev): | |
2203 | check_dpp_capab(dev[0]) | |
2204 | check_dpp_capab(dev[1]) | |
6d196e59 JM |
2205 | dev[0].dpp_pkex_resp(5745, identifier="test", code="secret") |
2206 | dev[1].dpp_pkex_init(identifier="test", code="secret") | |
517f76b1 | 2207 | wait_auth_success(dev[0], dev[1], timeout=20) |
4370ffc0 | 2208 | |
5da4b2f3 JM |
2209 | def test_dpp_pkex_test_vector(dev, apdev): |
2210 | """DPP and PKEX (P-256) test vector""" | |
2211 | check_dpp_capab(dev[0]) | |
2212 | check_dpp_capab(dev[1]) | |
2d7aa8d5 | 2213 | |
8f9d2b17 JM |
2214 | init_addr = "ac:64:91:f4:52:07" |
2215 | resp_addr = "6e:5e:ce:6e:f3:dd" | |
2d7aa8d5 | 2216 | |
5da4b2f3 JM |
2217 | identifier = "joes_key" |
2218 | code = "thisisreallysecret" | |
2219 | ||
2d7aa8d5 JM |
2220 | # Initiator bootstrapping private key |
2221 | init_priv = "5941b51acfc702cdc1c347264beb2920db88eb1a0bf03a211868b1632233c269" | |
2222 | ||
2223 | # Responder bootstrapping private key | |
2224 | resp_priv = "2ae8956293f49986b6d0b8169a86805d9232babb5f6813fdfe96f19d59536c60" | |
2225 | ||
2226 | # Initiator x/X keypair override | |
8f9d2b17 | 2227 | init_x_priv = "8365c5ed93d751bef2d92b410dc6adfd95670889183fac1bd66759ad85c3187a" |
2d7aa8d5 JM |
2228 | |
2229 | # Responder y/Y keypair override | |
8f9d2b17 | 2230 | resp_y_priv = "d98faa24d7dd3f592665d71a95c862bfd02c4c48acb0c515a41cbc6e929675ea" |
2d7aa8d5 JM |
2231 | |
2232 | p256_prefix = "30310201010420" | |
2233 | p256_postfix = "a00a06082a8648ce3d030107" | |
2234 | ||
2235 | dev[0].set("dpp_pkex_own_mac_override", resp_addr) | |
2236 | dev[0].set("dpp_pkex_peer_mac_override", init_addr) | |
2237 | dev[1].set("dpp_pkex_own_mac_override", init_addr) | |
2238 | dev[1].set("dpp_pkex_peer_mac_override", resp_addr) | |
2239 | ||
5da4b2f3 | 2240 | # Responder y/Y keypair override |
5da4b2f3 | 2241 | dev[0].set("dpp_pkex_ephemeral_key_override", |
2d7aa8d5 | 2242 | p256_prefix + resp_y_priv + p256_postfix) |
5da4b2f3 | 2243 | |
5da4b2f3 | 2244 | # Initiator x/X keypair override |
5da4b2f3 | 2245 | dev[1].set("dpp_pkex_ephemeral_key_override", |
2d7aa8d5 | 2246 | p256_prefix + init_x_priv + p256_postfix) |
5da4b2f3 | 2247 | |
6d196e59 JM |
2248 | dev[0].dpp_pkex_resp(2437, identifier=identifier, code=code, |
2249 | key=p256_prefix + resp_priv + p256_postfix) | |
2250 | dev[1].dpp_pkex_init(identifier=identifier, code=code, | |
2251 | key=p256_prefix + init_priv + p256_postfix) | |
517f76b1 | 2252 | wait_auth_success(dev[0], dev[1]) |
5da4b2f3 | 2253 | |
d592d134 JM |
2254 | def test_dpp_pkex_code_mismatch(dev, apdev): |
2255 | """DPP and PKEX with mismatching code""" | |
2256 | check_dpp_capab(dev[0]) | |
2257 | check_dpp_capab(dev[1]) | |
6d196e59 JM |
2258 | dev[0].dpp_pkex_resp(2437, identifier="test", code="secret") |
2259 | id1 = dev[1].dpp_pkex_init(identifier="test", code="unknown") | |
203878d7 | 2260 | wait_dpp_fail(dev[0], "possible PKEX code mismatch") |
84d53c77 JM |
2261 | dev[0].dump_monitor() |
2262 | dev[1].dump_monitor() | |
6d196e59 | 2263 | dev[1].dpp_pkex_init(identifier="test", code="secret", use_id=id1) |
517f76b1 | 2264 | wait_auth_success(dev[0], dev[1]) |
84d53c77 | 2265 | |
aa485b0e JM |
2266 | def test_dpp_pkex_code_mismatch_limit(dev, apdev): |
2267 | """DPP and PKEX with mismatching code limit""" | |
2268 | check_dpp_capab(dev[0]) | |
2269 | check_dpp_capab(dev[1]) | |
6d196e59 | 2270 | dev[0].dpp_pkex_resp(2437, identifier="test", code="secret") |
aa485b0e | 2271 | |
6d196e59 | 2272 | id1 = None |
aa485b0e JM |
2273 | for i in range(5): |
2274 | dev[0].dump_monitor() | |
2275 | dev[1].dump_monitor() | |
6d196e59 JM |
2276 | id1 = dev[1].dpp_pkex_init(identifier="test", code="unknown", |
2277 | use_id=id1) | |
203878d7 | 2278 | wait_dpp_fail(dev[0], "possible PKEX code mismatch") |
aa485b0e JM |
2279 | |
2280 | ev = dev[0].wait_event(["DPP-PKEX-T-LIMIT"], timeout=1) | |
2281 | if ev is None: | |
2282 | raise Exception("PKEX t limit not reported") | |
2283 | ||
dab56420 JM |
2284 | def test_dpp_pkex_curve_mismatch(dev, apdev): |
2285 | """DPP and PKEX with mismatching curve""" | |
2286 | check_dpp_capab(dev[0]) | |
2287 | check_dpp_capab(dev[1]) | |
6d196e59 JM |
2288 | dev[0].dpp_pkex_resp(2437, identifier="test", code="secret", curve="P-256") |
2289 | dev[1].dpp_pkex_init(identifier="test", code="secret", curve="P-384") | |
203878d7 JM |
2290 | wait_dpp_fail(dev[0], "Mismatching PKEX curve: peer=20 own=19") |
2291 | wait_dpp_fail(dev[1], "Peer indicated mismatching PKEX group - proposed 19") | |
dab56420 | 2292 | |
6026ed0d JM |
2293 | def test_dpp_pkex_curve_mismatch_failure(dev, apdev): |
2294 | """DPP and PKEX with mismatching curve (local failure)""" | |
2295 | run_dpp_pkex_curve_mismatch_failure(dev, apdev, "=dpp_pkex_rx_exchange_req") | |
2296 | ||
2297 | def test_dpp_pkex_curve_mismatch_failure2(dev, apdev): | |
2298 | """DPP and PKEX with mismatching curve (local failure 2)""" | |
2299 | run_dpp_pkex_curve_mismatch_failure(dev, apdev, | |
2300 | "dpp_pkex_build_exchange_resp") | |
2301 | ||
2302 | def run_dpp_pkex_curve_mismatch_failure(dev, apdev, func): | |
2303 | check_dpp_capab(dev[0]) | |
2304 | check_dpp_capab(dev[1]) | |
6d196e59 | 2305 | dev[0].dpp_pkex_resp(2437, identifier="test", code="secret", curve="P-256") |
6026ed0d JM |
2306 | |
2307 | with alloc_fail(dev[0], 1, func): | |
6d196e59 | 2308 | dev[1].dpp_pkex_init(identifier="test", code="secret", curve="P-384") |
6026ed0d JM |
2309 | |
2310 | ev = dev[0].wait_event(["DPP-FAIL"], timeout=5) | |
2311 | if ev is None: | |
2312 | raise Exception("Failure not reported (dev 0)") | |
2313 | if "Mismatching PKEX curve: peer=20 own=19" not in ev: | |
2314 | raise Exception("Unexpected result: " + ev) | |
203878d7 | 2315 | wait_dpp_fail(dev[0], "Mismatching PKEX curve: peer=20 own=19") |
6026ed0d | 2316 | |
a7758916 JM |
2317 | def test_dpp_pkex_exchange_resp_processing_failure(dev, apdev): |
2318 | """DPP and PKEX with local failure in processing Exchange Resp""" | |
2319 | check_dpp_capab(dev[0]) | |
2320 | check_dpp_capab(dev[1]) | |
6d196e59 | 2321 | dev[0].dpp_pkex_resp(2437, identifier="test", code="secret") |
a7758916 JM |
2322 | |
2323 | with fail_test(dev[1], 1, "dpp_pkex_derive_Qr;dpp_pkex_rx_exchange_resp"): | |
6d196e59 | 2324 | dev[1].dpp_pkex_init(identifier="test", code="secret") |
a7758916 JM |
2325 | wait_fail_trigger(dev[1], "GET_FAIL") |
2326 | ||
24c4200d JM |
2327 | def test_dpp_pkex_commit_reveal_req_processing_failure(dev, apdev): |
2328 | """DPP and PKEX with local failure in processing Commit Reveal Req""" | |
2329 | check_dpp_capab(dev[0]) | |
2330 | check_dpp_capab(dev[1]) | |
6d196e59 | 2331 | dev[0].dpp_pkex_resp(2437, identifier="test", code="secret") |
24c4200d JM |
2332 | |
2333 | with alloc_fail(dev[0], 1, | |
2334 | "dpp_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"): | |
6d196e59 | 2335 | dev[1].dpp_pkex_init(identifier="test", code="secret") |
24c4200d JM |
2336 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") |
2337 | ||
34a5c762 JM |
2338 | def test_dpp_pkex_config2(dev, apdev): |
2339 | """DPP and PKEX with responder as the configurator""" | |
4874f5ba | 2340 | check_dpp_capab(dev[0]) |
e105110f | 2341 | conf_id = dev[0].dpp_configurator_add() |
34a5c762 | 2342 | dev[0].set("dpp_configurator_params", |
58be42b2 | 2343 | " conf=sta-dpp configurator=%d" % conf_id) |
34a5c762 JM |
2344 | run_dpp_pkex2(dev, apdev) |
2345 | ||
2346 | def run_dpp_pkex2(dev, apdev, curve=None, init_extra=""): | |
2347 | check_dpp_capab(dev[0]) | |
2348 | check_dpp_capab(dev[1]) | |
6d196e59 JM |
2349 | dev[0].dpp_pkex_resp(2437, identifier="test", code="secret", curve=curve, |
2350 | listen_role="configurator") | |
2351 | dev[1].dpp_pkex_init(identifier="test", code="secret", role="enrollee", | |
2352 | curve=curve, extra=init_extra) | |
517f76b1 | 2353 | wait_auth_success(dev[0], dev[1], configurator=dev[0], enrollee=dev[1]) |
163f76de | 2354 | |
169e341e JM |
2355 | def test_dpp_pkex_no_responder(dev, apdev): |
2356 | """DPP and PKEX with no responder (retry behavior)""" | |
2357 | check_dpp_capab(dev[0]) | |
6d196e59 | 2358 | dev[0].dpp_pkex_init(identifier="test", code="secret") |
169e341e | 2359 | |
5a5529c9 JM |
2360 | for i in range(15): |
2361 | ev = dev[0].wait_event(["DPP-TX ", "DPP-FAIL"], timeout=5) | |
2362 | if ev is None: | |
2363 | raise Exception("DPP PKEX failure not reported") | |
2364 | if "DPP-FAIL" not in ev: | |
2365 | continue | |
2366 | if "No response from PKEX peer" not in ev: | |
2367 | raise Exception("Unexpected failure reason: " + ev) | |
2368 | break | |
169e341e JM |
2369 | |
2370 | def test_dpp_pkex_after_retry(dev, apdev): | |
2371 | """DPP and PKEX completing after retry""" | |
2372 | check_dpp_capab(dev[0]) | |
6d196e59 | 2373 | dev[0].dpp_pkex_init(identifier="test", code="secret") |
169e341e | 2374 | time.sleep(0.1) |
6d196e59 | 2375 | dev[1].dpp_pkex_resp(2437, identifier="test", code="secret") |
517f76b1 JM |
2376 | wait_auth_success(dev[1], dev[0], configurator=dev[0], enrollee=dev[1], |
2377 | allow_enrollee_failure=True) | |
169e341e | 2378 | |
163f76de JM |
2379 | def test_dpp_pkex_hostapd_responder(dev, apdev): |
2380 | """DPP PKEX with hostapd as responder""" | |
2381 | check_dpp_capab(dev[0]) | |
fab49f61 JM |
2382 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured", |
2383 | "channel": "6"}) | |
163f76de | 2384 | check_dpp_capab(hapd) |
6d196e59 | 2385 | hapd.dpp_pkex_resp(2437, identifier="test", code="secret") |
e105110f | 2386 | conf_id = dev[0].dpp_configurator_add() |
6d196e59 JM |
2387 | dev[0].dpp_pkex_init(identifier="test", code="secret", |
2388 | extra="conf=ap-dpp configurator=%d" % conf_id) | |
517f76b1 JM |
2389 | wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd, |
2390 | stop_initiator=True) | |
163f76de JM |
2391 | |
2392 | def test_dpp_pkex_hostapd_initiator(dev, apdev): | |
2393 | """DPP PKEX with hostapd as initiator""" | |
2394 | check_dpp_capab(dev[0]) | |
fab49f61 JM |
2395 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured", |
2396 | "channel": "6"}) | |
163f76de | 2397 | check_dpp_capab(hapd) |
e105110f | 2398 | conf_id = dev[0].dpp_configurator_add() |
163f76de | 2399 | dev[0].set("dpp_configurator_params", |
58be42b2 | 2400 | " conf=ap-dpp configurator=%d" % conf_id) |
6d196e59 JM |
2401 | dev[0].dpp_pkex_resp(2437, identifier="test", code="secret", |
2402 | listen_role="configurator") | |
2403 | hapd.dpp_pkex_init(identifier="test", code="secret", role="enrollee") | |
517f76b1 JM |
2404 | wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd, |
2405 | stop_initiator=True) | |
0651dfb7 JM |
2406 | |
2407 | def test_dpp_hostapd_configurator(dev, apdev): | |
2408 | """DPP with hostapd as configurator/initiator""" | |
2409 | check_dpp_capab(dev[0]) | |
fab49f61 JM |
2410 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured", |
2411 | "channel": "1"}) | |
0651dfb7 | 2412 | check_dpp_capab(hapd) |
e105110f | 2413 | conf_id = hapd.dpp_configurator_add() |
a5387062 | 2414 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
0651dfb7 | 2415 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
0422d06b | 2416 | id1 = hapd.dpp_qr_code(uri0) |
5725b3e3 | 2417 | res = hapd.request("DPP_BOOTSTRAP_INFO %d" % id1) |
97136c83 JM |
2418 | if "FAIL" in res: |
2419 | raise Exception("DPP_BOOTSTRAP_INFO failed") | |
2420 | if "type=QRCODE" not in res: | |
2421 | raise Exception("DPP_BOOTSTRAP_INFO did not report correct type") | |
2422 | if "mac_addr=" + dev[0].own_addr() not in res: | |
2423 | raise Exception("DPP_BOOTSTRAP_INFO did not report correct mac_addr") | |
7e009100 | 2424 | dev[0].dpp_listen(2412) |
5725b3e3 | 2425 | hapd.dpp_auth_init(peer=id1, configurator=conf_id, conf="sta-dpp") |
517f76b1 JM |
2426 | wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0], |
2427 | stop_responder=True) | |
0651dfb7 JM |
2428 | |
2429 | def test_dpp_hostapd_configurator_responder(dev, apdev): | |
2430 | """DPP with hostapd as configurator/responder""" | |
2431 | check_dpp_capab(dev[0]) | |
fab49f61 JM |
2432 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured", |
2433 | "channel": "1"}) | |
0651dfb7 | 2434 | check_dpp_capab(hapd) |
e105110f | 2435 | conf_id = hapd.dpp_configurator_add() |
0651dfb7 | 2436 | hapd.set("dpp_configurator_params", |
58be42b2 | 2437 | " conf=sta-dpp configurator=%d" % conf_id) |
a5387062 | 2438 | id0 = hapd.dpp_bootstrap_gen(chan="81/1", mac=True) |
0651dfb7 | 2439 | uri0 = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
5725b3e3 | 2440 | dev[0].dpp_auth_init(uri=uri0, role="enrollee") |
517f76b1 JM |
2441 | wait_auth_success(hapd, dev[0], configurator=hapd, enrollee=dev[0], |
2442 | stop_initiator=True) | |
854d0de3 JM |
2443 | |
2444 | def test_dpp_own_config(dev, apdev): | |
2445 | """DPP configurator signing own connector""" | |
2446 | try: | |
2447 | run_dpp_own_config(dev, apdev) | |
2448 | finally: | |
5bf51d38 | 2449 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
854d0de3 | 2450 | |
2697e85e JM |
2451 | def test_dpp_own_config_group_id(dev, apdev): |
2452 | """DPP configurator signing own connector""" | |
2453 | try: | |
2454 | run_dpp_own_config(dev, apdev, extra=" group_id=test-group") | |
2455 | finally: | |
5bf51d38 | 2456 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
2697e85e | 2457 | |
854d0de3 JM |
2458 | def test_dpp_own_config_curve_mismatch(dev, apdev): |
2459 | """DPP configurator signing own connector using mismatching curve""" | |
2460 | try: | |
2461 | run_dpp_own_config(dev, apdev, own_curve="BP-384", expect_failure=True) | |
2462 | finally: | |
5bf51d38 | 2463 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
854d0de3 | 2464 | |
2697e85e | 2465 | def run_dpp_own_config(dev, apdev, own_curve=None, expect_failure=False, |
5725b3e3 | 2466 | extra=None): |
d584946e | 2467 | check_dpp_capab(dev[0], own_curve and "BP" in own_curve) |
fab49f61 | 2468 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"}) |
854d0de3 | 2469 | check_dpp_capab(hapd) |
a5387062 | 2470 | id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True) |
854d0de3 | 2471 | uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h) |
e105110f | 2472 | conf_id = dev[0].dpp_configurator_add() |
5725b3e3 JM |
2473 | dev[0].dpp_auth_init(uri=uri, conf="ap-dpp", configurator=conf_id, |
2474 | extra=extra) | |
517f76b1 | 2475 | wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd) |
854d0de3 JM |
2476 | update_hapd_config(hapd) |
2477 | ||
2478 | dev[0].set("dpp_config_processing", "1") | |
9552a736 | 2479 | cmd = "DPP_CONFIGURATOR_SIGN conf=sta-dpp configurator=%d%s" % (conf_id, extra) |
854d0de3 JM |
2480 | if own_curve: |
2481 | cmd += " curve=" + own_curve | |
2482 | res = dev[0].request(cmd) | |
2483 | if "FAIL" in res: | |
2484 | raise Exception("Failed to generate own configuration") | |
2485 | ||
2486 | ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1) | |
2487 | if ev is None: | |
2488 | raise Exception("DPP network profile not generated") | |
2489 | id = ev.split(' ')[1] | |
2490 | dev[0].select_network(id, freq="2412") | |
2491 | if expect_failure: | |
2492 | ev = dev[0].wait_event(["CTRL-EVENT-CONNECTED"], timeout=1) | |
2493 | if ev is not None: | |
58be42b2 | 2494 | raise Exception("Unexpected connection") |
854d0de3 JM |
2495 | dev[0].request("DISCONNECT") |
2496 | else: | |
2497 | dev[0].wait_connected() | |
a0e3e222 | 2498 | |
73a7feb3 JM |
2499 | def test_dpp_own_config_ap(dev, apdev): |
2500 | """DPP configurator (AP) signing own connector""" | |
2501 | try: | |
2502 | run_dpp_own_config_ap(dev, apdev) | |
2503 | finally: | |
5bf51d38 | 2504 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
73a7feb3 | 2505 | |
2697e85e JM |
2506 | def test_dpp_own_config_ap_group_id(dev, apdev): |
2507 | """DPP configurator (AP) signing own connector (group_id)""" | |
2508 | try: | |
2509 | run_dpp_own_config_ap(dev, apdev, extra=" group_id=test-group") | |
2510 | finally: | |
5bf51d38 | 2511 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
2697e85e | 2512 | |
0c061630 JM |
2513 | def test_dpp_own_config_ap_reconf(dev, apdev): |
2514 | """DPP configurator (AP) signing own connector and configurator reconf""" | |
2515 | try: | |
2516 | run_dpp_own_config_ap(dev, apdev) | |
2517 | finally: | |
5bf51d38 | 2518 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
0c061630 | 2519 | |
5725b3e3 | 2520 | def run_dpp_own_config_ap(dev, apdev, reconf_configurator=False, extra=None): |
73a7feb3 | 2521 | check_dpp_capab(dev[0]) |
fab49f61 | 2522 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"}) |
73a7feb3 | 2523 | check_dpp_capab(hapd) |
e105110f | 2524 | conf_id = hapd.dpp_configurator_add() |
0c061630 JM |
2525 | if reconf_configurator: |
2526 | csign = hapd.request("DPP_CONFIGURATOR_GET_KEY %d" % conf_id) | |
2527 | if "FAIL" in csign or len(csign) == 0: | |
2528 | raise Exception("DPP_CONFIGURATOR_GET_KEY failed") | |
2529 | ||
9552a736 | 2530 | cmd = "DPP_CONFIGURATOR_SIGN conf=ap-dpp configurator=%d%s" % (conf_id, extra) |
73a7feb3 JM |
2531 | res = hapd.request(cmd) |
2532 | if "FAIL" in res: | |
2533 | raise Exception("Failed to generate own configuration") | |
2534 | update_hapd_config(hapd) | |
2535 | ||
0c061630 | 2536 | if reconf_configurator: |
e105110f JM |
2537 | hapd.dpp_configurator_remove(conf_id) |
2538 | conf_id = hapd.dpp_configurator_add(key=csign) | |
0c061630 | 2539 | |
a5387062 | 2540 | id = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
73a7feb3 | 2541 | uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id) |
73a7feb3 | 2542 | dev[0].set("dpp_config_processing", "2") |
7e009100 | 2543 | dev[0].dpp_listen(2412) |
5725b3e3 JM |
2544 | hapd.dpp_auth_init(uri=uri, conf="sta-dpp", configurator=conf_id, |
2545 | extra=extra) | |
517f76b1 | 2546 | wait_auth_success(dev[0], hapd, configurator=hapd, enrollee=dev[0]) |
73a7feb3 JM |
2547 | dev[0].wait_connected() |
2548 | ||
d045b7a1 JM |
2549 | def test_dpp_intro_mismatch(dev, apdev): |
2550 | """DPP network introduction mismatch cases""" | |
2551 | try: | |
2552 | wpas = None | |
2553 | wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') | |
2554 | wpas.interface_add("wlan5") | |
2555 | check_dpp_capab(wpas) | |
2556 | run_dpp_intro_mismatch(dev, apdev, wpas) | |
2557 | finally: | |
5bf51d38 JM |
2558 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
2559 | dev[2].set("dpp_config_processing", "0", allow_fail=True) | |
d045b7a1 | 2560 | if wpas: |
5bf51d38 | 2561 | wpas.set("dpp_config_processing", "0", allow_fail=True) |
d045b7a1 JM |
2562 | |
2563 | def run_dpp_intro_mismatch(dev, apdev, wpas): | |
2564 | check_dpp_capab(dev[0]) | |
2565 | check_dpp_capab(dev[1]) | |
2566 | check_dpp_capab(dev[2]) | |
d045b7a1 | 2567 | logger.info("Start AP in unconfigured state") |
fab49f61 | 2568 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"}) |
d045b7a1 | 2569 | check_dpp_capab(hapd) |
a5387062 | 2570 | id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True) |
d045b7a1 | 2571 | uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h) |
d045b7a1 | 2572 | logger.info("Provision AP with DPP configuration") |
e105110f | 2573 | conf_id = dev[1].dpp_configurator_add() |
d045b7a1 | 2574 | dev[1].set("dpp_groups_override", '[{"groupId":"a","netRole":"ap"}]') |
5725b3e3 | 2575 | dev[1].dpp_auth_init(uri=uri, conf="ap-dpp", configurator=conf_id) |
d045b7a1 JM |
2576 | update_hapd_config(hapd) |
2577 | ||
2578 | logger.info("Provision STA0 with DPP Connector that has mismatching groupId") | |
2579 | dev[0].set("dpp_config_processing", "2") | |
a5387062 | 2580 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
d045b7a1 | 2581 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
7e009100 | 2582 | dev[0].dpp_listen(2412) |
d045b7a1 | 2583 | dev[1].set("dpp_groups_override", '[{"groupId":"b","netRole":"sta"}]') |
5725b3e3 JM |
2584 | dev[1].dpp_auth_init(uri=uri0, conf="sta-dpp", configurator=conf_id) |
2585 | wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0]) | |
d045b7a1 JM |
2586 | |
2587 | logger.info("Provision STA2 with DPP Connector that has mismatching C-sign-key") | |
2588 | dev[2].set("dpp_config_processing", "2") | |
a5387062 | 2589 | id2 = dev[2].dpp_bootstrap_gen(chan="81/1", mac=True) |
d045b7a1 | 2590 | uri2 = dev[2].request("DPP_BOOTSTRAP_GET_URI %d" % id2) |
7e009100 | 2591 | dev[2].dpp_listen(2412) |
e105110f | 2592 | conf_id_2 = dev[1].dpp_configurator_add() |
d045b7a1 | 2593 | dev[1].set("dpp_groups_override", '') |
5725b3e3 JM |
2594 | dev[1].dpp_auth_init(uri=uri2, conf="sta-dpp", configurator=conf_id_2) |
2595 | wait_auth_success(dev[2], dev[1], configurator=dev[1], enrollee=dev[2]) | |
d045b7a1 JM |
2596 | |
2597 | logger.info("Provision STA5 with DPP Connector that has mismatching netAccessKey EC group") | |
2598 | wpas.set("dpp_config_processing", "2") | |
a5387062 | 2599 | id5 = wpas.dpp_bootstrap_gen(chan="81/1", mac=True, curve="P-521") |
d045b7a1 | 2600 | uri5 = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % id5) |
7e009100 | 2601 | wpas.dpp_listen(2412) |
d045b7a1 | 2602 | dev[1].set("dpp_groups_override", '') |
5725b3e3 JM |
2603 | dev[1].dpp_auth_init(uri=uri5, conf="sta-dpp", configurator=conf_id) |
2604 | wait_auth_success(wpas, dev[1], configurator=dev[1], enrollee=wpas) | |
d045b7a1 JM |
2605 | |
2606 | logger.info("Verify network introduction results") | |
2607 | ev = dev[0].wait_event(["DPP-INTRO"], timeout=10) | |
2608 | if ev is None: | |
2609 | raise Exception("DPP network introduction result not seen on STA0") | |
2610 | if "status=8" not in ev: | |
2611 | raise Exception("Unexpected network introduction result on STA0: " + ev) | |
2612 | ||
2613 | ev = dev[2].wait_event(["DPP-INTRO"], timeout=5) | |
2614 | if ev is None: | |
2615 | raise Exception("DPP network introduction result not seen on STA2") | |
2616 | if "status=8" not in ev: | |
2617 | raise Exception("Unexpected network introduction result on STA2: " + ev) | |
2618 | ||
2619 | ev = wpas.wait_event(["DPP-INTRO"], timeout=10) | |
2620 | if ev is None: | |
2621 | raise Exception("DPP network introduction result not seen on STA5") | |
2622 | if "status=7" not in ev: | |
2623 | raise Exception("Unexpected network introduction result on STA5: " + ev) | |
2624 | ||
8968acda | 2625 | def run_dpp_proto_init(dev, test_dev, test, mutual=False, unicast=True, |
4e72b1de JM |
2626 | listen=True, chan="81/1", init_enrollee=False, |
2627 | incompatible_roles=False): | |
a0e3e222 JM |
2628 | check_dpp_capab(dev[0]) |
2629 | check_dpp_capab(dev[1]) | |
2630 | dev[test_dev].set("dpp_test", str(test)) | |
c30517c6 | 2631 | if init_enrollee: |
e105110f | 2632 | conf_id = dev[0].dpp_configurator_add() |
c30517c6 | 2633 | else: |
e105110f | 2634 | conf_id = dev[1].dpp_configurator_add() |
a5387062 | 2635 | id0 = dev[0].dpp_bootstrap_gen(chan=chan, mac=unicast) |
a0e3e222 JM |
2636 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
2637 | ||
a0e3e222 | 2638 | if mutual: |
a5387062 | 2639 | id1b = dev[1].dpp_bootstrap_gen(chan="81/1", mac=True) |
a0e3e222 JM |
2640 | uri1b = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1b) |
2641 | ||
0422d06b | 2642 | id0b = dev[0].dpp_qr_code(uri1b) |
7e009100 | 2643 | qr = "mutual" |
47183df7 | 2644 | else: |
7e009100 | 2645 | qr = None |
47183df7 | 2646 | |
c30517c6 | 2647 | if init_enrollee: |
4e72b1de | 2648 | if incompatible_roles: |
7e009100 | 2649 | role = "enrollee" |
4e72b1de | 2650 | else: |
7e009100 | 2651 | role = "configurator" |
c30517c6 | 2652 | dev[0].set("dpp_configurator_params", |
58be42b2 | 2653 | " conf=sta-dpp configurator=%d" % conf_id) |
4e72b1de | 2654 | elif incompatible_roles: |
7e009100 JM |
2655 | role = "enrollee" |
2656 | else: | |
2657 | role = None | |
c30517c6 | 2658 | |
8968acda | 2659 | if listen: |
7e009100 | 2660 | dev[0].dpp_listen(2412, qr=qr, role=role) |
a0e3e222 | 2661 | |
5725b3e3 JM |
2662 | role = None |
2663 | configurator = None | |
2664 | conf = None | |
2665 | own = None | |
2666 | ||
c30517c6 | 2667 | if init_enrollee: |
5725b3e3 | 2668 | role="enrollee" |
c30517c6 | 2669 | else: |
5725b3e3 JM |
2670 | configurator=conf_id |
2671 | conf="sta-dpp" | |
4e72b1de | 2672 | if incompatible_roles: |
5725b3e3 | 2673 | role="enrollee" |
a0e3e222 | 2674 | if mutual: |
5725b3e3 JM |
2675 | own = id1b |
2676 | dev[1].dpp_auth_init(uri=uri0, role=role, configurator=configurator, | |
2677 | conf=conf, own=own) | |
a0e3e222 JM |
2678 | |
2679 | def test_dpp_proto_after_wrapped_data_auth_req(dev, apdev): | |
2680 | """DPP protocol testing - attribute after Wrapped Data in Auth Req""" | |
2681 | run_dpp_proto_init(dev, 1, 1) | |
2682 | ev = dev[0].wait_event(["DPP-RX"], timeout=5) | |
2683 | if ev is None: | |
2684 | raise Exception("DPP Authentication Request not seen") | |
2685 | if "type=0" not in ev or "ignore=invalid-attributes" not in ev: | |
2686 | raise Exception("Unexpected RX info: " + ev) | |
2687 | ev = dev[1].wait_event(["DPP-RX"], timeout=0.1) | |
2688 | if ev is not None: | |
2689 | raise Exception("Unexpected DPP message seen") | |
2690 | ||
8968acda JM |
2691 | def test_dpp_auth_req_stop_after_ack(dev, apdev): |
2692 | """DPP initiator stopping after ACK, but no response""" | |
2693 | run_dpp_proto_init(dev, 1, 1, listen=True) | |
2694 | ev = dev[1].wait_event(["DPP-AUTH-INIT-FAILED"], timeout=5) | |
2695 | if ev is None: | |
2696 | raise Exception("Authentication failure not reported") | |
2697 | ||
2698 | def test_dpp_auth_req_retries(dev, apdev): | |
2699 | """DPP initiator retries with no ACK""" | |
92fe5f56 | 2700 | check_dpp_capab(dev[1]) |
8968acda JM |
2701 | dev[1].set("dpp_init_max_tries", "3") |
2702 | dev[1].set("dpp_init_retry_time", "1000") | |
2703 | dev[1].set("dpp_resp_wait_time", "100") | |
2704 | run_dpp_proto_init(dev, 1, 1, unicast=False, listen=False) | |
2705 | ||
2706 | for i in range(3): | |
edac8087 | 2707 | ev = dev[1].wait_event(["DPP-TX "], timeout=5) |
8968acda JM |
2708 | if ev is None: |
2709 | raise Exception("Auth Req not sent (%d)" % i) | |
8968acda JM |
2710 | |
2711 | ev = dev[1].wait_event(["DPP-AUTH-INIT-FAILED"], timeout=5) | |
2712 | if ev is None: | |
2713 | raise Exception("Authentication failure not reported") | |
2714 | ||
2715 | def test_dpp_auth_req_retries_multi_chan(dev, apdev): | |
2716 | """DPP initiator retries with no ACK and multiple channels""" | |
92fe5f56 | 2717 | check_dpp_capab(dev[1]) |
8968acda JM |
2718 | dev[1].set("dpp_init_max_tries", "3") |
2719 | dev[1].set("dpp_init_retry_time", "1000") | |
2720 | dev[1].set("dpp_resp_wait_time", "100") | |
2721 | run_dpp_proto_init(dev, 1, 1, unicast=False, listen=False, | |
2722 | chan="81/1,81/6,81/11") | |
2723 | ||
2724 | for i in range(3 * 3): | |
edac8087 | 2725 | ev = dev[1].wait_event(["DPP-TX "], timeout=5) |
8968acda JM |
2726 | if ev is None: |
2727 | raise Exception("Auth Req not sent (%d)" % i) | |
8968acda JM |
2728 | |
2729 | ev = dev[1].wait_event(["DPP-AUTH-INIT-FAILED"], timeout=5) | |
2730 | if ev is None: | |
2731 | raise Exception("Authentication failure not reported") | |
2732 | ||
a0e3e222 JM |
2733 | def test_dpp_proto_after_wrapped_data_auth_resp(dev, apdev): |
2734 | """DPP protocol testing - attribute after Wrapped Data in Auth Resp""" | |
2735 | run_dpp_proto_init(dev, 0, 2) | |
2736 | ev = dev[1].wait_event(["DPP-RX"], timeout=5) | |
2737 | if ev is None: | |
2738 | raise Exception("DPP Authentication Response not seen") | |
2739 | if "type=1" not in ev or "ignore=invalid-attributes" not in ev: | |
2740 | raise Exception("Unexpected RX info: " + ev) | |
2741 | ev = dev[0].wait_event(["DPP-RX"], timeout=1) | |
2742 | if ev is None or "type=0" not in ev: | |
2743 | raise Exception("DPP Authentication Request not seen") | |
2744 | ev = dev[0].wait_event(["DPP-RX"], timeout=0.1) | |
2745 | if ev is not None: | |
2746 | raise Exception("Unexpected DPP message seen") | |
2747 | ||
2748 | def test_dpp_proto_after_wrapped_data_auth_conf(dev, apdev): | |
2749 | """DPP protocol testing - attribute after Wrapped Data in Auth Conf""" | |
2750 | run_dpp_proto_init(dev, 1, 3) | |
2751 | ev = dev[0].wait_event(["DPP-RX"], timeout=5) | |
2752 | if ev is None or "type=0" not in ev: | |
2753 | raise Exception("DPP Authentication Request not seen") | |
2754 | ev = dev[0].wait_event(["DPP-RX"], timeout=5) | |
2755 | if ev is None: | |
2756 | raise Exception("DPP Authentication Confirm not seen") | |
2757 | if "type=2" not in ev or "ignore=invalid-attributes" not in ev: | |
2758 | raise Exception("Unexpected RX info: " + ev) | |
2759 | ||
2760 | def test_dpp_proto_after_wrapped_data_conf_req(dev, apdev): | |
2761 | """DPP protocol testing - attribute after Wrapped Data in Conf Req""" | |
2762 | run_dpp_proto_init(dev, 0, 6) | |
2763 | ev = dev[1].wait_event(["DPP-CONF-FAILED"], timeout=10) | |
2764 | if ev is None: | |
2765 | raise Exception("DPP Configuration failure not seen") | |
2766 | ||
2767 | def test_dpp_proto_after_wrapped_data_conf_resp(dev, apdev): | |
2768 | """DPP protocol testing - attribute after Wrapped Data in Conf Resp""" | |
2769 | run_dpp_proto_init(dev, 1, 7) | |
2770 | ev = dev[0].wait_event(["DPP-CONF-FAILED"], timeout=10) | |
2771 | if ev is None: | |
2772 | raise Exception("DPP Configuration failure not seen") | |
2773 | ||
2774 | def test_dpp_proto_zero_i_capab(dev, apdev): | |
2775 | """DPP protocol testing - zero I-capability in Auth Req""" | |
2776 | run_dpp_proto_init(dev, 1, 8) | |
203878d7 | 2777 | wait_dpp_fail(dev[0], "Invalid role in I-capabilities 0x00") |
a0e3e222 JM |
2778 | ev = dev[1].wait_event(["DPP-RX"], timeout=0.1) |
2779 | if ev is not None: | |
2780 | raise Exception("Unexpected DPP message seen") | |
2781 | ||
2782 | def test_dpp_proto_zero_r_capab(dev, apdev): | |
2783 | """DPP protocol testing - zero R-capability in Auth Resp""" | |
2784 | run_dpp_proto_init(dev, 0, 9) | |
203878d7 | 2785 | wait_dpp_fail(dev[1], "Unexpected role in R-capabilities 0x00") |
a0e3e222 JM |
2786 | ev = dev[0].wait_event(["DPP-RX"], timeout=1) |
2787 | if ev is None or "type=0" not in ev: | |
2788 | raise Exception("DPP Authentication Request not seen") | |
2789 | ev = dev[0].wait_event(["DPP-RX"], timeout=0.1) | |
2790 | if ev is not None: | |
2791 | raise Exception("Unexpected DPP message seen") | |
2792 | ||
47183df7 JM |
2793 | def run_dpp_proto_auth_req_missing(dev, test, reason, mutual=False): |
2794 | run_dpp_proto_init(dev, 1, test, mutual=mutual) | |
203878d7 | 2795 | wait_dpp_fail(dev[0], reason) |
a0e3e222 JM |
2796 | ev = dev[1].wait_event(["DPP-RX"], timeout=0.1) |
2797 | if ev is not None: | |
2798 | raise Exception("Unexpected DPP message seen") | |
2799 | ||
2800 | def test_dpp_proto_auth_req_no_r_bootstrap_key(dev, apdev): | |
2801 | """DPP protocol testing - no R-bootstrap key in Auth Req""" | |
2802 | run_dpp_proto_auth_req_missing(dev, 10, "Missing or invalid required Responder Bootstrapping Key Hash attribute") | |
2803 | ||
47183df7 JM |
2804 | def test_dpp_proto_auth_req_invalid_r_bootstrap_key(dev, apdev): |
2805 | """DPP protocol testing - invalid R-bootstrap key in Auth Req""" | |
2806 | run_dpp_proto_auth_req_missing(dev, 68, "No matching own bootstrapping key found - ignore message") | |
2807 | ||
a0e3e222 JM |
2808 | def test_dpp_proto_auth_req_no_i_bootstrap_key(dev, apdev): |
2809 | """DPP protocol testing - no I-bootstrap key in Auth Req""" | |
2810 | run_dpp_proto_auth_req_missing(dev, 11, "Missing or invalid required Initiator Bootstrapping Key Hash attribute") | |
2811 | ||
47183df7 JM |
2812 | def test_dpp_proto_auth_req_invalid_i_bootstrap_key(dev, apdev): |
2813 | """DPP protocol testing - invalid I-bootstrap key in Auth Req""" | |
2814 | run_dpp_proto_init(dev, 1, 69, mutual=True) | |
2815 | ev = dev[0].wait_event(["DPP-SCAN-PEER-QR-CODE"], timeout=5) | |
2816 | if ev is None: | |
2817 | raise Exception("DPP scan request not seen") | |
2818 | ev = dev[1].wait_event(["DPP-RESPONSE-PENDING"], timeout=5) | |
2819 | if ev is None: | |
2820 | raise Exception("DPP response pending indivation not seen") | |
2821 | ||
a0e3e222 JM |
2822 | def test_dpp_proto_auth_req_no_i_proto_key(dev, apdev): |
2823 | """DPP protocol testing - no I-proto key in Auth Req""" | |
2824 | run_dpp_proto_auth_req_missing(dev, 12, "Missing required Initiator Protocol Key attribute") | |
2825 | ||
dc515328 JM |
2826 | def test_dpp_proto_auth_req_invalid_i_proto_key(dev, apdev): |
2827 | """DPP protocol testing - invalid I-proto key in Auth Req""" | |
2828 | run_dpp_proto_auth_req_missing(dev, 66, "Invalid Initiator Protocol Key") | |
2829 | ||
a0e3e222 JM |
2830 | def test_dpp_proto_auth_req_no_i_nonce(dev, apdev): |
2831 | """DPP protocol testing - no I-nonce in Auth Req""" | |
2832 | run_dpp_proto_auth_req_missing(dev, 13, "Missing or invalid I-nonce") | |
2833 | ||
af872d9d JM |
2834 | def test_dpp_proto_auth_req_invalid_i_nonce(dev, apdev): |
2835 | """DPP protocol testing - invalid I-nonce in Auth Req""" | |
2836 | run_dpp_proto_auth_req_missing(dev, 81, "Missing or invalid I-nonce") | |
2837 | ||
a0e3e222 JM |
2838 | def test_dpp_proto_auth_req_no_i_capab(dev, apdev): |
2839 | """DPP protocol testing - no I-capab in Auth Req""" | |
2840 | run_dpp_proto_auth_req_missing(dev, 14, "Missing or invalid I-capab") | |
2841 | ||
2842 | def test_dpp_proto_auth_req_no_wrapped_data(dev, apdev): | |
2843 | """DPP protocol testing - no Wrapped Data in Auth Req""" | |
2844 | run_dpp_proto_auth_req_missing(dev, 15, "Missing or invalid required Wrapped Data attribute") | |
2845 | ||
4e72b1de JM |
2846 | def run_dpp_proto_auth_resp_missing(dev, test, reason, |
2847 | incompatible_roles=False): | |
2848 | run_dpp_proto_init(dev, 0, test, mutual=True, | |
2849 | incompatible_roles=incompatible_roles) | |
a0e3e222 | 2850 | if reason is None: |
3d5cfa0f JM |
2851 | if incompatible_roles: |
2852 | ev = dev[0].wait_event(["DPP-NOT-COMPATIBLE"], timeout=5) | |
2853 | if ev is None: | |
2854 | raise Exception("DPP-NOT-COMPATIBLE not reported") | |
a0e3e222 JM |
2855 | time.sleep(0.1) |
2856 | return | |
203878d7 | 2857 | wait_dpp_fail(dev[1], reason) |
a0e3e222 JM |
2858 | ev = dev[0].wait_event(["DPP-RX"], timeout=1) |
2859 | if ev is None or "type=0" not in ev: | |
2860 | raise Exception("DPP Authentication Request not seen") | |
2861 | ev = dev[0].wait_event(["DPP-RX"], timeout=0.1) | |
2862 | if ev is not None: | |
2863 | raise Exception("Unexpected DPP message seen") | |
2864 | ||
2865 | def test_dpp_proto_auth_resp_no_status(dev, apdev): | |
2866 | """DPP protocol testing - no Status in Auth Resp""" | |
2867 | run_dpp_proto_auth_resp_missing(dev, 16, "Missing or invalid required DPP Status attribute") | |
2868 | ||
4e72b1de JM |
2869 | def test_dpp_proto_auth_resp_status_no_status(dev, apdev): |
2870 | """DPP protocol testing - no Status in Auth Resp(status)""" | |
2871 | run_dpp_proto_auth_resp_missing(dev, 16, | |
2872 | "Missing or invalid required DPP Status attribute", | |
2873 | incompatible_roles=True) | |
2874 | ||
655e82b1 JM |
2875 | def test_dpp_proto_auth_resp_invalid_status(dev, apdev): |
2876 | """DPP protocol testing - invalid Status in Auth Resp""" | |
2877 | run_dpp_proto_auth_resp_missing(dev, 74, "Responder reported failure") | |
2878 | ||
a0e3e222 JM |
2879 | def test_dpp_proto_auth_resp_no_r_bootstrap_key(dev, apdev): |
2880 | """DPP protocol testing - no R-bootstrap key in Auth Resp""" | |
2881 | run_dpp_proto_auth_resp_missing(dev, 17, "Missing or invalid required Responder Bootstrapping Key Hash attribute") | |
2882 | ||
4e72b1de JM |
2883 | def test_dpp_proto_auth_resp_status_no_r_bootstrap_key(dev, apdev): |
2884 | """DPP protocol testing - no R-bootstrap key in Auth Resp(status)""" | |
2885 | run_dpp_proto_auth_resp_missing(dev, 17, | |
2886 | "Missing or invalid required Responder Bootstrapping Key Hash attribute", | |
2887 | incompatible_roles=True) | |
2888 | ||
47183df7 JM |
2889 | def test_dpp_proto_auth_resp_invalid_r_bootstrap_key(dev, apdev): |
2890 | """DPP protocol testing - invalid R-bootstrap key in Auth Resp""" | |
2891 | run_dpp_proto_auth_resp_missing(dev, 70, "Unexpected Responder Bootstrapping Key Hash value") | |
2892 | ||
4e72b1de JM |
2893 | def test_dpp_proto_auth_resp_status_invalid_r_bootstrap_key(dev, apdev): |
2894 | """DPP protocol testing - invalid R-bootstrap key in Auth Resp(status)""" | |
2895 | run_dpp_proto_auth_resp_missing(dev, 70, | |
2896 | "Unexpected Responder Bootstrapping Key Hash value", | |
2897 | incompatible_roles=True) | |
2898 | ||
a0e3e222 JM |
2899 | def test_dpp_proto_auth_resp_no_i_bootstrap_key(dev, apdev): |
2900 | """DPP protocol testing - no I-bootstrap key in Auth Resp""" | |
2901 | run_dpp_proto_auth_resp_missing(dev, 18, None) | |
2902 | ||
4e72b1de JM |
2903 | def test_dpp_proto_auth_resp_status_no_i_bootstrap_key(dev, apdev): |
2904 | """DPP protocol testing - no I-bootstrap key in Auth Resp(status)""" | |
2905 | run_dpp_proto_auth_resp_missing(dev, 18, None, incompatible_roles=True) | |
2906 | ||
47183df7 JM |
2907 | def test_dpp_proto_auth_resp_invalid_i_bootstrap_key(dev, apdev): |
2908 | """DPP protocol testing - invalid I-bootstrap key in Auth Resp""" | |
2909 | run_dpp_proto_auth_resp_missing(dev, 71, "Initiator Bootstrapping Key Hash attribute did not match") | |
2910 | ||
4e72b1de JM |
2911 | def test_dpp_proto_auth_resp_status_invalid_i_bootstrap_key(dev, apdev): |
2912 | """DPP protocol testing - invalid I-bootstrap key in Auth Resp(status)""" | |
2913 | run_dpp_proto_auth_resp_missing(dev, 71, | |
2914 | "Initiator Bootstrapping Key Hash attribute did not match", | |
2915 | incompatible_roles=True) | |
2916 | ||
a0e3e222 JM |
2917 | def test_dpp_proto_auth_resp_no_r_proto_key(dev, apdev): |
2918 | """DPP protocol testing - no R-Proto Key in Auth Resp""" | |
2919 | run_dpp_proto_auth_resp_missing(dev, 19, "Missing required Responder Protocol Key attribute") | |
2920 | ||
dc515328 JM |
2921 | def test_dpp_proto_auth_resp_invalid_r_proto_key(dev, apdev): |
2922 | """DPP protocol testing - invalid R-Proto Key in Auth Resp""" | |
2923 | run_dpp_proto_auth_resp_missing(dev, 67, "Invalid Responder Protocol Key") | |
2924 | ||
a0e3e222 JM |
2925 | def test_dpp_proto_auth_resp_no_r_nonce(dev, apdev): |
2926 | """DPP protocol testing - no R-nonce in Auth Resp""" | |
2927 | run_dpp_proto_auth_resp_missing(dev, 20, "Missing or invalid R-nonce") | |
2928 | ||
2929 | def test_dpp_proto_auth_resp_no_i_nonce(dev, apdev): | |
2930 | """DPP protocol testing - no I-nonce in Auth Resp""" | |
2931 | run_dpp_proto_auth_resp_missing(dev, 21, "Missing or invalid I-nonce") | |
2932 | ||
4e72b1de JM |
2933 | def test_dpp_proto_auth_resp_status_no_i_nonce(dev, apdev): |
2934 | """DPP protocol testing - no I-nonce in Auth Resp(status)""" | |
2935 | run_dpp_proto_auth_resp_missing(dev, 21, "Missing or invalid I-nonce", | |
2936 | incompatible_roles=True) | |
2937 | ||
a0e3e222 JM |
2938 | def test_dpp_proto_auth_resp_no_r_capab(dev, apdev): |
2939 | """DPP protocol testing - no R-capab in Auth Resp""" | |
2940 | run_dpp_proto_auth_resp_missing(dev, 22, "Missing or invalid R-capabilities") | |
2941 | ||
2942 | def test_dpp_proto_auth_resp_no_r_auth(dev, apdev): | |
2943 | """DPP protocol testing - no R-auth in Auth Resp""" | |
2944 | run_dpp_proto_auth_resp_missing(dev, 23, "Missing or invalid Secondary Wrapped Data") | |
2945 | ||
2946 | def test_dpp_proto_auth_resp_no_wrapped_data(dev, apdev): | |
2947 | """DPP protocol testing - no Wrapped Data in Auth Resp""" | |
2948 | run_dpp_proto_auth_resp_missing(dev, 24, "Missing or invalid required Wrapped Data attribute") | |
2949 | ||
ba0840c9 JM |
2950 | def test_dpp_proto_auth_resp_i_nonce_mismatch(dev, apdev): |
2951 | """DPP protocol testing - I-nonce mismatch in Auth Resp""" | |
2952 | run_dpp_proto_init(dev, 0, 30, mutual=True) | |
203878d7 | 2953 | wait_dpp_fail(dev[1], "I-nonce mismatch") |
ba0840c9 JM |
2954 | ev = dev[0].wait_event(["DPP-RX"], timeout=1) |
2955 | if ev is None or "type=0" not in ev: | |
2956 | raise Exception("DPP Authentication Request not seen") | |
2957 | ev = dev[0].wait_event(["DPP-RX"], timeout=0.1) | |
2958 | if ev is not None: | |
2959 | raise Exception("Unexpected DPP message seen") | |
2960 | ||
2961 | def test_dpp_proto_auth_resp_incompatible_r_capab(dev, apdev): | |
2962 | """DPP protocol testing - Incompatible R-capab in Auth Resp""" | |
2963 | run_dpp_proto_init(dev, 0, 31, mutual=True) | |
203878d7 JM |
2964 | wait_dpp_fail(dev[1], "Unexpected role in R-capabilities 0x02") |
2965 | wait_dpp_fail(dev[0], "Peer reported incompatible R-capab role") | |
ba0840c9 JM |
2966 | |
2967 | def test_dpp_proto_auth_resp_r_auth_mismatch(dev, apdev): | |
2968 | """DPP protocol testing - R-auth mismatch in Auth Resp""" | |
2969 | run_dpp_proto_init(dev, 0, 32, mutual=True) | |
203878d7 JM |
2970 | wait_dpp_fail(dev[1], "Mismatching Responder Authenticating Tag") |
2971 | wait_dpp_fail(dev[0], "Peer reported authentication failure") | |
ba0840c9 | 2972 | |
4d38285b JM |
2973 | def test_dpp_proto_auth_resp_r_auth_mismatch_failure(dev, apdev): |
2974 | """DPP protocol testing - Auth Conf RX processing failure""" | |
2975 | with alloc_fail(dev[0], 1, "dpp_auth_conf_rx_failure"): | |
2976 | run_dpp_proto_init(dev, 0, 32, mutual=True) | |
203878d7 | 2977 | wait_dpp_fail(dev[0], "Authentication failed") |
4d38285b JM |
2978 | |
2979 | def test_dpp_proto_auth_resp_r_auth_mismatch_failure2(dev, apdev): | |
2980 | """DPP protocol testing - Auth Conf RX processing failure 2""" | |
2981 | with fail_test(dev[0], 1, "dpp_auth_conf_rx_failure"): | |
2982 | run_dpp_proto_init(dev, 0, 32, mutual=True) | |
203878d7 | 2983 | wait_dpp_fail(dev[0], "AES-SIV decryption failed") |
4d38285b | 2984 | |
b3a93f8f JM |
2985 | def run_dpp_proto_auth_conf_missing(dev, test, reason): |
2986 | run_dpp_proto_init(dev, 1, test, mutual=True) | |
2987 | if reason is None: | |
2988 | time.sleep(0.1) | |
2989 | return | |
203878d7 | 2990 | wait_dpp_fail(dev[0], reason) |
b3a93f8f JM |
2991 | |
2992 | def test_dpp_proto_auth_conf_no_status(dev, apdev): | |
2993 | """DPP protocol testing - no Status in Auth Conf""" | |
2994 | run_dpp_proto_auth_conf_missing(dev, 25, "Missing or invalid required DPP Status attribute") | |
2995 | ||
655e82b1 JM |
2996 | def test_dpp_proto_auth_conf_invalid_status(dev, apdev): |
2997 | """DPP protocol testing - invalid Status in Auth Conf""" | |
2998 | run_dpp_proto_auth_conf_missing(dev, 75, "Authentication failed") | |
2999 | ||
b3a93f8f JM |
3000 | def test_dpp_proto_auth_conf_no_r_bootstrap_key(dev, apdev): |
3001 | """DPP protocol testing - no R-bootstrap key in Auth Conf""" | |
3002 | run_dpp_proto_auth_conf_missing(dev, 26, "Missing or invalid required Responder Bootstrapping Key Hash attribute") | |
3003 | ||
47183df7 JM |
3004 | def test_dpp_proto_auth_conf_invalid_r_bootstrap_key(dev, apdev): |
3005 | """DPP protocol testing - invalid R-bootstrap key in Auth Conf""" | |
3006 | run_dpp_proto_auth_conf_missing(dev, 72, "Responder Bootstrapping Key Hash mismatch") | |
3007 | ||
b3a93f8f JM |
3008 | def test_dpp_proto_auth_conf_no_i_bootstrap_key(dev, apdev): |
3009 | """DPP protocol testing - no I-bootstrap key in Auth Conf""" | |
f7380b47 | 3010 | run_dpp_proto_auth_conf_missing(dev, 27, "Missing Initiator Bootstrapping Key Hash attribute") |
b3a93f8f | 3011 | |
47183df7 JM |
3012 | def test_dpp_proto_auth_conf_invalid_i_bootstrap_key(dev, apdev): |
3013 | """DPP protocol testing - invalid I-bootstrap key in Auth Conf""" | |
3014 | run_dpp_proto_auth_conf_missing(dev, 73, "Initiator Bootstrapping Key Hash mismatch") | |
3015 | ||
b3a93f8f JM |
3016 | def test_dpp_proto_auth_conf_no_i_auth(dev, apdev): |
3017 | """DPP protocol testing - no I-Auth in Auth Conf""" | |
3018 | run_dpp_proto_auth_conf_missing(dev, 28, "Missing or invalid Initiator Authenticating Tag") | |
3019 | ||
3020 | def test_dpp_proto_auth_conf_no_wrapped_data(dev, apdev): | |
3021 | """DPP protocol testing - no Wrapped Data in Auth Conf""" | |
3022 | run_dpp_proto_auth_conf_missing(dev, 29, "Missing or invalid required Wrapped Data attribute") | |
3023 | ||
ba0840c9 JM |
3024 | def test_dpp_proto_auth_conf_i_auth_mismatch(dev, apdev): |
3025 | """DPP protocol testing - I-auth mismatch in Auth Conf""" | |
3026 | run_dpp_proto_init(dev, 1, 33, mutual=True) | |
203878d7 | 3027 | wait_dpp_fail(dev[0], "Mismatching Initiator Authenticating Tag") |
ba0840c9 | 3028 | |
3eae3ee2 JM |
3029 | def test_dpp_proto_auth_conf_replaced_by_resp(dev, apdev): |
3030 | """DPP protocol testing - Auth Conf replaced by Resp""" | |
3031 | run_dpp_proto_init(dev, 1, 65, mutual=True) | |
203878d7 | 3032 | wait_dpp_fail(dev[0], "Unexpected Authentication Response") |
3eae3ee2 | 3033 | |
bdf987b7 JM |
3034 | def run_dpp_proto_conf_req_missing(dev, test, reason): |
3035 | run_dpp_proto_init(dev, 0, test) | |
203878d7 | 3036 | wait_dpp_fail(dev[1], reason) |
bdf987b7 JM |
3037 | |
3038 | def test_dpp_proto_conf_req_no_e_nonce(dev, apdev): | |
3039 | """DPP protocol testing - no E-nonce in Conf Req""" | |
3040 | run_dpp_proto_conf_req_missing(dev, 51, | |
3041 | "Missing or invalid Enrollee Nonce attribute") | |
3042 | ||
5f170c99 JM |
3043 | def test_dpp_proto_conf_req_invalid_e_nonce(dev, apdev): |
3044 | """DPP protocol testing - invalid E-nonce in Conf Req""" | |
3045 | run_dpp_proto_conf_req_missing(dev, 83, | |
3046 | "Missing or invalid Enrollee Nonce attribute") | |
3047 | ||
bdf987b7 JM |
3048 | def test_dpp_proto_conf_req_no_config_attr_obj(dev, apdev): |
3049 | """DPP protocol testing - no Config Attr Obj in Conf Req""" | |
3050 | run_dpp_proto_conf_req_missing(dev, 52, | |
3051 | "Missing or invalid Config Attributes attribute") | |
3052 | ||
b0fda6b7 JM |
3053 | def test_dpp_proto_conf_req_invalid_config_attr_obj(dev, apdev): |
3054 | """DPP protocol testing - invalid Config Attr Obj in Conf Req""" | |
3055 | run_dpp_proto_conf_req_missing(dev, 76, | |
3056 | "Unsupported wi-fi_tech") | |
3057 | ||
bdf987b7 JM |
3058 | def test_dpp_proto_conf_req_no_wrapped_data(dev, apdev): |
3059 | """DPP protocol testing - no Wrapped Data in Conf Req""" | |
3060 | run_dpp_proto_conf_req_missing(dev, 53, | |
3061 | "Missing or invalid required Wrapped Data attribute") | |
3062 | ||
3063 | def run_dpp_proto_conf_resp_missing(dev, test, reason): | |
3064 | run_dpp_proto_init(dev, 1, test) | |
203878d7 | 3065 | wait_dpp_fail(dev[0], reason) |
bdf987b7 JM |
3066 | |
3067 | def test_dpp_proto_conf_resp_no_e_nonce(dev, apdev): | |
3068 | """DPP protocol testing - no E-nonce in Conf Resp""" | |
3069 | run_dpp_proto_conf_resp_missing(dev, 54, | |
3070 | "Missing or invalid Enrollee Nonce attribute") | |
3071 | ||
3072 | def test_dpp_proto_conf_resp_no_config_obj(dev, apdev): | |
3073 | """DPP protocol testing - no Config Object in Conf Resp""" | |
3074 | run_dpp_proto_conf_resp_missing(dev, 55, | |
3075 | "Missing required Configuration Object attribute") | |
3076 | ||
3077 | def test_dpp_proto_conf_resp_no_status(dev, apdev): | |
3078 | """DPP protocol testing - no Status in Conf Resp""" | |
3079 | run_dpp_proto_conf_resp_missing(dev, 56, | |
3080 | "Missing or invalid required DPP Status attribute") | |
3081 | ||
3082 | def test_dpp_proto_conf_resp_no_wrapped_data(dev, apdev): | |
3083 | """DPP protocol testing - no Wrapped Data in Conf Resp""" | |
3084 | run_dpp_proto_conf_resp_missing(dev, 57, | |
3085 | "Missing or invalid required Wrapped Data attribute") | |
3086 | ||
686cfce9 JM |
3087 | def test_dpp_proto_conf_resp_invalid_status(dev, apdev): |
3088 | """DPP protocol testing - invalid Status in Conf Resp""" | |
3089 | run_dpp_proto_conf_resp_missing(dev, 58, | |
3090 | "Configurator rejected configuration") | |
3091 | ||
3092 | def test_dpp_proto_conf_resp_e_nonce_mismatch(dev, apdev): | |
3093 | """DPP protocol testing - E-nonce mismatch in Conf Resp""" | |
3094 | run_dpp_proto_conf_resp_missing(dev, 59, | |
3095 | "Enrollee Nonce mismatch") | |
3096 | ||
c30517c6 JM |
3097 | def test_dpp_proto_stop_at_auth_req(dev, apdev): |
3098 | """DPP protocol testing - stop when receiving Auth Req""" | |
3099 | run_dpp_proto_init(dev, 0, 87) | |
3100 | ev = dev[1].wait_event(["DPP-AUTH-INIT-FAILED"], timeout=5) | |
3101 | if ev is None: | |
3102 | raise Exception("Authentication init failure not reported") | |
3103 | ||
3104 | def test_dpp_proto_stop_at_auth_resp(dev, apdev): | |
3105 | """DPP protocol testing - stop when receiving Auth Resp""" | |
3106 | run_dpp_proto_init(dev, 1, 88) | |
3107 | ||
3108 | ev = dev[1].wait_event(["DPP-TX "], timeout=5) | |
3109 | if ev is None: | |
3110 | raise Exception("Auth Req TX not seen") | |
3111 | ||
3112 | ev = dev[0].wait_event(["DPP-TX "], timeout=5) | |
3113 | if ev is None: | |
3114 | raise Exception("Auth Resp TX not seen") | |
3115 | ||
3116 | ev = dev[1].wait_event(["DPP-TX "], timeout=0.1) | |
3117 | if ev is not None: | |
3118 | raise Exception("Unexpected Auth Conf TX") | |
3119 | ||
3120 | def test_dpp_proto_stop_at_auth_conf(dev, apdev): | |
3121 | """DPP protocol testing - stop when receiving Auth Conf""" | |
3122 | run_dpp_proto_init(dev, 0, 89, init_enrollee=True) | |
3123 | ev = dev[1].wait_event(["GAS-QUERY-START"], timeout=10) | |
3124 | if ev is None: | |
3125 | raise Exception("Enrollee did not start GAS") | |
3126 | ev = dev[1].wait_event(["GAS-QUERY-DONE"], timeout=10) | |
3127 | if ev is None: | |
3128 | raise Exception("Enrollee did not time out GAS") | |
3129 | if "result=TIMEOUT" not in ev: | |
3130 | raise Exception("Unexpected GAS result: " + ev) | |
3131 | ||
c63e69c3 JM |
3132 | def test_dpp_proto_stop_at_auth_conf_tx(dev, apdev): |
3133 | """DPP protocol testing - stop when transmitting Auth Conf (Registrar)""" | |
3134 | run_dpp_proto_init(dev, 1, 89, init_enrollee=True) | |
517f76b1 | 3135 | wait_auth_success(dev[0], dev[1], timeout=10) |
c63e69c3 JM |
3136 | ev = dev[1].wait_event(["GAS-QUERY-START"], timeout=0.1) |
3137 | if ev is not None: | |
3138 | raise Exception("Unexpected GAS query") | |
3139 | ||
3140 | # There is currently no timeout on GAS server side, so no event to wait for | |
3141 | # in this case. | |
3142 | ||
3143 | def test_dpp_proto_stop_at_auth_conf_tx2(dev, apdev): | |
3144 | """DPP protocol testing - stop when transmitting Auth Conf (Enrollee)""" | |
3145 | run_dpp_proto_init(dev, 1, 89) | |
517f76b1 | 3146 | wait_auth_success(dev[0], dev[1], timeout=10) |
c63e69c3 JM |
3147 | |
3148 | ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=5) | |
3149 | if ev is None or "result=TIMEOUT" not in ev: | |
3150 | raise Exception("GAS query did not time out") | |
3151 | ||
c30517c6 JM |
3152 | def test_dpp_proto_stop_at_conf_req(dev, apdev): |
3153 | """DPP protocol testing - stop when receiving Auth Req""" | |
3154 | run_dpp_proto_init(dev, 1, 90) | |
3155 | ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=10) | |
3156 | if ev is None: | |
3157 | raise Exception("Enrollee did not start GAS") | |
3158 | ev = dev[0].wait_event(["GAS-QUERY-DONE"], timeout=10) | |
3159 | if ev is None: | |
3160 | raise Exception("Enrollee did not time out GAS") | |
3161 | if "result=TIMEOUT" not in ev: | |
3162 | raise Exception("Unexpected GAS result: " + ev) | |
3163 | ||
a0e3e222 JM |
3164 | def run_dpp_proto_init_pkex(dev, test_dev, test): |
3165 | check_dpp_capab(dev[0]) | |
3166 | check_dpp_capab(dev[1]) | |
3167 | dev[test_dev].set("dpp_test", str(test)) | |
6d196e59 JM |
3168 | dev[0].dpp_pkex_resp(2437, identifier="test", code="secret") |
3169 | dev[1].dpp_pkex_init(identifier="test", code="secret") | |
a0e3e222 JM |
3170 | |
3171 | def test_dpp_proto_after_wrapped_data_pkex_cr_req(dev, apdev): | |
3172 | """DPP protocol testing - attribute after Wrapped Data in PKEX CR Req""" | |
3173 | run_dpp_proto_init_pkex(dev, 1, 4) | |
3174 | ev = dev[0].wait_event(["DPP-RX"], timeout=5) | |
3175 | if ev is None or "type=7" not in ev: | |
3176 | raise Exception("PKEX Exchange Request not seen") | |
3177 | ev = dev[0].wait_event(["DPP-RX"], timeout=5) | |
3178 | if ev is None or "type=9" not in ev: | |
3179 | raise Exception("PKEX Commit-Reveal Request not seen") | |
3180 | if "ignore=invalid-attributes" not in ev: | |
3181 | raise Exception("Unexpected RX info: " + ev) | |
3182 | ||
3183 | def test_dpp_proto_after_wrapped_data_pkex_cr_resp(dev, apdev): | |
3184 | """DPP protocol testing - attribute after Wrapped Data in PKEX CR Resp""" | |
3185 | run_dpp_proto_init_pkex(dev, 0, 5) | |
3186 | ev = dev[1].wait_event(["DPP-RX"], timeout=5) | |
3187 | if ev is None or "type=8" not in ev: | |
3188 | raise Exception("PKEX Exchange Response not seen") | |
3189 | ev = dev[1].wait_event(["DPP-RX"], timeout=5) | |
3190 | if ev is None or "type=10" not in ev: | |
3191 | raise Exception("PKEX Commit-Reveal Response not seen") | |
3192 | if "ignore=invalid-attributes" not in ev: | |
3193 | raise Exception("Unexpected RX info: " + ev) | |
d5f89062 JM |
3194 | |
3195 | def run_dpp_proto_pkex_req_missing(dev, test, reason): | |
3196 | run_dpp_proto_init_pkex(dev, 1, test) | |
203878d7 | 3197 | wait_dpp_fail(dev[0], reason) |
d5f89062 JM |
3198 | |
3199 | def run_dpp_proto_pkex_resp_missing(dev, test, reason): | |
3200 | run_dpp_proto_init_pkex(dev, 0, test) | |
203878d7 | 3201 | wait_dpp_fail(dev[1], reason) |
d5f89062 JM |
3202 | |
3203 | def test_dpp_proto_pkex_exchange_req_no_finite_cyclic_group(dev, apdev): | |
3204 | """DPP protocol testing - no Finite Cyclic Group in PKEX Exchange Request""" | |
3205 | run_dpp_proto_pkex_req_missing(dev, 34, | |
3206 | "Missing or invalid Finite Cyclic Group attribute") | |
3207 | ||
3208 | def test_dpp_proto_pkex_exchange_req_no_encrypted_key(dev, apdev): | |
3209 | """DPP protocol testing - no Encrypted Key in PKEX Exchange Request""" | |
3210 | run_dpp_proto_pkex_req_missing(dev, 35, | |
3211 | "Missing Encrypted Key attribute") | |
3212 | ||
3213 | def test_dpp_proto_pkex_exchange_resp_no_status(dev, apdev): | |
3214 | """DPP protocol testing - no Status in PKEX Exchange Response""" | |
3215 | run_dpp_proto_pkex_resp_missing(dev, 36, "No DPP Status attribute") | |
3216 | ||
3217 | def test_dpp_proto_pkex_exchange_resp_no_encrypted_key(dev, apdev): | |
3218 | """DPP protocol testing - no Encrypted Key in PKEX Exchange Response""" | |
3219 | run_dpp_proto_pkex_resp_missing(dev, 37, "Missing Encrypted Key attribute") | |
3220 | ||
3221 | def test_dpp_proto_pkex_cr_req_no_bootstrap_key(dev, apdev): | |
3222 | """DPP protocol testing - no Bootstrap Key in PKEX Commit-Reveal Request""" | |
3223 | run_dpp_proto_pkex_req_missing(dev, 38, | |
3224 | "No valid peer bootstrapping key found") | |
3225 | ||
3226 | def test_dpp_proto_pkex_cr_req_no_i_auth_tag(dev, apdev): | |
3227 | """DPP protocol testing - no I-Auth Tag in PKEX Commit-Reveal Request""" | |
3228 | run_dpp_proto_pkex_req_missing(dev, 39, "No valid u (I-Auth tag) found") | |
3229 | ||
3230 | def test_dpp_proto_pkex_cr_req_no_wrapped_data(dev, apdev): | |
3231 | """DPP protocol testing - no Wrapped Data in PKEX Commit-Reveal Request""" | |
3232 | run_dpp_proto_pkex_req_missing(dev, 40, "Missing or invalid required Wrapped Data attribute") | |
3233 | ||
3234 | def test_dpp_proto_pkex_cr_resp_no_bootstrap_key(dev, apdev): | |
3235 | """DPP protocol testing - no Bootstrap Key in PKEX Commit-Reveal Response""" | |
3236 | run_dpp_proto_pkex_resp_missing(dev, 41, | |
3237 | "No valid peer bootstrapping key found") | |
3238 | ||
3239 | def test_dpp_proto_pkex_cr_resp_no_r_auth_tag(dev, apdev): | |
3240 | """DPP protocol testing - no R-Auth Tag in PKEX Commit-Reveal Response""" | |
3241 | run_dpp_proto_pkex_resp_missing(dev, 42, "No valid v (R-Auth tag) found") | |
3242 | ||
3243 | def test_dpp_proto_pkex_cr_resp_no_wrapped_data(dev, apdev): | |
3244 | """DPP protocol testing - no Wrapped Data in PKEX Commit-Reveal Response""" | |
3245 | run_dpp_proto_pkex_resp_missing(dev, 43, "Missing or invalid required Wrapped Data attribute") | |
dea2ab99 JM |
3246 | |
3247 | def test_dpp_proto_pkex_exchange_req_invalid_encrypted_key(dev, apdev): | |
3248 | """DPP protocol testing - invalid Encrypted Key in PKEX Exchange Request""" | |
3249 | run_dpp_proto_pkex_req_missing(dev, 44, | |
3250 | "Invalid Encrypted Key value") | |
3251 | ||
3252 | def test_dpp_proto_pkex_exchange_resp_invalid_encrypted_key(dev, apdev): | |
3253 | """DPP protocol testing - invalid Encrypted Key in PKEX Exchange Response""" | |
3254 | run_dpp_proto_pkex_resp_missing(dev, 45, | |
3255 | "Invalid Encrypted Key value") | |
230028a3 JM |
3256 | |
3257 | def test_dpp_proto_pkex_exchange_resp_invalid_status(dev, apdev): | |
3258 | """DPP protocol testing - invalid Status in PKEX Exchange Response""" | |
3259 | run_dpp_proto_pkex_resp_missing(dev, 46, | |
3260 | "PKEX failed (peer indicated failure)") | |
fd4639aa JM |
3261 | |
3262 | def test_dpp_proto_pkex_cr_req_invalid_bootstrap_key(dev, apdev): | |
3263 | """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Request""" | |
3264 | run_dpp_proto_pkex_req_missing(dev, 47, | |
3265 | "Peer bootstrapping key is invalid") | |
3266 | ||
3267 | def test_dpp_proto_pkex_cr_resp_invalid_bootstrap_key(dev, apdev): | |
3268 | """DPP protocol testing - invalid Bootstrap Key in PKEX Commit-Reveal Response""" | |
3269 | run_dpp_proto_pkex_resp_missing(dev, 48, | |
3270 | "Peer bootstrapping key is invalid") | |
c20d3ca8 JM |
3271 | |
3272 | def test_dpp_proto_pkex_cr_req_i_auth_tag_mismatch(dev, apdev): | |
3273 | """DPP protocol testing - I-auth tag mismatch in PKEX Commit-Reveal Request""" | |
3274 | run_dpp_proto_pkex_req_missing(dev, 49, "No valid u (I-Auth tag) found") | |
3275 | ||
3276 | def test_dpp_proto_pkex_cr_resp_r_auth_tag_mismatch(dev, apdev): | |
3277 | """DPP protocol testing - R-auth tag mismatch in PKEX Commit-Reveal Response""" | |
3278 | run_dpp_proto_pkex_resp_missing(dev, 50, "No valid v (R-Auth tag) found") | |
993eab91 | 3279 | |
c30517c6 JM |
3280 | def test_dpp_proto_stop_at_pkex_exchange_resp(dev, apdev): |
3281 | """DPP protocol testing - stop when receiving PKEX Exchange Response""" | |
3282 | run_dpp_proto_init_pkex(dev, 1, 84) | |
3283 | ||
3284 | ev = dev[1].wait_event(["DPP-TX "], timeout=5) | |
3285 | if ev is None: | |
3286 | raise Exception("PKEX Exchange Req TX not seen") | |
3287 | ||
3288 | ev = dev[0].wait_event(["DPP-TX "], timeout=5) | |
3289 | if ev is None: | |
3290 | raise Exception("PKEX Exchange Resp not seen") | |
3291 | ||
3292 | ev = dev[1].wait_event(["DPP-TX "], timeout=0.1) | |
3293 | if ev is not None: | |
3294 | raise Exception("Unexpected PKEX CR Req TX") | |
3295 | ||
3296 | def test_dpp_proto_stop_at_pkex_cr_req(dev, apdev): | |
3297 | """DPP protocol testing - stop when receiving PKEX CR Request""" | |
3298 | run_dpp_proto_init_pkex(dev, 0, 85) | |
3299 | ||
3300 | ev = dev[1].wait_event(["DPP-TX "], timeout=5) | |
3301 | if ev is None: | |
3302 | raise Exception("PKEX Exchange Req TX not seen") | |
3303 | ||
3304 | ev = dev[0].wait_event(["DPP-TX "], timeout=5) | |
3305 | if ev is None: | |
3306 | raise Exception("PKEX Exchange Resp not seen") | |
3307 | ||
3308 | ev = dev[1].wait_event(["DPP-TX "], timeout=5) | |
3309 | if ev is None: | |
3310 | raise Exception("PKEX CR Req TX not seen") | |
3311 | ||
3312 | ev = dev[0].wait_event(["DPP-TX "], timeout=0.1) | |
3313 | if ev is not None: | |
3314 | raise Exception("Unexpected PKEX CR Resp TX") | |
3315 | ||
3316 | def test_dpp_proto_stop_at_pkex_cr_resp(dev, apdev): | |
3317 | """DPP protocol testing - stop when receiving PKEX CR Response""" | |
3318 | run_dpp_proto_init_pkex(dev, 1, 86) | |
3319 | ||
3320 | ev = dev[1].wait_event(["DPP-TX "], timeout=5) | |
3321 | if ev is None: | |
3322 | raise Exception("PKEX Exchange Req TX not seen") | |
3323 | ||
3324 | ev = dev[0].wait_event(["DPP-TX "], timeout=5) | |
3325 | if ev is None: | |
3326 | raise Exception("PKEX Exchange Resp not seen") | |
3327 | ||
3328 | ev = dev[1].wait_event(["DPP-TX "], timeout=5) | |
3329 | if ev is None: | |
3330 | raise Exception("PKEX CR Req TX not seen") | |
3331 | ||
3332 | ev = dev[0].wait_event(["DPP-TX "], timeout=5) | |
3333 | if ev is None: | |
3334 | raise Exception("PKEX CR Resp TX not seen") | |
3335 | ||
3336 | ev = dev[1].wait_event(["DPP-TX "], timeout=0.1) | |
3337 | if ev is not None: | |
3338 | raise Exception("Unexpected Auth Req TX") | |
3339 | ||
993eab91 JM |
3340 | def test_dpp_proto_network_introduction(dev, apdev): |
3341 | """DPP protocol testing - network introduction""" | |
3342 | check_dpp_capab(dev[0]) | |
3343 | check_dpp_capab(dev[1]) | |
3344 | ||
fab49f61 JM |
3345 | params = {"ssid": "dpp", |
3346 | "wpa": "2", | |
3347 | "wpa_key_mgmt": "DPP", | |
3348 | "ieee80211w": "2", | |
3349 | "rsn_pairwise": "CCMP", | |
3350 | "dpp_connector": params1_ap_connector, | |
3351 | "dpp_csign": params1_csign, | |
3352 | "dpp_netaccesskey": params1_ap_netaccesskey} | |
993eab91 JM |
3353 | try: |
3354 | hapd = hostapd.add_ap(apdev[0], params) | |
3355 | except: | |
3356 | raise HwsimSkip("DPP not supported") | |
3357 | ||
fab49f61 | 3358 | for test in [60, 61, 80, 82]: |
993eab91 JM |
3359 | dev[0].set("dpp_test", str(test)) |
3360 | dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", ieee80211w="2", | |
7e26f1bc JM |
3361 | dpp_csign=params1_csign, |
3362 | dpp_connector=params1_sta_connector, | |
3363 | dpp_netaccesskey=params1_sta_netaccesskey, | |
3364 | wait_connect=False) | |
993eab91 | 3365 | |
dbdd445d | 3366 | ev = dev[0].wait_event(["DPP-TX "], timeout=10) |
993eab91 JM |
3367 | if ev is None or "type=5" not in ev: |
3368 | raise Exception("Peer Discovery Request TX not reported") | |
3369 | ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=2) | |
3370 | if ev is None or "result=SUCCESS" not in ev: | |
3371 | raise Exception("Peer Discovery Request TX status not reported") | |
3372 | ||
3373 | ev = hapd.wait_event(["DPP-RX"], timeout=10) | |
3374 | if ev is None or "type=5" not in ev: | |
3375 | raise Exception("Peer Discovery Request RX not reported") | |
3376 | ||
de731ec2 JM |
3377 | if test == 80: |
3378 | ev = dev[0].wait_event(["DPP-INTRO"], timeout=10) | |
3379 | if ev is None: | |
3380 | raise Exception("DPP-INTRO not reported for test 80") | |
3381 | if "status=7" not in ev: | |
3382 | raise Exception("Unexpected result in test 80: " + ev) | |
3383 | ||
993eab91 JM |
3384 | dev[0].request("REMOVE_NETWORK all") |
3385 | dev[0].dump_monitor() | |
3386 | hapd.dump_monitor() | |
3387 | dev[0].set("dpp_test", "0") | |
3388 | ||
fab49f61 | 3389 | for test in [62, 63, 64, 77, 78, 79]: |
993eab91 JM |
3390 | hapd.set("dpp_test", str(test)) |
3391 | dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", ieee80211w="2", | |
7e26f1bc JM |
3392 | dpp_csign=params1_csign, |
3393 | dpp_connector=params1_sta_connector, | |
3394 | dpp_netaccesskey=params1_sta_netaccesskey, | |
3395 | wait_connect=False) | |
993eab91 JM |
3396 | |
3397 | ev = dev[0].wait_event(["DPP-INTRO"], timeout=10) | |
3398 | if ev is None: | |
de731ec2 JM |
3399 | raise Exception("Peer introduction result not reported (test %d)" % test) |
3400 | if test == 77: | |
3401 | if "fail=transaction_id_mismatch" not in ev: | |
3402 | raise Exception("Connector validation failure not reported") | |
3403 | elif test == 78: | |
3404 | if "status=254" not in ev: | |
3405 | raise Exception("Invalid status value not reported") | |
3406 | elif test == 79: | |
3407 | if "fail=peer_connector_validation_failed" not in ev: | |
3408 | raise Exception("Connector validation failure not reported") | |
3409 | elif "status=" in ev: | |
3410 | raise Exception("Unexpected peer introduction result (test %d): " % test + ev) | |
993eab91 JM |
3411 | |
3412 | dev[0].request("REMOVE_NETWORK all") | |
3413 | dev[0].dump_monitor() | |
3414 | hapd.dump_monitor() | |
3415 | hapd.set("dpp_test", "0") | |
3416 | ||
3417 | dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", ieee80211w="2", | |
7e26f1bc JM |
3418 | dpp_csign=params1_csign, dpp_connector=params1_sta_connector, |
3419 | dpp_netaccesskey=params1_sta_netaccesskey) | |
751f7f7c JM |
3420 | |
3421 | def test_dpp_qr_code_no_chan_list_unicast(dev, apdev): | |
3422 | """DPP QR Code and no channel list (unicast)""" | |
3423 | run_dpp_qr_code_chan_list(dev, apdev, True, 2417, None) | |
3424 | ||
3425 | def test_dpp_qr_code_chan_list_unicast(dev, apdev): | |
3426 | """DPP QR Code and 2.4 GHz channels (unicast)""" | |
3427 | run_dpp_qr_code_chan_list(dev, apdev, True, 2417, | |
3428 | "81/1,81/2,81/3,81/4,81/5,81/6,81/7,81/8,81/9,81/10,81/11,81/12,81/13") | |
3429 | ||
35814134 JM |
3430 | def test_dpp_qr_code_chan_list_unicast2(dev, apdev): |
3431 | """DPP QR Code and 2.4 GHz channels (unicast 2)""" | |
3432 | run_dpp_qr_code_chan_list(dev, apdev, True, 2417, | |
3433 | "81/1,2,3,4,5,6,7,8,9,10,11,12,13") | |
3434 | ||
751f7f7c JM |
3435 | def test_dpp_qr_code_chan_list_no_peer_unicast(dev, apdev): |
3436 | """DPP QR Code and channel list and no peer (unicast)""" | |
3437 | run_dpp_qr_code_chan_list(dev, apdev, True, 2417, "81/1,81/6,81/11", | |
3438 | no_wait=True) | |
3439 | ev = dev[1].wait_event(["DPP-AUTH-INIT-FAILED"], timeout=5) | |
3440 | if ev is None: | |
3441 | raise Exception("Initiation failure not reported") | |
3442 | ||
3443 | def test_dpp_qr_code_no_chan_list_broadcast(dev, apdev): | |
3444 | """DPP QR Code and no channel list (broadcast)""" | |
3445 | run_dpp_qr_code_chan_list(dev, apdev, False, 2412, None) | |
3446 | ||
3447 | def test_dpp_qr_code_chan_list_broadcast(dev, apdev): | |
3448 | """DPP QR Code and some 2.4 GHz channels (broadcast)""" | |
3449 | run_dpp_qr_code_chan_list(dev, apdev, False, 2412, "81/1,81/6,81/11", | |
3450 | timeout=10) | |
3451 | ||
3452 | def run_dpp_qr_code_chan_list(dev, apdev, unicast, listen_freq, chanlist, | |
3453 | no_wait=False, timeout=5): | |
3454 | check_dpp_capab(dev[0]) | |
3455 | check_dpp_capab(dev[1]) | |
3456 | dev[1].set("dpp_init_max_tries", "3") | |
3457 | dev[1].set("dpp_init_retry_time", "100") | |
8968acda | 3458 | dev[1].set("dpp_resp_wait_time", "1000") |
751f7f7c JM |
3459 | |
3460 | logger.info("dev0 displays QR Code") | |
a5387062 | 3461 | id0 = dev[0].dpp_bootstrap_gen(chan=chanlist, mac=unicast) |
751f7f7c | 3462 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
5725b3e3 | 3463 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 3464 | dev[0].dpp_listen(listen_freq) |
5725b3e3 | 3465 | dev[1].dpp_auth_init(uri=uri0) |
751f7f7c JM |
3466 | if no_wait: |
3467 | return | |
517f76b1 JM |
3468 | wait_auth_success(dev[0], dev[1], timeout=timeout, configurator=dev[1], |
3469 | enrollee=dev[0], allow_enrollee_failure=True, | |
3470 | stop_responder=True) | |
751f7f7c JM |
3471 | |
3472 | def test_dpp_qr_code_chan_list_no_match(dev, apdev): | |
3473 | """DPP QR Code and no matching supported channel""" | |
3474 | check_dpp_capab(dev[0]) | |
3475 | check_dpp_capab(dev[1]) | |
a5387062 | 3476 | id0 = dev[0].dpp_bootstrap_gen(chan="123/123") |
751f7f7c | 3477 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
5725b3e3 | 3478 | dev[1].dpp_auth_init(uri=uri0, expect_fail=True) |
818e3c94 JM |
3479 | |
3480 | def test_dpp_pkex_alloc_fail(dev, apdev): | |
3481 | """DPP/PKEX and memory allocation failures""" | |
3482 | check_dpp_capab(dev[0]) | |
3483 | check_dpp_capab(dev[1]) | |
3484 | ||
fab49f61 JM |
3485 | tests = [(1, "=dpp_keygen_configurator"), |
3486 | (1, "base64_gen_encode;dpp_keygen_configurator")] | |
818e3c94 JM |
3487 | for count, func in tests: |
3488 | with alloc_fail(dev[1], count, func): | |
3489 | cmd = "DPP_CONFIGURATOR_ADD" | |
58be42b2 | 3490 | res = dev[1].request(cmd) |
818e3c94 JM |
3491 | if "FAIL" not in res: |
3492 | raise Exception("Unexpected DPP_CONFIGURATOR_ADD success") | |
3493 | ||
e105110f | 3494 | conf_id = dev[1].dpp_configurator_add() |
818e3c94 | 3495 | |
6d196e59 JM |
3496 | id0 = None |
3497 | id1 = None | |
818e3c94 JM |
3498 | |
3499 | # Local error cases on the Initiator | |
fab49f61 JM |
3500 | tests = [(1, "dpp_get_pubkey_point"), |
3501 | (1, "dpp_alloc_msg;dpp_pkex_build_exchange_req"), | |
3502 | (1, "dpp_alloc_msg;dpp_pkex_build_commit_reveal_req"), | |
3503 | (1, "dpp_alloc_msg;dpp_auth_build_req"), | |
3504 | (1, "dpp_alloc_msg;dpp_auth_build_conf"), | |
3505 | (1, "dpp_bootstrap_key_hash"), | |
3506 | (1, "dpp_auth_init"), | |
269a7878 | 3507 | (1, "dpp_alloc_auth"), |
fab49f61 | 3508 | (1, "=dpp_auth_resp_rx"), |
fab49f61 JM |
3509 | (1, "dpp_build_conf_start"), |
3510 | (1, "dpp_build_conf_obj_dpp"), | |
3511 | (2, "dpp_build_conf_obj_dpp"), | |
3512 | (3, "dpp_build_conf_obj_dpp"), | |
3513 | (4, "dpp_build_conf_obj_dpp"), | |
3514 | (5, "dpp_build_conf_obj_dpp"), | |
3515 | (6, "dpp_build_conf_obj_dpp"), | |
3516 | (7, "dpp_build_conf_obj_dpp"), | |
3517 | (8, "dpp_build_conf_obj_dpp"), | |
3518 | (1, "dpp_conf_req_rx"), | |
3519 | (2, "dpp_conf_req_rx"), | |
3520 | (3, "dpp_conf_req_rx"), | |
3521 | (4, "dpp_conf_req_rx"), | |
3522 | (5, "dpp_conf_req_rx"), | |
3523 | (6, "dpp_conf_req_rx"), | |
3524 | (7, "dpp_conf_req_rx"), | |
3525 | (1, "dpp_pkex_init"), | |
3526 | (2, "dpp_pkex_init"), | |
3527 | (3, "dpp_pkex_init"), | |
3528 | (1, "dpp_pkex_derive_z"), | |
3529 | (1, "=dpp_pkex_rx_commit_reveal_resp"), | |
3530 | (1, "dpp_get_pubkey_point;dpp_build_jwk"), | |
3531 | (2, "dpp_get_pubkey_point;dpp_build_jwk"), | |
3532 | (1, "dpp_get_pubkey_point;dpp_auth_init")] | |
818e3c94 JM |
3533 | for count, func in tests: |
3534 | dev[0].request("DPP_STOP_LISTEN") | |
3535 | dev[1].request("DPP_STOP_LISTEN") | |
3536 | dev[0].dump_monitor() | |
3537 | dev[1].dump_monitor() | |
6d196e59 JM |
3538 | id0 = dev[0].dpp_pkex_resp(2437, identifier="test", code="secret", |
3539 | use_id=id0) | |
818e3c94 JM |
3540 | |
3541 | with alloc_fail(dev[1], count, func): | |
6d196e59 JM |
3542 | id1 = dev[1].dpp_pkex_init(identifier="test", code="secret", |
3543 | use_id=id1, | |
3544 | extra="conf=sta-dpp configurator=%d" % conf_id, | |
3545 | allow_fail=True) | |
8b5a4973 | 3546 | wait_fail_trigger(dev[1], "GET_ALLOC_FAIL", max_iter=100) |
818e3c94 JM |
3547 | ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=0.01) |
3548 | if ev: | |
3549 | dev[0].request("DPP_STOP_LISTEN") | |
3550 | dev[0].wait_event(["GAS-QUERY-DONE"], timeout=3) | |
3551 | ||
3552 | # Local error cases on the Responder | |
fab49f61 JM |
3553 | tests = [(1, "dpp_get_pubkey_point"), |
3554 | (1, "dpp_alloc_msg;dpp_pkex_build_exchange_resp"), | |
3555 | (1, "dpp_alloc_msg;dpp_pkex_build_commit_reveal_resp"), | |
3556 | (1, "dpp_alloc_msg;dpp_auth_build_resp"), | |
3557 | (1, "dpp_get_pubkey_point;dpp_auth_build_resp_ok"), | |
269a7878 | 3558 | (1, "dpp_alloc_auth"), |
fab49f61 | 3559 | (1, "=dpp_auth_req_rx"), |
fab49f61 JM |
3560 | (1, "=dpp_auth_conf_rx"), |
3561 | (1, "json_parse;dpp_parse_jws_prot_hdr"), | |
3562 | (1, "json_get_member_base64url;dpp_parse_jws_prot_hdr"), | |
3563 | (1, "json_get_member_base64url;dpp_parse_jwk"), | |
3564 | (2, "json_get_member_base64url;dpp_parse_jwk"), | |
3565 | (1, "json_parse;dpp_parse_connector"), | |
3566 | (1, "dpp_parse_jwk;dpp_parse_connector"), | |
3567 | (1, "dpp_parse_jwk;dpp_parse_cred_dpp"), | |
3568 | (1, "dpp_get_pubkey_point;dpp_check_pubkey_match"), | |
3569 | (1, "base64_gen_decode;dpp_process_signed_connector"), | |
3570 | (1, "dpp_parse_jws_prot_hdr;dpp_process_signed_connector"), | |
3571 | (2, "base64_gen_decode;dpp_process_signed_connector"), | |
3572 | (3, "base64_gen_decode;dpp_process_signed_connector"), | |
3573 | (4, "base64_gen_decode;dpp_process_signed_connector"), | |
3574 | (1, "json_parse;dpp_parse_conf_obj"), | |
3575 | (1, "dpp_conf_resp_rx"), | |
3576 | (1, "=dpp_pkex_derive_z"), | |
3577 | (1, "=dpp_pkex_rx_exchange_req"), | |
3578 | (2, "=dpp_pkex_rx_exchange_req"), | |
3579 | (3, "=dpp_pkex_rx_exchange_req"), | |
3580 | (1, "=dpp_pkex_rx_commit_reveal_req"), | |
3581 | (1, "dpp_get_pubkey_point;dpp_pkex_rx_commit_reveal_req"), | |
3582 | (1, "dpp_bootstrap_key_hash")] | |
818e3c94 JM |
3583 | for count, func in tests: |
3584 | dev[0].request("DPP_STOP_LISTEN") | |
3585 | dev[1].request("DPP_STOP_LISTEN") | |
3586 | dev[0].dump_monitor() | |
3587 | dev[1].dump_monitor() | |
6d196e59 JM |
3588 | id0 = dev[0].dpp_pkex_resp(2437, identifier="test", code="secret", |
3589 | use_id=id0) | |
818e3c94 JM |
3590 | |
3591 | with alloc_fail(dev[0], count, func): | |
6d196e59 JM |
3592 | id1 = dev[1].dpp_pkex_init(identifier="test", code="secret", |
3593 | use_id=id1, | |
3594 | extra="conf=sta-dpp configurator=%d" % conf_id) | |
8b5a4973 | 3595 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL", max_iter=100) |
818e3c94 JM |
3596 | ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=0.01) |
3597 | if ev: | |
3598 | dev[0].request("DPP_STOP_LISTEN") | |
3599 | dev[0].wait_event(["GAS-QUERY-DONE"], timeout=3) | |
3600 | ||
3601 | def test_dpp_pkex_test_fail(dev, apdev): | |
3602 | """DPP/PKEX and local failures""" | |
3603 | check_dpp_capab(dev[0]) | |
3604 | check_dpp_capab(dev[1]) | |
3605 | ||
fab49f61 | 3606 | tests = [(1, "dpp_keygen_configurator")] |
818e3c94 JM |
3607 | for count, func in tests: |
3608 | with fail_test(dev[1], count, func): | |
3609 | cmd = "DPP_CONFIGURATOR_ADD" | |
58be42b2 | 3610 | res = dev[1].request(cmd) |
818e3c94 JM |
3611 | if "FAIL" not in res: |
3612 | raise Exception("Unexpected DPP_CONFIGURATOR_ADD success") | |
3613 | ||
fab49f61 | 3614 | tests = [(1, "dpp_keygen")] |
818e3c94 JM |
3615 | for count, func in tests: |
3616 | with fail_test(dev[1], count, func): | |
3617 | cmd = "DPP_BOOTSTRAP_GEN type=pkex" | |
58be42b2 | 3618 | res = dev[1].request(cmd) |
818e3c94 JM |
3619 | if "FAIL" not in res: |
3620 | raise Exception("Unexpected DPP_BOOTSTRAP_GEN success") | |
3621 | ||
e105110f | 3622 | conf_id = dev[1].dpp_configurator_add() |
818e3c94 | 3623 | |
6d196e59 JM |
3624 | id0 = None |
3625 | id1 = None | |
818e3c94 JM |
3626 | |
3627 | # Local error cases on the Initiator | |
fab49f61 JM |
3628 | tests = [(1, "aes_siv_encrypt;dpp_auth_build_req"), |
3629 | (1, "os_get_random;dpp_auth_init"), | |
3630 | (1, "dpp_derive_k1;dpp_auth_init"), | |
3631 | (1, "dpp_hkdf_expand;dpp_derive_k1;dpp_auth_init"), | |
3632 | (1, "dpp_gen_i_auth;dpp_auth_build_conf"), | |
3633 | (1, "aes_siv_encrypt;dpp_auth_build_conf"), | |
3634 | (1, "dpp_derive_k2;dpp_auth_resp_rx"), | |
3635 | (1, "dpp_hkdf_expand;dpp_derive_k2;dpp_auth_resp_rx"), | |
3636 | (1, "dpp_derive_ke;dpp_auth_resp_rx"), | |
3637 | (1, "dpp_hkdf_expand;dpp_derive_ke;dpp_auth_resp_rx"), | |
3638 | (1, "dpp_gen_r_auth;dpp_auth_resp_rx"), | |
3639 | (1, "aes_siv_encrypt;dpp_build_conf_resp"), | |
3640 | (1, "dpp_pkex_derive_Qi;dpp_pkex_build_exchange_req"), | |
3641 | (1, "aes_siv_encrypt;dpp_pkex_build_commit_reveal_req"), | |
3642 | (1, "hmac_sha256_vector;dpp_pkex_rx_exchange_resp"), | |
3643 | (1, "aes_siv_decrypt;dpp_pkex_rx_commit_reveal_resp"), | |
3644 | (1, "hmac_sha256_vector;dpp_pkex_rx_commit_reveal_resp"), | |
3645 | (1, "dpp_bootstrap_key_hash")] | |
818e3c94 JM |
3646 | for count, func in tests: |
3647 | dev[0].request("DPP_STOP_LISTEN") | |
3648 | dev[1].request("DPP_STOP_LISTEN") | |
3649 | dev[0].dump_monitor() | |
3650 | dev[1].dump_monitor() | |
6d196e59 JM |
3651 | id0 = dev[0].dpp_pkex_resp(2437, identifier="test", code="secret", |
3652 | use_id=id0) | |
818e3c94 JM |
3653 | |
3654 | with fail_test(dev[1], count, func): | |
6d196e59 JM |
3655 | id1 = dev[1].dpp_pkex_init(identifier="test", code="secret", |
3656 | use_id=id1, | |
3657 | extra="conf=sta-dpp configurator=%d" % conf_id, | |
3658 | allow_fail=True) | |
8b5a4973 | 3659 | wait_fail_trigger(dev[1], "GET_FAIL", max_iter=100) |
818e3c94 JM |
3660 | ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=0.01) |
3661 | if ev: | |
3662 | dev[0].request("DPP_STOP_LISTEN") | |
3663 | dev[0].wait_event(["GAS-QUERY-DONE"], timeout=3) | |
3664 | ||
3665 | # Local error cases on the Responder | |
fab49f61 JM |
3666 | tests = [(1, "aes_siv_encrypt;dpp_auth_build_resp"), |
3667 | (1, "aes_siv_encrypt;dpp_auth_build_resp;dpp_auth_build_resp_ok"), | |
3668 | (1, "os_get_random;dpp_build_conf_req"), | |
3669 | (1, "aes_siv_encrypt;dpp_build_conf_req"), | |
3670 | (1, "os_get_random;dpp_auth_build_resp_ok"), | |
3671 | (1, "dpp_derive_k2;dpp_auth_build_resp_ok"), | |
3672 | (1, "dpp_derive_ke;dpp_auth_build_resp_ok"), | |
3673 | (1, "dpp_gen_r_auth;dpp_auth_build_resp_ok"), | |
3674 | (1, "aes_siv_encrypt;dpp_auth_build_resp_ok"), | |
3675 | (1, "dpp_derive_k1;dpp_auth_req_rx"), | |
3676 | (1, "aes_siv_decrypt;dpp_auth_req_rx"), | |
3677 | (1, "aes_siv_decrypt;dpp_auth_conf_rx"), | |
3678 | (1, "dpp_gen_i_auth;dpp_auth_conf_rx"), | |
3679 | (1, "dpp_check_pubkey_match"), | |
3680 | (1, "aes_siv_decrypt;dpp_conf_resp_rx"), | |
3681 | (1, "hmac_sha256_kdf;dpp_pkex_derive_z"), | |
3682 | (1, "dpp_pkex_derive_Qi;dpp_pkex_rx_exchange_req"), | |
3683 | (1, "dpp_pkex_derive_Qr;dpp_pkex_rx_exchange_req"), | |
3684 | (1, "aes_siv_encrypt;dpp_pkex_build_commit_reveal_resp"), | |
3685 | (1, "aes_siv_decrypt;dpp_pkex_rx_commit_reveal_req"), | |
3686 | (1, "hmac_sha256_vector;dpp_pkex_rx_commit_reveal_req"), | |
3687 | (2, "hmac_sha256_vector;dpp_pkex_rx_commit_reveal_req")] | |
818e3c94 JM |
3688 | for count, func in tests: |
3689 | dev[0].request("DPP_STOP_LISTEN") | |
3690 | dev[1].request("DPP_STOP_LISTEN") | |
3691 | dev[0].dump_monitor() | |
3692 | dev[1].dump_monitor() | |
6d196e59 JM |
3693 | id0 = dev[0].dpp_pkex_resp(2437, identifier="test", code="secret", |
3694 | use_id=id0) | |
818e3c94 JM |
3695 | |
3696 | with fail_test(dev[0], count, func): | |
6d196e59 JM |
3697 | id1 = dev[1].dpp_pkex_init(identifier="test", code="secret", |
3698 | use_id=id1, | |
3699 | extra="conf=sta-dpp configurator=%d" % conf_id) | |
818e3c94 JM |
3700 | wait_fail_trigger(dev[0], "GET_FAIL", max_iter=100) |
3701 | ev = dev[0].wait_event(["GAS-QUERY-START"], timeout=0.01) | |
3702 | if ev: | |
3703 | dev[0].request("DPP_STOP_LISTEN") | |
3704 | dev[0].wait_event(["GAS-QUERY-DONE"], timeout=3) | |
f1e2d381 JM |
3705 | |
3706 | def test_dpp_keygen_configurator_error(dev, apdev): | |
3707 | """DPP Configurator keygen error case""" | |
3708 | check_dpp_capab(dev[0]) | |
3709 | if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD curve=unknown"): | |
3710 | raise Exception("Unexpected success of invalid DPP_CONFIGURATOR_ADD") | |
a46b60c4 JM |
3711 | |
3712 | def rx_process_frame(dev): | |
3713 | msg = dev.mgmt_rx() | |
8b6c834f JM |
3714 | if msg is None: |
3715 | raise Exception("No management frame RX reported") | |
54c58f29 MH |
3716 | if "OK" not in dev.request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format( |
3717 | msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())): | |
a46b60c4 | 3718 | raise Exception("MGMT_RX_PROCESS failed") |
ba6ce9c6 | 3719 | return msg |
a46b60c4 | 3720 | |
517f76b1 JM |
3721 | def wait_auth_success(responder, initiator, configurator=None, enrollee=None, |
3722 | allow_enrollee_failure=False, | |
3723 | allow_configurator_failure=False, | |
3724 | require_configurator_failure=False, | |
3725 | timeout=5, stop_responder=False, stop_initiator=False): | |
b256d939 | 3726 | res = {} |
517f76b1 JM |
3727 | ev = responder.wait_event(["DPP-AUTH-SUCCESS", "DPP-FAIL"], timeout=timeout) |
3728 | if ev is None or "DPP-AUTH-SUCCESS" not in ev: | |
a46b60c4 | 3729 | raise Exception("DPP authentication did not succeed (Responder)") |
517f76b1 JM |
3730 | ev = initiator.wait_event(["DPP-AUTH-SUCCESS", "DPP-FAIL"], timeout=5) |
3731 | if ev is None or "DPP-AUTH-SUCCESS" not in ev: | |
a46b60c4 | 3732 | raise Exception("DPP authentication did not succeed (Initiator)") |
517f76b1 JM |
3733 | if configurator: |
3734 | ev = configurator.wait_event(["DPP-CONF-SENT", | |
3735 | "DPP-CONF-FAILED"], timeout=5) | |
3736 | if ev is None: | |
3737 | raise Exception("DPP configuration not completed (Configurator)") | |
3738 | if "DPP-CONF-FAILED" in ev and not allow_configurator_failure: | |
19d4a5de | 3739 | raise Exception("DPP configuration did not succeed (Configurator)") |
530b31ea JM |
3740 | if "DPP-CONF-SENT" in ev and require_configurator_failure: |
3741 | raise Exception("DPP configuration succeeded (Configurator)") | |
b256d939 JM |
3742 | if "DPP-CONF-SENT" in ev and "wait_conn_status=1" in ev: |
3743 | res['wait_conn_status'] = True | |
517f76b1 JM |
3744 | if enrollee: |
3745 | ev = enrollee.wait_event(["DPP-CONF-RECEIVED", | |
3746 | "DPP-CONF-FAILED"], timeout=5) | |
3747 | if ev is None: | |
3748 | raise Exception("DPP configuration not completed (Enrollee)") | |
3749 | if "DPP-CONF-FAILED" in ev and not allow_enrollee_failure: | |
3750 | raise Exception("DPP configuration did not succeed (Enrollee)") | |
3751 | if stop_responder: | |
3752 | responder.request("DPP_STOP_LISTEN") | |
3753 | if stop_initiator: | |
3754 | initiator.request("DPP_STOP_LISTEN") | |
b256d939 | 3755 | return res |
a46b60c4 JM |
3756 | |
3757 | def wait_conf_completion(configurator, enrollee): | |
3758 | ev = configurator.wait_event(["DPP-CONF-SENT"], timeout=5) | |
3759 | if ev is None: | |
3760 | raise Exception("DPP configuration not completed (Configurator)") | |
3761 | ev = enrollee.wait_event(["DPP-CONF-RECEIVED", "DPP-CONF-FAILED"], | |
3762 | timeout=5) | |
3763 | if ev is None: | |
3764 | raise Exception("DPP configuration not completed (Enrollee)") | |
3765 | ||
3766 | def start_dpp(dev): | |
a5387062 | 3767 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
a46b60c4 JM |
3768 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
3769 | ||
a46b60c4 JM |
3770 | conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"test"},"cred":{"akm":"psk","pass":"secret passphrase"}}' + 3000*' ' |
3771 | dev[0].set("dpp_config_obj_override", conf) | |
3772 | ||
3773 | dev[0].set("ext_mgmt_frame_handling", "1") | |
7e009100 | 3774 | dev[0].dpp_listen(2412) |
5725b3e3 | 3775 | dev[1].dpp_auth_init(uri=uri0, role="enrollee") |
a46b60c4 JM |
3776 | |
3777 | def test_dpp_gas_timeout_handling(dev, apdev): | |
3778 | """DPP and GAS timeout handling""" | |
3779 | check_dpp_capab(dev[0]) | |
3780 | check_dpp_capab(dev[1]) | |
3781 | start_dpp(dev) | |
3782 | ||
3783 | # DPP Authentication Request | |
3784 | rx_process_frame(dev[0]) | |
3785 | ||
3786 | # DPP Authentication Confirmation | |
3787 | rx_process_frame(dev[0]) | |
3788 | ||
3789 | wait_auth_success(dev[0], dev[1]) | |
3790 | ||
3791 | # DPP Configuration Request (GAS Initial Request frame) | |
3792 | rx_process_frame(dev[0]) | |
3793 | ||
3794 | # DPP Configuration Request (GAS Comeback Request frame) | |
3795 | rx_process_frame(dev[0]) | |
3796 | ||
3797 | # Wait for GAS timeout | |
3798 | ev = dev[1].wait_event(["DPP-CONF-FAILED"], timeout=5) | |
3799 | if ev is None: | |
3800 | raise Exception("DPP configuration not completed (Enrollee)") | |
3801 | ||
3802 | def test_dpp_gas_comeback_after_failure(dev, apdev): | |
3803 | """DPP and GAS comeback after failure""" | |
3804 | check_dpp_capab(dev[0]) | |
3805 | check_dpp_capab(dev[1]) | |
3806 | start_dpp(dev) | |
3807 | ||
3808 | # DPP Authentication Request | |
3809 | rx_process_frame(dev[0]) | |
3810 | ||
3811 | # DPP Authentication Confirmation | |
3812 | rx_process_frame(dev[0]) | |
3813 | ||
3814 | wait_auth_success(dev[0], dev[1]) | |
3815 | ||
3816 | # DPP Configuration Request (GAS Initial Request frame) | |
3817 | rx_process_frame(dev[0]) | |
3818 | ||
3819 | # DPP Configuration Request (GAS Comeback Request frame) | |
3820 | msg = dev[0].mgmt_rx() | |
54c58f29 | 3821 | frame = binascii.hexlify(msg['frame']).decode() |
a46b60c4 JM |
3822 | with alloc_fail(dev[0], 1, "gas_build_comeback_resp;gas_server_handle_rx_comeback_req"): |
3823 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)): | |
3824 | raise Exception("MGMT_RX_PROCESS failed") | |
3825 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
3826 | # Try the same frame again - this is expected to fail since the response has | |
3827 | # already been freed. | |
3828 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)): | |
3829 | raise Exception("MGMT_RX_PROCESS failed") | |
3830 | ||
3831 | # DPP Configuration Request (GAS Comeback Request frame retry) | |
3832 | msg = dev[0].mgmt_rx() | |
3833 | ||
3834 | def test_dpp_gas(dev, apdev): | |
3835 | """DPP and GAS protocol testing""" | |
8b6c834f JM |
3836 | ver0 = check_dpp_capab(dev[0]) |
3837 | ver1 = check_dpp_capab(dev[1]) | |
a46b60c4 JM |
3838 | start_dpp(dev) |
3839 | ||
3840 | # DPP Authentication Request | |
3841 | rx_process_frame(dev[0]) | |
3842 | ||
3843 | # DPP Authentication Confirmation | |
3844 | rx_process_frame(dev[0]) | |
3845 | ||
3846 | wait_auth_success(dev[0], dev[1]) | |
3847 | ||
3848 | # DPP Configuration Request (GAS Initial Request frame) | |
3849 | msg = dev[0].mgmt_rx() | |
3850 | ||
3851 | # Protected Dual of GAS Initial Request frame (dropped by GAS server) | |
54c58f29 MH |
3852 | if msg == None: |
3853 | raise Exception("MGMT_RX_PROCESS failed. <Please retry>") | |
3854 | frame = binascii.hexlify(msg['frame']) | |
3855 | frame = frame[0:48] + b"09" + frame[50:] | |
3856 | frame = frame.decode() | |
a46b60c4 JM |
3857 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)): |
3858 | raise Exception("MGMT_RX_PROCESS failed") | |
3859 | ||
3860 | with alloc_fail(dev[0], 1, "gas_server_send_resp"): | |
54c58f29 | 3861 | frame = binascii.hexlify(msg['frame']).decode() |
a46b60c4 JM |
3862 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)): |
3863 | raise Exception("MGMT_RX_PROCESS failed") | |
3864 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
3865 | ||
3866 | with alloc_fail(dev[0], 1, "gas_build_initial_resp;gas_server_send_resp"): | |
54c58f29 | 3867 | frame = binascii.hexlify(msg['frame']).decode() |
a46b60c4 JM |
3868 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)): |
3869 | raise Exception("MGMT_RX_PROCESS failed") | |
3870 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
3871 | ||
3872 | # Add extra data after Query Request field to trigger | |
3873 | # "GAS: Ignored extra data after Query Request field" | |
54c58f29 | 3874 | frame = binascii.hexlify(msg['frame']).decode() + "00" |
a46b60c4 JM |
3875 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)): |
3876 | raise Exception("MGMT_RX_PROCESS failed") | |
3877 | ||
3878 | # DPP Configuration Request (GAS Comeback Request frame) | |
3879 | rx_process_frame(dev[0]) | |
3880 | ||
3881 | # DPP Configuration Request (GAS Comeback Request frame) | |
3882 | rx_process_frame(dev[0]) | |
3883 | ||
3884 | # DPP Configuration Request (GAS Comeback Request frame) | |
3885 | rx_process_frame(dev[0]) | |
3886 | ||
8b6c834f JM |
3887 | if ver0 >= 2 and ver1 >= 2: |
3888 | # DPP Configuration Result | |
3889 | rx_process_frame(dev[0]) | |
3890 | ||
a46b60c4 | 3891 | wait_conf_completion(dev[0], dev[1]) |
01e39ba9 JM |
3892 | |
3893 | def test_dpp_truncated_attr(dev, apdev): | |
3894 | """DPP and truncated attribute""" | |
3895 | check_dpp_capab(dev[0]) | |
3896 | check_dpp_capab(dev[1]) | |
3897 | start_dpp(dev) | |
3898 | ||
3899 | # DPP Authentication Request | |
3900 | msg = dev[0].mgmt_rx() | |
3901 | frame = msg['frame'] | |
3902 | ||
3903 | # DPP: Truncated message - not enough room for the attribute - dropped | |
54c58f29 | 3904 | frame1 = binascii.hexlify(frame[0:36]).decode() |
01e39ba9 JM |
3905 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame1)): |
3906 | raise Exception("MGMT_RX_PROCESS failed") | |
3907 | ev = dev[0].wait_event(["DPP-RX"], timeout=5) | |
3908 | if ev is None or "ignore=invalid-attributes" not in ev: | |
3909 | raise Exception("Invalid attribute error not reported") | |
3910 | ||
3911 | # DPP: Unexpected octets (3) after the last attribute | |
54c58f29 | 3912 | frame2 = binascii.hexlify(frame).decode() + "000000" |
01e39ba9 JM |
3913 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame2)): |
3914 | raise Exception("MGMT_RX_PROCESS failed") | |
3915 | ev = dev[0].wait_event(["DPP-RX"], timeout=5) | |
3916 | if ev is None or "ignore=invalid-attributes" not in ev: | |
3917 | raise Exception("Invalid attribute error not reported") | |
f1042596 JM |
3918 | |
3919 | def test_dpp_bootstrap_key_autogen_issues(dev, apdev): | |
3920 | """DPP bootstrap key autogen issues""" | |
3921 | check_dpp_capab(dev[0]) | |
3922 | check_dpp_capab(dev[1]) | |
3923 | ||
3924 | logger.info("dev0 displays QR Code") | |
a5387062 | 3925 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
f1042596 JM |
3926 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
3927 | ||
3928 | logger.info("dev1 scans QR Code") | |
0422d06b | 3929 | id1 = dev[1].dpp_qr_code(uri0) |
f1042596 JM |
3930 | |
3931 | logger.info("dev1 initiates DPP Authentication") | |
7e009100 | 3932 | dev[0].dpp_listen(2412) |
f1042596 | 3933 | with alloc_fail(dev[1], 1, "dpp_autogen_bootstrap_key"): |
5725b3e3 | 3934 | dev[1].dpp_auth_init(peer=id1, expect_fail=True) |
2bbe6ad3 | 3935 | with alloc_fail(dev[1], 1, "dpp_gen_uri;dpp_autogen_bootstrap_key"): |
5725b3e3 | 3936 | dev[1].dpp_auth_init(peer=id1, expect_fail=True) |
f1042596 | 3937 | with fail_test(dev[1], 1, "dpp_keygen;dpp_autogen_bootstrap_key"): |
5725b3e3 | 3938 | dev[1].dpp_auth_init(peer=id1, expect_fail=True) |
f1042596 | 3939 | dev[0].request("DPP_STOP_LISTEN") |
14ea96db JM |
3940 | |
3941 | def test_dpp_auth_resp_status_failure(dev, apdev): | |
3942 | """DPP and Auth Resp(status) build failure""" | |
3943 | with alloc_fail(dev[0], 1, "dpp_auth_build_resp"): | |
3944 | run_dpp_proto_auth_resp_missing(dev, 99999, None, | |
3945 | incompatible_roles=True) | |
4ea1915b JM |
3946 | |
3947 | def test_dpp_auth_resp_aes_siv_issue(dev, apdev): | |
3948 | """DPP Auth Resp AES-SIV issue""" | |
3949 | check_dpp_capab(dev[0]) | |
3950 | check_dpp_capab(dev[1]) | |
4ea1915b | 3951 | logger.info("dev0 displays QR Code") |
a5387062 | 3952 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
4ea1915b | 3953 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
5725b3e3 | 3954 | logger.info("dev1 scans QR Code and initiates DPP Authentication") |
7e009100 | 3955 | dev[0].dpp_listen(2412) |
4ea1915b | 3956 | with fail_test(dev[1], 1, "aes_siv_decrypt;dpp_auth_resp_rx"): |
5725b3e3 | 3957 | dev[1].dpp_auth_init(uri=uri0) |
203878d7 | 3958 | wait_dpp_fail(dev[1], "AES-SIV decryption failed") |
4ea1915b | 3959 | dev[0].request("DPP_STOP_LISTEN") |
77e4f012 JM |
3960 | |
3961 | def test_dpp_invalid_legacy_params(dev, apdev): | |
3962 | """DPP invalid legacy parameters""" | |
3963 | check_dpp_capab(dev[0]) | |
3964 | check_dpp_capab(dev[1]) | |
a5387062 | 3965 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
77e4f012 | 3966 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
77e4f012 | 3967 | # No pass/psk |
5725b3e3 JM |
3968 | dev[1].dpp_auth_init(uri=uri0, conf="sta-psk", ssid="dpp-legacy", |
3969 | expect_fail=True) | |
77e4f012 JM |
3970 | |
3971 | def test_dpp_invalid_legacy_params2(dev, apdev): | |
3972 | """DPP invalid legacy parameters 2""" | |
3973 | check_dpp_capab(dev[0]) | |
3974 | check_dpp_capab(dev[1]) | |
a5387062 | 3975 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
77e4f012 | 3976 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
77e4f012 | 3977 | dev[0].set("dpp_configurator_params", |
54c58f29 | 3978 | " conf=sta-psk ssid=%s" % (binascii.hexlify(b"dpp-legacy").decode())) |
7e009100 | 3979 | dev[0].dpp_listen(2412, role="configurator") |
5725b3e3 | 3980 | dev[1].dpp_auth_init(uri=uri0, role="enrollee") |
77e4f012 | 3981 | # No pass/psk |
77e4f012 JM |
3982 | ev = dev[0].wait_event(["DPP: Failed to set configurator parameters"], |
3983 | timeout=5) | |
3984 | if ev is None: | |
3985 | raise Exception("DPP configuration failure not reported") | |
88d4e0ba JM |
3986 | |
3987 | def test_dpp_legacy_params_failure(dev, apdev): | |
3988 | """DPP legacy parameters local failure""" | |
3989 | check_dpp_capab(dev[0]) | |
3990 | check_dpp_capab(dev[1]) | |
a5387062 | 3991 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
88d4e0ba | 3992 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) |
7e009100 | 3993 | dev[0].dpp_listen(2412) |
88d4e0ba | 3994 | with alloc_fail(dev[1], 1, "dpp_build_conf_obj_legacy"): |
5725b3e3 JM |
3995 | dev[1].dpp_auth_init(uri=uri0, conf="sta-psk", passphrase="passphrase", |
3996 | ssid="dpp-legacy") | |
88d4e0ba JM |
3997 | ev = dev[0].wait_event(["DPP-CONF-FAILED"], timeout=5) |
3998 | if ev is None: | |
3999 | raise Exception("DPP configuration failure not reported") | |
1ddf1b34 JM |
4000 | |
4001 | def test_dpp_invalid_configurator_key(dev, apdev): | |
4002 | """DPP invalid configurator key""" | |
4003 | check_dpp_capab(dev[0]) | |
4004 | ||
4005 | if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=aa"): | |
4006 | raise Exception("Invalid key accepted") | |
4007 | ||
4008 | with alloc_fail(dev[0], 1, "dpp_keygen_configurator"): | |
4009 | if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256): | |
4010 | raise Exception("Error not reported") | |
4011 | ||
4012 | with alloc_fail(dev[0], 1, "dpp_get_pubkey_point;dpp_keygen_configurator"): | |
4013 | if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256): | |
4014 | raise Exception("Error not reported") | |
4015 | ||
4016 | with alloc_fail(dev[0], 1, "base64_gen_encode;dpp_keygen_configurator"): | |
4017 | if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256): | |
4018 | raise Exception("Error not reported") | |
4019 | ||
4020 | with fail_test(dev[0], 1, "dpp_keygen_configurator"): | |
4021 | if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_ADD key=" + dpp_key_p256): | |
4022 | raise Exception("Error not reported") | |
b856b943 JM |
4023 | |
4024 | def test_dpp_own_config_sign_fail(dev, apdev): | |
4025 | """DPP own config signing failure""" | |
4026 | check_dpp_capab(dev[0]) | |
e105110f | 4027 | conf_id = dev[0].dpp_configurator_add() |
fab49f61 JM |
4028 | tests = ["", |
4029 | " ", | |
4030 | " conf=sta-dpp", | |
4031 | " configurator=%d" % conf_id, | |
4032 | " conf=sta-dpp configurator=%d curve=unsupported" % conf_id] | |
b856b943 JM |
4033 | for t in tests: |
4034 | if "FAIL" not in dev[0].request("DPP_CONFIGURATOR_SIGN " + t): | |
4035 | raise Exception("Invalid command accepted: " + t) | |
5c6c42aa JM |
4036 | |
4037 | def test_dpp_peer_intro_failures(dev, apdev): | |
4038 | """DPP peer introduction failures""" | |
4039 | try: | |
4040 | run_dpp_peer_intro_failures(dev, apdev) | |
4041 | finally: | |
5bf51d38 | 4042 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
5c6c42aa JM |
4043 | |
4044 | def run_dpp_peer_intro_failures(dev, apdev): | |
4045 | check_dpp_capab(dev[0]) | |
fab49f61 | 4046 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"}) |
5c6c42aa JM |
4047 | check_dpp_capab(hapd) |
4048 | ||
e105110f | 4049 | conf_id = hapd.dpp_configurator_add(key=dpp_key_p256) |
5c6c42aa JM |
4050 | csign = hapd.request("DPP_CONFIGURATOR_GET_KEY %d" % conf_id) |
4051 | if "FAIL" in csign or len(csign) == 0: | |
4052 | raise Exception("DPP_CONFIGURATOR_GET_KEY failed") | |
4053 | ||
e105110f | 4054 | conf_id2 = dev[0].dpp_configurator_add(key=csign) |
5c6c42aa JM |
4055 | csign2 = dev[0].request("DPP_CONFIGURATOR_GET_KEY %d" % conf_id2) |
4056 | ||
4057 | if csign != csign2: | |
4058 | raise Exception("Unexpected difference in configurator key") | |
4059 | ||
4060 | cmd = "DPP_CONFIGURATOR_SIGN conf=ap-dpp configurator=%d" % conf_id | |
4061 | res = hapd.request(cmd) | |
4062 | if "FAIL" in res: | |
4063 | raise Exception("Failed to generate own configuration") | |
4064 | update_hapd_config(hapd) | |
4065 | ||
4066 | dev[0].set("dpp_config_processing", "1") | |
4067 | cmd = "DPP_CONFIGURATOR_SIGN conf=sta-dpp configurator=%d" % conf_id | |
4068 | res = dev[0].request(cmd) | |
4069 | if "FAIL" in res: | |
4070 | raise Exception("Failed to generate own configuration") | |
4071 | ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1) | |
4072 | if ev is None: | |
4073 | raise Exception("DPP network profile not generated") | |
4074 | id = ev.split(' ')[1] | |
4075 | dev[0].select_network(id, freq=2412) | |
4076 | dev[0].wait_connected() | |
4077 | dev[0].request("DISCONNECT") | |
4078 | dev[0].wait_disconnected() | |
4079 | dev[0].dump_monitor() | |
4080 | ||
fab49f61 JM |
4081 | tests = ["eyJ0eXAiOiJkcHBDb24iLCJraWQiOiIwTlNSNTlxRTc0alFfZTFLVGVPV1lYY1pTWnFUaDdNXzU0aHJPcFRpaFJnIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOltdLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJiVmFMRGlBT09OQmFjcVFVN1pYamFBVEtEMVhhbDVlUExqOUZFZUl3VkN3IiwieSI6Il95c25JR1hTYjBvNEsyMWg0anZmSkZxMHdVNnlPNWp1VUFPd3FuM0dHVHMifX0.WgzZBOJaisWBRxvtXPbVYPXU7OIZxs6sZD-cPOLmJVTIYZKdMkSOMvP5b6si_j61FIrjhm43tmGq1P6cpoxB_g", |
4082 | "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiIwTlNSNTlxRTc0alFfZTFLVGVPV1lYY1pTWnFUaDdNXzU0aHJPcFRpaFJnIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7fV0sIm5ldEFjY2Vzc0tleSI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IkJhY3BWSDNpNDBrZklNS0RHa1FFRzhCODBCaEk4cEFmTWpLbzM5NlFZT2ciLCJ5IjoiMjBDYjhDNjRsSjFzQzV2NXlKMnBFZXRRempxMjI4YVV2cHMxNmQ0M3EwQSJ9fQ.dG2y8VvZQJ5hfob8E5F2FAeR7Nd700qstYkxDgA2QfARaNMZ0_SfKfoG-yKXsIZNM-TvGBfACgfhagG9Oaw_Xw", | |
4083 | "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiIwTlNSNTlxRTc0alFfZTFLVGVPV1lYY1pTWnFUaDdNXzU0aHJPcFRpaFJnIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiJkc2VmcmJWWlhad0RMWHRpLWlObDBBYkFIOXpqeFFKd0R1SUd5NzNuZGU0IiwieSI6IjZFQnExN3cwYW1fZlh1OUQ4UGxWYk9XZ2I3b19DcTUxWHlmSG8wcHJyeDQifX0.caBvdDUtXrhnS61-juVZ_2FQdprepv0yZjC04G4ERvLUpeX7cgu0Hp-A1aFDogP1PEFGpkaEdcAWRQnSSRiIKQ"] | |
5c6c42aa JM |
4084 | for t in tests: |
4085 | dev[0].set_network_quoted(id, "dpp_connector", t) | |
4086 | dev[0].select_network(id, freq=2412) | |
4087 | ev = dev[0].wait_event(["DPP-INTRO"], timeout=5) | |
4088 | if ev is None or "status=8" not in ev: | |
4089 | raise Exception("Introduction failure not reported") | |
4090 | dev[0].request("DISCONNECT") | |
4091 | dev[0].dump_monitor() | |
7e26f1bc JM |
4092 | |
4093 | def test_dpp_peer_intro_local_failures(dev, apdev): | |
4094 | """DPP peer introduction local failures""" | |
4095 | check_dpp_capab(dev[0]) | |
4096 | check_dpp_capab(dev[1]) | |
4097 | ||
fab49f61 JM |
4098 | params = {"ssid": "dpp", |
4099 | "wpa": "2", | |
4100 | "wpa_key_mgmt": "DPP", | |
4101 | "ieee80211w": "2", | |
4102 | "rsn_pairwise": "CCMP", | |
4103 | "dpp_connector": params1_ap_connector, | |
4104 | "dpp_csign": params1_csign, | |
4105 | "dpp_netaccesskey": params1_ap_netaccesskey} | |
7e26f1bc JM |
4106 | try: |
4107 | hapd = hostapd.add_ap(apdev[0], params) | |
4108 | except: | |
4109 | raise HwsimSkip("DPP not supported") | |
4110 | ||
fab49f61 JM |
4111 | tests = ["dpp_derive_pmk", |
4112 | "dpp_hkdf_expand;dpp_derive_pmk", | |
4113 | "dpp_derive_pmkid"] | |
7e26f1bc JM |
4114 | for func in tests: |
4115 | with fail_test(dev[0], 1, func): | |
4116 | dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", | |
4117 | ieee80211w="2", | |
4118 | dpp_csign=params1_csign, | |
4119 | dpp_connector=params1_sta_connector, | |
4120 | dpp_netaccesskey=params1_sta_netaccesskey, | |
4121 | wait_connect=False) | |
4122 | ev = dev[0].wait_event(["DPP-INTRO"], timeout=10) | |
4123 | if ev is None or "fail=peer_connector_validation_failed" not in ev: | |
4124 | raise Exception("Introduction failure not reported") | |
4125 | dev[0].request("REMOVE_NETWORK all") | |
4126 | dev[0].dump_monitor() | |
4127 | ||
fab49f61 JM |
4128 | tests = [(1, "base64_gen_decode;dpp_peer_intro"), |
4129 | (1, "json_parse;dpp_peer_intro"), | |
4130 | (50, "json_parse;dpp_peer_intro"), | |
4131 | (1, "=dpp_peer_intro"), | |
4132 | (1, "dpp_parse_jwk")] | |
4133 | for count, func in tests: | |
7e26f1bc JM |
4134 | with alloc_fail(dev[0], count, func): |
4135 | dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", | |
4136 | ieee80211w="2", | |
4137 | dpp_csign=params1_csign, | |
4138 | dpp_connector=params1_sta_connector, | |
4139 | dpp_netaccesskey=params1_sta_netaccesskey, | |
4140 | wait_connect=False) | |
4141 | ev = dev[0].wait_event(["DPP-INTRO"], timeout=10) | |
4142 | if ev is None or "fail=peer_connector_validation_failed" not in ev: | |
4143 | raise Exception("Introduction failure not reported") | |
4144 | dev[0].request("REMOVE_NETWORK all") | |
4145 | dev[0].dump_monitor() | |
4146 | ||
4147 | parts = params1_ap_connector.split('.') | |
fab49f61 | 4148 | for ap_connector in ['.'.join(parts[0:2]), '.'.join(parts[0:1])]: |
7e26f1bc JM |
4149 | hapd.set("dpp_connector", ap_connector) |
4150 | dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", | |
4151 | ieee80211w="2", | |
4152 | dpp_csign=params1_csign, | |
4153 | dpp_connector=params1_sta_connector, | |
4154 | dpp_netaccesskey=params1_sta_netaccesskey, | |
4155 | wait_connect=False) | |
4156 | ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=10) | |
4157 | if ev is None: | |
4158 | raise Exception("No TX status reported") | |
4159 | dev[0].request("REMOVE_NETWORK all") | |
4160 | dev[0].dump_monitor() | |
4161 | ||
4162 | hapd.set("dpp_netaccesskey", "00") | |
4163 | dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", | |
4164 | ieee80211w="2", | |
4165 | dpp_csign=params1_csign, | |
4166 | dpp_connector=params1_sta_connector, | |
4167 | dpp_netaccesskey=params1_sta_netaccesskey, | |
4168 | wait_connect=False) | |
4169 | ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=10) | |
4170 | if ev is None: | |
4171 | raise Exception("No TX status reported") | |
4172 | dev[0].request("REMOVE_NETWORK all") | |
4173 | dev[0].dump_monitor() | |
4174 | ||
4175 | hapd.set("dpp_csign", "00") | |
4176 | dev[0].connect("dpp", key_mgmt="DPP", scan_freq="2412", | |
4177 | ieee80211w="2", | |
4178 | dpp_csign=params1_csign, | |
4179 | dpp_connector=params1_sta_connector, | |
4180 | dpp_netaccesskey=params1_sta_netaccesskey, | |
4181 | wait_connect=False) | |
4182 | ev = dev[0].wait_event(["DPP-TX-STATUS"], timeout=10) | |
4183 | if ev is None: | |
4184 | raise Exception("No TX status reported") | |
4185 | dev[0].request("REMOVE_NETWORK all") | |
d0e88871 JM |
4186 | |
4187 | def run_dpp_configurator_id_unknown(dev): | |
4188 | check_dpp_capab(dev) | |
e105110f | 4189 | conf_id = dev.dpp_configurator_add() |
d0e88871 JM |
4190 | if "FAIL" not in dev.request("DPP_CONFIGURATOR_GET_KEY %d" % (conf_id + 1)): |
4191 | raise Exception("DPP_CONFIGURATOR_GET_KEY with incorrect id accepted") | |
4192 | ||
4193 | cmd = "DPP_CONFIGURATOR_SIGN conf=sta-dpp configurator=%d" % (conf_id + 1) | |
4194 | if "FAIL" not in dev.request(cmd): | |
4195 | raise Exception("DPP_CONFIGURATOR_SIGN with incorrect id accepted") | |
4196 | ||
4197 | def test_dpp_configurator_id_unknown(dev, apdev): | |
4198 | """DPP and unknown configurator id""" | |
4199 | run_dpp_configurator_id_unknown(dev[0]) | |
fab49f61 | 4200 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"}) |
d0e88871 | 4201 | run_dpp_configurator_id_unknown(hapd) |
88c08a29 | 4202 | |
5be5b816 | 4203 | def run_dpp_bootstrap_gen_failures(dev): |
88c08a29 JM |
4204 | check_dpp_capab(dev) |
4205 | ||
fab49f61 JM |
4206 | tests = ["type=unsupported", |
4207 | "type=qrcode chan=-1", | |
4208 | "type=qrcode mac=a", | |
4209 | "type=qrcode key=qq", | |
4210 | "type=qrcode key=", | |
4211 | "type=qrcode info=abc\tdef"] | |
88c08a29 JM |
4212 | for t in tests: |
4213 | if "FAIL" not in dev.request("DPP_BOOTSTRAP_GEN " + t): | |
4214 | raise Exception("Command accepted unexpectedly") | |
4215 | ||
a5387062 JM |
4216 | id = dev.dpp_bootstrap_gen() |
4217 | uri = dev.request("DPP_BOOTSTRAP_GET_URI %d" % id) | |
88c08a29 JM |
4218 | if not uri.startswith("DPP:"): |
4219 | raise Exception("Could not get URI") | |
4220 | if "FAIL" not in dev.request("DPP_BOOTSTRAP_GET_URI 0"): | |
4221 | raise Exception("Failure not reported") | |
a5387062 | 4222 | info = dev.request("DPP_BOOTSTRAP_INFO %d" % id) |
88c08a29 JM |
4223 | if not info.startswith("type=QRCODE"): |
4224 | raise Exception("Could not get info") | |
4225 | if "FAIL" not in dev.request("DPP_BOOTSTRAP_REMOVE 0"): | |
4226 | raise Exception("Failure not reported") | |
4227 | if "FAIL" in dev.request("DPP_BOOTSTRAP_REMOVE *"): | |
4228 | raise Exception("Failed to remove bootstrap info") | |
a5387062 | 4229 | if "FAIL" not in dev.request("DPP_BOOTSTRAP_GET_URI %d" % id): |
88c08a29 | 4230 | raise Exception("Failure not reported") |
a5387062 | 4231 | if "FAIL" not in dev.request("DPP_BOOTSTRAP_INFO %d" % id): |
88c08a29 JM |
4232 | raise Exception("Failure not reported") |
4233 | ||
5be5b816 | 4234 | func = "dpp_bootstrap_gen" |
88c08a29 JM |
4235 | with alloc_fail(dev, 1, "=" + func): |
4236 | if "FAIL" not in dev.request("DPP_BOOTSTRAP_GEN type=qrcode"): | |
4237 | raise Exception("Command accepted unexpectedly") | |
4238 | ||
2bbe6ad3 | 4239 | with alloc_fail(dev, 1, "dpp_gen_uri;dpp_bootstrap_gen"): |
88c08a29 JM |
4240 | if "FAIL" not in dev.request("DPP_BOOTSTRAP_GEN type=qrcode"): |
4241 | raise Exception("Command accepted unexpectedly") | |
4242 | ||
4243 | with alloc_fail(dev, 1, "get_param"): | |
4244 | dev.request("DPP_BOOTSTRAP_GEN type=qrcode curve=foo") | |
4245 | ||
4246 | def test_dpp_bootstrap_gen_failures(dev, apdev): | |
4247 | """DPP_BOOTSTRAP_GEN/REMOVE/GET_URI/INFO error cases""" | |
5be5b816 | 4248 | run_dpp_bootstrap_gen_failures(dev[0]) |
fab49f61 | 4249 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"}) |
5be5b816 | 4250 | run_dpp_bootstrap_gen_failures(hapd) |
fe7c91f8 JM |
4251 | |
4252 | def test_dpp_listen_continue(dev, apdev): | |
4253 | """DPP and continue listen state""" | |
4254 | check_dpp_capab(dev[0]) | |
4255 | check_dpp_capab(dev[1]) | |
a5387062 JM |
4256 | id = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
4257 | uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id) | |
7e009100 | 4258 | dev[0].dpp_listen(2412) |
fe7c91f8 | 4259 | time.sleep(5.1) |
5725b3e3 JM |
4260 | dev[1].dpp_auth_init(uri=uri) |
4261 | wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0], | |
4262 | allow_enrollee_failure=True, stop_responder=True, | |
4263 | stop_initiator=True) | |
d0cd2d1a JM |
4264 | |
4265 | def test_dpp_network_addition_failure(dev, apdev): | |
4266 | """DPP network addition failure""" | |
4267 | try: | |
4268 | run_dpp_network_addition_failure(dev, apdev) | |
4269 | finally: | |
5bf51d38 | 4270 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
d0cd2d1a JM |
4271 | |
4272 | def run_dpp_network_addition_failure(dev, apdev): | |
4273 | check_dpp_capab(dev[0]) | |
e105110f | 4274 | conf_id = dev[0].dpp_configurator_add() |
d0cd2d1a JM |
4275 | dev[0].set("dpp_config_processing", "1") |
4276 | cmd = "DPP_CONFIGURATOR_SIGN conf=sta-dpp configurator=%d" % conf_id | |
fab49f61 JM |
4277 | tests = [(1, "=wpas_dpp_add_network"), |
4278 | (2, "=wpas_dpp_add_network"), | |
4279 | (3, "=wpas_dpp_add_network"), | |
4280 | (4, "=wpas_dpp_add_network"), | |
4281 | (1, "wpa_config_add_network;wpas_dpp_add_network")] | |
4282 | for count, func in tests: | |
d0cd2d1a JM |
4283 | with alloc_fail(dev[0], count, func): |
4284 | res = dev[0].request(cmd) | |
8b6c834f JM |
4285 | if "OK" in res: |
4286 | ev = dev[0].wait_event(["DPP-NET-ACCESS-KEY"], timeout=2) | |
4287 | if ev is None: | |
4288 | raise Exception("Config object not processed") | |
d0cd2d1a JM |
4289 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") |
4290 | dev[0].dump_monitor() | |
4291 | ||
54c58f29 | 4292 | cmd = "DPP_CONFIGURATOR_SIGN conf=sta-psk pass=%s configurator=%d" % (binascii.hexlify(b"passphrase").decode(), conf_id) |
fab49f61 JM |
4293 | tests = [(1, "wpa_config_set_quoted;wpas_dpp_add_network")] |
4294 | for count, func in tests: | |
d0cd2d1a JM |
4295 | with alloc_fail(dev[0], count, func): |
4296 | res = dev[0].request(cmd) | |
8b6c834f JM |
4297 | if "OK" in res: |
4298 | ev = dev[0].wait_event(["DPP-NET-ACCESS-KEY"], timeout=2) | |
4299 | if ev is None: | |
4300 | raise Exception("Config object not processed") | |
d0cd2d1a JM |
4301 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") |
4302 | dev[0].dump_monitor() | |
051c8cae JM |
4303 | |
4304 | def test_dpp_two_initiators(dev, apdev): | |
4305 | """DPP and two initiators""" | |
4306 | check_dpp_capab(dev[0]) | |
4307 | check_dpp_capab(dev[1]) | |
4308 | check_dpp_capab(dev[2]) | |
a5387062 JM |
4309 | id = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
4310 | uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id) | |
7e009100 | 4311 | dev[0].dpp_listen(2412) |
5725b3e3 | 4312 | dev[1].dpp_auth_init(uri=uri) |
051c8cae JM |
4313 | ev = dev[0].wait_event(["DPP-RX"], timeout=5) |
4314 | if ev is None: | |
4315 | raise Exeption("No DPP Authentication Request seen") | |
5725b3e3 | 4316 | dev[2].dpp_auth_init(uri=uri) |
203878d7 JM |
4317 | wait_dpp_fail(dev[0], |
4318 | "DPP-FAIL Already in DPP authentication exchange - ignore new one") | |
051c8cae JM |
4319 | |
4320 | ev = dev[0].wait_event(["DPP-CONF-FAILED"], timeout=2) | |
4321 | if ev is None: | |
4322 | raise Exception("DPP configuration result not seen (Enrollee)") | |
4323 | ev = dev[1].wait_event(["DPP-CONF-SENT"], timeout=2) | |
4324 | if ev is None: | |
4325 | raise Exception("DPP configuration result not seen (Responder)") | |
4326 | ||
4327 | dev[0].request("DPP_STOP_LISTEN") | |
4328 | dev[1].request("DPP_STOP_LISTEN") | |
4329 | dev[2].request("DPP_STOP_LISTEN") | |
7010f4be JM |
4330 | |
4331 | def test_dpp_conf_file_update(dev, apdev, params): | |
4332 | """DPP provisioning updating wpa_supplicant configuration file""" | |
4333 | config = os.path.join(params['logdir'], 'dpp_conf_file_update.conf') | |
4334 | with open(config, "w") as f: | |
4335 | f.write("update_config=1\n") | |
4336 | wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') | |
4337 | wpas.interface_add("wlan5", config=config) | |
5bf51d38 | 4338 | check_dpp_capab(wpas) |
7010f4be | 4339 | wpas.set("dpp_config_processing", "1") |
fab49f61 | 4340 | run_dpp_qr_code_auth_unicast([wpas, dev[1]], apdev, None, |
7010f4be JM |
4341 | init_extra="conf=sta-dpp", |
4342 | require_conf_success=True, | |
4343 | configurator=True) | |
4344 | wpas.interface_remove("wlan5") | |
4345 | ||
4346 | with open(config, "r") as f: | |
4347 | res = f.read() | |
fab49f61 JM |
4348 | for i in ["network={", "dpp_connector=", "key_mgmt=DPP", "ieee80211w=2", |
4349 | "dpp_netaccesskey=", "dpp_csign="]: | |
7010f4be JM |
4350 | if i not in res: |
4351 | raise Exception("Configuration file missing '%s'" % i) | |
4352 | ||
4353 | wpas.interface_add("wlan5", config=config) | |
4354 | if len(wpas.list_networks()) != 1: | |
4355 | raise Exception("Unexpected number of networks") | |
ba6ce9c6 JM |
4356 | |
4357 | def test_dpp_duplicated_auth_resp(dev, apdev): | |
4358 | """DPP and duplicated Authentication Response""" | |
4359 | check_dpp_capab(dev[0]) | |
4360 | check_dpp_capab(dev[1]) | |
ba6ce9c6 JM |
4361 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
4362 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) | |
ba6ce9c6 JM |
4363 | dev[0].set("ext_mgmt_frame_handling", "1") |
4364 | dev[1].set("ext_mgmt_frame_handling", "1") | |
7e009100 | 4365 | dev[0].dpp_listen(2412) |
5725b3e3 | 4366 | dev[1].dpp_auth_init(uri=uri0) |
ba6ce9c6 JM |
4367 | |
4368 | # DPP Authentication Request | |
4369 | rx_process_frame(dev[0]) | |
4370 | ||
4371 | # DPP Authentication Response | |
4372 | msg = rx_process_frame(dev[1]) | |
4373 | frame = binascii.hexlify(msg['frame']).decode() | |
4374 | # Duplicated frame | |
4375 | if "OK" not in dev[1].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame)): | |
4376 | raise Exception("MGMT_RX_PROCESS failed") | |
4377 | # Modified frame - nonzero status | |
4378 | if frame[2*32:2*37] != "0010010000": | |
4379 | raise Exception("Could not find Status attribute") | |
4380 | frame2 = frame[0:2*32] + "0010010001" + frame[2*37:] | |
4381 | if "OK" not in dev[1].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame2)): | |
4382 | raise Exception("MGMT_RX_PROCESS failed") | |
4383 | frame2 = frame[0:2*32] + "00100100ff" + frame[2*37:] | |
4384 | if "OK" not in dev[1].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], frame2)): | |
4385 | raise Exception("MGMT_RX_PROCESS failed") | |
4386 | ||
4387 | # DPP Authentication Confirmation | |
4388 | rx_process_frame(dev[0]) | |
4389 | ||
4390 | wait_auth_success(dev[0], dev[1]) | |
4391 | ||
4392 | # DPP Configuration Request | |
4393 | rx_process_frame(dev[1]) | |
4394 | ||
4395 | # DPP Configuration Response | |
4396 | rx_process_frame(dev[0]) | |
4397 | ||
4398 | wait_conf_completion(dev[1], dev[0]) | |
8ad1009e | 4399 | |
71281978 JM |
4400 | def test_dpp_duplicated_auth_conf(dev, apdev): |
4401 | """DPP and duplicated Authentication Confirmation""" | |
4402 | check_dpp_capab(dev[0]) | |
4403 | check_dpp_capab(dev[1]) | |
4404 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) | |
4405 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) | |
4406 | dev[0].set("ext_mgmt_frame_handling", "1") | |
4407 | dev[1].set("ext_mgmt_frame_handling", "1") | |
4408 | dev[0].dpp_listen(2412) | |
4409 | dev[1].dpp_auth_init(uri=uri0) | |
4410 | ||
4411 | # DPP Authentication Request | |
4412 | rx_process_frame(dev[0]) | |
4413 | ||
4414 | # DPP Authentication Response | |
4415 | rx_process_frame(dev[1]) | |
4416 | ||
4417 | # DPP Authentication Confirmation | |
4418 | msg = rx_process_frame(dev[0]) | |
4419 | # Duplicated frame | |
4420 | if "OK" not in dev[0].request("MGMT_RX_PROCESS freq={} datarate={} ssi_signal={} frame={}".format(msg['freq'], msg['datarate'], msg['ssi_signal'], binascii.hexlify(msg['frame']).decode())): | |
4421 | raise Exception("MGMT_RX_PROCESS failed") | |
4422 | ||
4423 | wait_auth_success(dev[0], dev[1]) | |
4424 | ||
4425 | # DPP Configuration Request | |
4426 | rx_process_frame(dev[1]) | |
4427 | ||
4428 | # DPP Configuration Response | |
4429 | rx_process_frame(dev[0]) | |
4430 | ||
4431 | wait_conf_completion(dev[1], dev[0]) | |
4432 | ||
8ad1009e JM |
4433 | def test_dpp_enrollee_reject_config(dev, apdev): |
4434 | """DPP and Enrollee rejecting Config Object""" | |
4435 | check_dpp_capab(dev[0]) | |
4436 | check_dpp_capab(dev[1]) | |
4437 | dev[0].set("dpp_test", "91") | |
8ad1009e JM |
4438 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) |
4439 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) | |
7e009100 | 4440 | dev[0].dpp_listen(2412) |
5725b3e3 JM |
4441 | dev[1].dpp_auth_init(uri=uri0, conf="sta-sae", ssid="dpp-legacy", |
4442 | passphrase="secret passphrase") | |
4443 | wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0], | |
4444 | allow_enrollee_failure=True, | |
4445 | allow_configurator_failure=True) | |
8ad1009e JM |
4446 | |
4447 | def test_dpp_enrollee_ap_reject_config(dev, apdev): | |
4448 | """DPP and Enrollee AP rejecting Config Object""" | |
4449 | check_dpp_capab(dev[0]) | |
4450 | check_dpp_capab(dev[1]) | |
fab49f61 | 4451 | hapd = hostapd.add_ap(apdev[0], {"ssid": "unconfigured"}) |
8ad1009e JM |
4452 | check_dpp_capab(hapd) |
4453 | hapd.set("dpp_test", "91") | |
e105110f | 4454 | conf_id = dev[0].dpp_configurator_add() |
8ad1009e JM |
4455 | id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True) |
4456 | uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h) | |
5725b3e3 JM |
4457 | dev[0].dpp_auth_init(uri=uri, conf="ap-dpp", configurator=conf_id) |
4458 | wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd, | |
4459 | allow_enrollee_failure=True, | |
4460 | allow_configurator_failure=True) | |
009b54be JM |
4461 | |
4462 | def test_dpp_legacy_and_dpp_akm(dev, apdev): | |
4463 | """DPP and provisoning DPP and legacy AKMs""" | |
4464 | try: | |
4465 | run_dpp_legacy_and_dpp_akm(dev, apdev) | |
4466 | finally: | |
5bf51d38 | 4467 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
009b54be JM |
4468 | |
4469 | def run_dpp_legacy_and_dpp_akm(dev, apdev): | |
4470 | check_dpp_capab(dev[0], min_ver=2) | |
4471 | check_dpp_capab(dev[1], min_ver=2) | |
4472 | ||
4473 | csign = "30770201010420768240a3fc89d6662d9782f120527fe7fb9edc6366ab0b9c7dde96125cfd250fa00a06082a8648ce3d030107a144034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708" | |
4474 | csign_pub = "3059301306072a8648ce3d020106082a8648ce3d030107034200042908e1baf7bf413cc66f9e878a03e8bb1835ba94b033dbe3d6969fc8575d5eb5dfda1cb81c95cee21d0cd7d92ba30541ffa05cb6296f5dd808b0c1c2a83c0708" | |
4475 | ap_connector = "eyJ0eXAiOiJkcHBDb24iLCJraWQiOiJwYWtZbXVzd1dCdWpSYTl5OEsweDViaTVrT3VNT3dzZHRlaml2UG55ZHZzIiwiYWxnIjoiRVMyNTYifQ.eyJncm91cHMiOlt7Imdyb3VwSWQiOiIqIiwibmV0Um9sZSI6ImFwIn1dLCJuZXRBY2Nlc3NLZXkiOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiIybU5vNXZuRkI5bEw3d1VWb1hJbGVPYzBNSEE1QXZKbnpwZXZULVVTYzVNIiwieSI6IlhzS3dqVHJlLTg5WWdpU3pKaG9CN1haeUttTU05OTl3V2ZaSVl0bi01Q3MifX0.XhjFpZgcSa7G2lHy0OCYTvaZFRo5Hyx6b7g7oYyusLC7C_73AJ4_BxEZQVYJXAtDuGvb3dXSkHEKxREP9Q6Qeg" | |
4476 | ap_netaccesskey = "30770201010420ceba752db2ad5200fa7bc565b9c05c69b7eb006751b0b329b0279de1c19ca67ca00a06082a8648ce3d030107a14403420004da6368e6f9c507d94bef0515a1722578e73430703902f267ce97af4fe51273935ec2b08d3adefbcf588224b3261a01ed76722a630cf7df7059f64862d9fee42b" | |
4477 | ||
4478 | ssid = "dpp-both" | |
4479 | passphrase = "secret passphrase" | |
4480 | params = {"ssid": ssid, | |
4481 | "wpa": "2", | |
4482 | "wpa_key_mgmt": "DPP WPA-PSK SAE", | |
4483 | "ieee80211w": "1", | |
4484 | "sae_require_mfp": '1', | |
4485 | "rsn_pairwise": "CCMP", | |
4486 | "wpa_passphrase": passphrase, | |
4487 | "dpp_connector": ap_connector, | |
4488 | "dpp_csign": csign_pub, | |
4489 | "dpp_netaccesskey": ap_netaccesskey} | |
4490 | try: | |
4491 | hapd = hostapd.add_ap(apdev[0], params) | |
4492 | except: | |
4493 | raise HwsimSkip("DPP not supported") | |
4494 | ||
c9ead82d | 4495 | dev[0].request("SET sae_groups ") |
e105110f | 4496 | conf_id = dev[1].dpp_configurator_add(key=csign) |
009b54be JM |
4497 | dev[0].set("dpp_config_processing", "1") |
4498 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) | |
4499 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) | |
7e009100 | 4500 | dev[0].dpp_listen(2412) |
5725b3e3 JM |
4501 | dev[1].dpp_auth_init(uri=uri0, conf="sta-psk-sae-dpp", ssid=ssid, |
4502 | passphrase=passphrase, configurator=conf_id) | |
4503 | wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0], | |
4504 | allow_enrollee_failure=True, | |
4505 | allow_configurator_failure=True) | |
009b54be JM |
4506 | ev = dev[0].wait_event(["DPP-NETWORK-ID"], timeout=1) |
4507 | if ev is None: | |
4508 | raise Exception("DPP network profile not generated") | |
4509 | id0 = ev.split(' ')[1] | |
4510 | ||
4511 | key_mgmt = dev[0].get_network(id0, "key_mgmt").split(' ') | |
4512 | for m in ["SAE", "WPA-PSK", "DPP"]: | |
4513 | if m not in key_mgmt: | |
4514 | raise Exception("%s missing from key_mgmt" % m) | |
4515 | ||
4516 | dev[0].scan_for_bss(hapd.own_addr(), freq=2412) | |
4517 | dev[0].select_network(id0, freq=2412) | |
4518 | dev[0].wait_connected() | |
4519 | ||
4520 | dev[0].request("DISCONNECT") | |
4521 | dev[0].wait_disconnected() | |
4522 | hapd.disable() | |
4523 | ||
4524 | params = {"ssid": ssid, | |
4525 | "wpa": "2", | |
4526 | "wpa_key_mgmt": "WPA-PSK SAE", | |
4527 | "ieee80211w": "1", | |
4528 | "sae_require_mfp": '1', | |
4529 | "rsn_pairwise": "CCMP", | |
4530 | "wpa_passphrase": passphrase} | |
4531 | hapd2 = hostapd.add_ap(apdev[1], params) | |
4532 | ||
4533 | dev[0].request("BSS_FLUSH 0") | |
4534 | dev[0].scan_for_bss(hapd2.own_addr(), freq=2412, force_scan=True, | |
4535 | only_new=True) | |
4536 | dev[0].select_network(id0, freq=2412) | |
4537 | dev[0].wait_connected() | |
4538 | ||
4539 | dev[0].request("DISCONNECT") | |
4540 | dev[0].wait_disconnected() | |
5fbefcc6 JM |
4541 | |
4542 | def test_dpp_controller_relay(dev, apdev, params): | |
4543 | """DPP Controller/Relay""" | |
4544 | try: | |
4545 | run_dpp_controller_relay(dev, apdev, params) | |
4546 | finally: | |
5bf51d38 | 4547 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
5fbefcc6 JM |
4548 | dev[1].request("DPP_CONTROLLER_STOP") |
4549 | ||
4550 | def run_dpp_controller_relay(dev, apdev, params): | |
4551 | check_dpp_capab(dev[0]) | |
4552 | check_dpp_capab(dev[1]) | |
4553 | prefix = "dpp_controller_relay" | |
4554 | cap_lo = os.path.join(params['logdir'], prefix + ".lo.pcap") | |
4555 | ||
4e9bcdeb | 4556 | wt = WlantestCapture('lo', cap_lo) |
5fbefcc6 JM |
4557 | |
4558 | # Controller | |
4559 | conf_id = dev[1].dpp_configurator_add() | |
4560 | dev[1].set("dpp_configurator_params", | |
4561 | " conf=sta-dpp configurator=%d" % conf_id) | |
4562 | id_c = dev[1].dpp_bootstrap_gen() | |
4563 | uri_c = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_c) | |
4564 | res = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id_c) | |
4565 | pkhash = None | |
4566 | for line in res.splitlines(): | |
4567 | name, value = line.split('=') | |
4568 | if name == "pkhash": | |
4569 | pkhash = value | |
4570 | break | |
4571 | if not pkhash: | |
4572 | raise Exception("Could not fetch public key hash from Controller") | |
4573 | if "OK" not in dev[1].request("DPP_CONTROLLER_START"): | |
4574 | raise Exception("Failed to start Controller") | |
4575 | ||
4576 | # Relay | |
4577 | params = {"ssid": "unconfigured", | |
4578 | "channel": "6", | |
4579 | "dpp_controller": "ipaddr=127.0.0.1 pkhash=" + pkhash} | |
4580 | relay = hostapd.add_ap(apdev[1], params) | |
4581 | check_dpp_capab(relay) | |
4582 | ||
4583 | # Enroll Relay to the network | |
4584 | # TODO: Do this over TCP once direct Enrollee-over-TCP case is supported | |
4585 | id_h = relay.dpp_bootstrap_gen(chan="81/6", mac=True) | |
4586 | uri_r = relay.request("DPP_BOOTSTRAP_GET_URI %d" % id_h) | |
4587 | dev[1].dpp_auth_init(uri=uri_r, conf="ap-dpp", configurator=conf_id) | |
4588 | wait_auth_success(relay, dev[1], configurator=dev[1], enrollee=relay) | |
4589 | update_hapd_config(relay) | |
4590 | ||
4591 | # Initiate from Enrollee with broadcast DPP Authentication Request | |
4592 | dev[0].set("dpp_config_processing", "2") | |
4593 | dev[0].dpp_auth_init(uri=uri_c, role="enrollee") | |
4594 | wait_auth_success(dev[1], dev[0], configurator=dev[1], enrollee=dev[0], | |
4595 | allow_enrollee_failure=True, | |
4596 | allow_configurator_failure=True) | |
4597 | dev[0].wait_connected() | |
4598 | ||
4599 | time.sleep(0.5) | |
4e9bcdeb | 4600 | wt.close() |
5fbefcc6 JM |
4601 | |
4602 | def test_dpp_tcp(dev, apdev, params): | |
4603 | """DPP over TCP""" | |
4604 | prefix = "dpp_tcp" | |
4605 | cap_lo = os.path.join(params['logdir'], prefix + ".lo.pcap") | |
4606 | try: | |
4607 | run_dpp_tcp(dev, apdev, cap_lo) | |
4608 | finally: | |
4609 | dev[1].request("DPP_CONTROLLER_STOP") | |
4610 | ||
4611 | def test_dpp_tcp_port(dev, apdev, params): | |
4612 | """DPP over TCP and specified port""" | |
4613 | prefix = "dpp_tcp_port" | |
4614 | cap_lo = os.path.join(params['logdir'], prefix + ".lo.pcap") | |
4615 | try: | |
4616 | run_dpp_tcp(dev, apdev, cap_lo, port="23456") | |
4617 | finally: | |
4618 | dev[1].request("DPP_CONTROLLER_STOP") | |
4619 | ||
4620 | def run_dpp_tcp(dev, apdev, cap_lo, port=None): | |
4621 | check_dpp_capab(dev[0]) | |
4622 | check_dpp_capab(dev[1]) | |
4623 | ||
4e9bcdeb | 4624 | wt = WlantestCapture('lo', cap_lo) |
5fbefcc6 JM |
4625 | time.sleep(1) |
4626 | ||
4627 | # Controller | |
4628 | conf_id = dev[1].dpp_configurator_add() | |
4629 | dev[1].set("dpp_configurator_params", | |
4630 | " conf=sta-dpp configurator=%d" % conf_id) | |
4631 | id_c = dev[1].dpp_bootstrap_gen() | |
4632 | uri_c = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_c) | |
4633 | res = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id_c) | |
4634 | pkhash = None | |
4635 | for line in res.splitlines(): | |
4636 | name, value = line.split('=') | |
4637 | if name == "pkhash": | |
4638 | pkhash = value | |
4639 | break | |
4640 | if not pkhash: | |
4641 | raise Exception("Could not fetch public key hash from Controller") | |
4642 | req = "DPP_CONTROLLER_START" | |
4643 | if port: | |
4644 | req += " tcp_port=" + port | |
4645 | if "OK" not in dev[1].request(req): | |
4646 | raise Exception("Failed to start Controller") | |
4647 | ||
4648 | # Initiate from Enrollee with broadcast DPP Authentication Request | |
4649 | dev[0].dpp_auth_init(uri=uri_c, role="enrollee", tcp_addr="127.0.0.1", | |
4650 | tcp_port=port) | |
4651 | wait_auth_success(dev[1], dev[0], configurator=dev[1], enrollee=dev[0], | |
4652 | allow_enrollee_failure=True, | |
4653 | allow_configurator_failure=True) | |
4654 | time.sleep(0.5) | |
4e9bcdeb | 4655 | wt.close() |
16149090 JM |
4656 | |
4657 | def test_dpp_tcp_controller_start_failure(dev, apdev, params): | |
4658 | """DPP Controller startup failure""" | |
4659 | check_dpp_capab(dev[0]) | |
4660 | ||
4661 | try: | |
4662 | if "OK" not in dev[0].request("DPP_CONTROLLER_START"): | |
4663 | raise Exception("Could not start Controller") | |
4664 | if "OK" in dev[0].request("DPP_CONTROLLER_START"): | |
4665 | raise Exception("Second Controller start not rejected") | |
4666 | finally: | |
4667 | dev[0].request("DPP_CONTROLLER_STOP") | |
4668 | ||
4669 | tests = ["dpp_controller_start", | |
4670 | "eloop_sock_table_add_sock;?eloop_register_sock;dpp_controller_start"] | |
4671 | for func in tests: | |
4672 | with alloc_fail(dev[0], 1, func): | |
4673 | if "FAIL" not in dev[0].request("DPP_CONTROLLER_START"): | |
4674 | raise Exception("Failure not reported during OOM") | |
4675 | ||
4676 | def test_dpp_tcp_init_failure(dev, apdev, params): | |
4677 | """DPP TCP init failure""" | |
4678 | check_dpp_capab(dev[0]) | |
4679 | check_dpp_capab(dev[1]) | |
4680 | id_c = dev[1].dpp_bootstrap_gen() | |
4681 | uri_c = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id_c) | |
4682 | peer = dev[0].dpp_qr_code(uri_c) | |
4683 | tests = ["dpp_tcp_init", | |
4684 | "eloop_sock_table_add_sock;?eloop_register_sock;dpp_tcp_init", | |
4685 | "dpp_tcp_encaps"] | |
4686 | cmd = "DPP_AUTH_INIT peer=%d tcp_addr=127.0.0.1" % peer | |
4687 | for func in tests: | |
4688 | with alloc_fail(dev[0], 1, func): | |
4689 | if "FAIL" not in dev[0].request(cmd): | |
4690 | raise Exception("DPP_AUTH_INIT accepted during OOM") | |
4691 | ||
4692 | def test_dpp_controller_rx_failure(dev, apdev, params): | |
4693 | """DPP Controller RX failure""" | |
4694 | check_dpp_capab(dev[0]) | |
4695 | check_dpp_capab(dev[1]) | |
4696 | try: | |
4697 | run_dpp_controller_rx_failure(dev, apdev) | |
4698 | finally: | |
4699 | dev[0].request("DPP_CONTROLLER_STOP") | |
4700 | ||
4701 | def run_dpp_controller_rx_failure(dev, apdev): | |
4702 | if "OK" not in dev[0].request("DPP_CONTROLLER_START"): | |
4703 | raise Exception("Could not start Controller") | |
4704 | id_c = dev[0].dpp_bootstrap_gen() | |
4705 | uri_c = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id_c) | |
4706 | peer = dev[1].dpp_qr_code(uri_c) | |
4707 | tests = ["dpp_controller_tcp_cb", | |
4708 | "eloop_sock_table_add_sock;?eloop_register_sock;dpp_controller_tcp_cb", | |
4709 | "dpp_controller_rx", | |
4710 | "dpp_controller_rx_auth_req", | |
4711 | "wpabuf_alloc;=dpp_controller_rx_auth_req"] | |
4712 | cmd = "DPP_AUTH_INIT peer=%d tcp_addr=127.0.0.1" % peer | |
4713 | for func in tests: | |
4714 | with alloc_fail(dev[0], 1, func): | |
4715 | if "OK" not in dev[1].request(cmd): | |
4716 | raise Exception("Failed to initiate TCP connection") | |
4717 | wait_fail_trigger(dev[0], "GET_ALLOC_FAIL") | |
b4928ff9 JM |
4718 | |
4719 | def test_dpp_controller_rx_errors(dev, apdev, params): | |
4720 | """DPP Controller RX error cases""" | |
4721 | check_dpp_capab(dev[0]) | |
4722 | check_dpp_capab(dev[1]) | |
4723 | try: | |
4724 | run_dpp_controller_rx_errors(dev, apdev) | |
4725 | finally: | |
4726 | dev[0].request("DPP_CONTROLLER_STOP") | |
4727 | ||
4728 | def run_dpp_controller_rx_errors(dev, apdev): | |
4729 | if "OK" not in dev[0].request("DPP_CONTROLLER_START"): | |
4730 | raise Exception("Could not start Controller") | |
4731 | ||
4732 | addr = ("127.0.0.1", 7871) | |
4733 | ||
4734 | tests = [b"abc", | |
4735 | b"abcd", | |
4736 | b"\x00\x00\x00\x00", | |
4737 | b"\x00\x00\x00\x01", | |
4738 | b"\x00\x00\x00\x01\x09", | |
4739 | b"\x00\x00\x00\x07\x09\x50\x6f\x9a\x1a\xff\xff", | |
4740 | b"\x00\x00\x00\x07\x09\x50\x6f\x9a\x1a\x01\xff", | |
4741 | b"\x00\x00\x00\x07\x09\x50\x6f\x9a\x1a\x01\x00", | |
4742 | b"\x00\x00\x00\x08\x09\x50\x6f\x9a\x1a\x01\x00\xff", | |
4743 | b"\x00\x00\x00\x01\x0a", | |
4744 | b"\x00\x00\x00\x04\x0a\xff\xff\xff", | |
4745 | b"\x00\x00\x00\x01\x0b", | |
4746 | b"\x00\x00\x00\x08\x0b\xff\xff\xff\xff\xff\xff\xff", | |
4747 | b"\x00\x00\x00\x08\x0b\xff\x00\x00\xff\xff\xff\xff", | |
4748 | b"\x00\x00\x00\x08\x0b\xff\x00\x00\xff\xff\x6c\x00", | |
4749 | b"\x00\x00\x00\x0a\x0b\xff\x00\x00\xff\xff\x6c\x02\xff\xff", | |
4750 | b"\x00\x00\x00\x10\x0b\xff\x00\x00\xff\xff\x6c\x08\xff\xdd\x05\x50\x6f\x9a\x1a\x01", | |
4751 | b"\x00\x00\x00\x12\x0b\xff\x00\x00\xff\xff\x6c\x08\xff\xdd\x05\x50\x6f\x9a\x1a\x01\x00\x00", | |
4752 | b"\x00\x00\x00\x01\xff", | |
4753 | b"\x00\x00\x00\x01\xff\xee"] | |
4754 | #define WLAN_PA_GAS_INITIAL_REQ 10 | |
4755 | #define WLAN_PA_GAS_INITIAL_RESP 11 | |
4756 | ||
4757 | for t in tests: | |
4758 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, | |
4759 | socket.IPPROTO_TCP) | |
4760 | sock.settimeout(0.1) | |
4761 | sock.connect(addr) | |
4762 | sock.send(t) | |
4763 | sock.shutdown(1) | |
4764 | try: | |
4765 | sock.recv(10) | |
4766 | except socket.timeout: | |
4767 | pass | |
4768 | sock.close() | |
b256d939 JM |
4769 | |
4770 | def test_dpp_conn_status_success(dev, apdev): | |
4771 | """DPP connection status - success""" | |
4772 | try: | |
4773 | run_dpp_conn_status(dev, apdev) | |
4774 | finally: | |
5bf51d38 | 4775 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
b256d939 JM |
4776 | |
4777 | def test_dpp_conn_status_wrong_passphrase(dev, apdev): | |
4778 | """DPP connection status - wrong passphrase""" | |
4779 | try: | |
4780 | run_dpp_conn_status(dev, apdev, result=2) | |
4781 | finally: | |
5bf51d38 | 4782 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
b256d939 JM |
4783 | |
4784 | def test_dpp_conn_status_no_ap(dev, apdev): | |
4785 | """DPP connection status - no AP""" | |
4786 | try: | |
4787 | run_dpp_conn_status(dev, apdev, result=10) | |
4788 | finally: | |
5bf51d38 | 4789 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
b256d939 JM |
4790 | |
4791 | def test_dpp_conn_status_connector_mismatch(dev, apdev): | |
4792 | """DPP connection status - invalid Connector""" | |
4793 | try: | |
4794 | run_dpp_conn_status(dev, apdev, result=8) | |
4795 | finally: | |
5bf51d38 | 4796 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
b256d939 | 4797 | |
972edba1 JM |
4798 | def test_dpp_conn_status_assoc_reject(dev, apdev): |
4799 | """DPP connection status - association rejection""" | |
4800 | try: | |
4801 | dev[0].request("TEST_ASSOC_IE 30020000") | |
4802 | run_dpp_conn_status(dev, apdev, assoc_reject=True) | |
4803 | finally: | |
5bf51d38 | 4804 | dev[0].set("dpp_config_processing", "0", allow_fail=True) |
972edba1 JM |
4805 | |
4806 | def run_dpp_conn_status(dev, apdev, result=0, assoc_reject=False): | |
b256d939 JM |
4807 | check_dpp_capab(dev[0], min_ver=2) |
4808 | check_dpp_capab(dev[1], min_ver=2) | |
4809 | ||
4810 | if result != 10: | |
4811 | if result == 7 or result == 8: | |
4812 | params = {"ssid": "dpp-status", | |
4813 | "wpa": "2", | |
4814 | "wpa_key_mgmt": "DPP", | |
4815 | "ieee80211w": "2", | |
4816 | "rsn_pairwise": "CCMP", | |
4817 | "dpp_connector": params1_ap_connector, | |
4818 | "dpp_csign": params1_csign, | |
4819 | "dpp_netaccesskey": params1_ap_netaccesskey} | |
4820 | else: | |
4821 | if result == 2: | |
4822 | passphrase = "wrong passphrase" | |
4823 | else: | |
4824 | passphrase = "secret passphrase" | |
4825 | params = hostapd.wpa2_params(ssid="dpp-status", | |
4826 | passphrase=passphrase) | |
4827 | try: | |
4828 | hapd = hostapd.add_ap(apdev[0], params) | |
4829 | except: | |
4830 | raise HwsimSkip("DPP not supported") | |
4831 | ||
4832 | dev[0].request("SET sae_groups ") | |
4833 | dev[0].set("dpp_config_processing", "2") | |
4834 | id0 = dev[0].dpp_bootstrap_gen(chan="81/1", mac=True) | |
4835 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) | |
4836 | ||
4837 | dev[0].dpp_listen(2412) | |
4838 | if result == 7 or result == 8: | |
4839 | conf = 'sta-dpp' | |
4840 | passphrase = None | |
4841 | configurator = dev[1].dpp_configurator_add() | |
4842 | else: | |
4843 | conf = 'sta-psk' | |
4844 | passphrase = "secret passphrase" | |
4845 | configurator = None | |
4846 | dev[1].dpp_auth_init(uri=uri0, conf=conf, ssid="dpp-status", | |
4847 | passphrase=passphrase, configurator=configurator, | |
4848 | conn_status=True) | |
4849 | res = wait_auth_success(dev[0], dev[1], configurator=dev[1], | |
4850 | enrollee=dev[0]) | |
4851 | if 'wait_conn_status' not in res: | |
4852 | raise Exception("Configurator did not request connection status") | |
4853 | ||
972edba1 JM |
4854 | if assoc_reject and result == 0: |
4855 | result = 2 | |
b256d939 JM |
4856 | ev = dev[1].wait_event(["DPP-CONN-STATUS-RESULT"], timeout=20) |
4857 | if ev is None: | |
4858 | raise Exception("No connection status reported") | |
4859 | if "timeout" in ev: | |
4860 | raise Exception("Connection status result timeout") | |
4861 | if "result=%d" % result not in ev: | |
4862 | raise Exception("Unexpected connection status result: " + ev) | |
4863 | if "ssid=dpp-status" not in ev: | |
4864 | raise Exception("SSID not reported") | |
4865 | ||
4866 | if result == 0: | |
4867 | dev[0].wait_connected() | |
4868 | if result == 10 and "channel_list=" not in ev: | |
4869 | raise Exception("Channel list not reported for no-AP") | |
11bbb7ec JM |
4870 | |
4871 | def test_dpp_mud_url(dev, apdev): | |
4872 | """DPP MUD URL""" | |
4873 | check_dpp_capab(dev[0]) | |
4874 | try: | |
4875 | dev[0].set("dpp_name", "Test Enrollee") | |
4876 | dev[0].set("dpp_mud_url", "https://example.com/mud") | |
4877 | run_dpp_qr_code_auth_unicast(dev, apdev, None) | |
4878 | finally: | |
4879 | dev[0].set("dpp_mud_url", "") | |
4880 | dev[0].set("dpp_name", "Test") | |
4881 | ||
4882 | def test_dpp_mud_url_hostapd(dev, apdev): | |
4883 | """DPP MUD URL from hostapd""" | |
4884 | check_dpp_capab(dev[0]) | |
4885 | check_dpp_capab(dev[1]) | |
4886 | params = {"ssid": "unconfigured", | |
4887 | "dpp_name": "AP Enrollee", | |
4888 | "dpp_mud_url": "https://example.com/mud"} | |
4889 | hapd = hostapd.add_ap(apdev[0], params) | |
4890 | check_dpp_capab(hapd) | |
4891 | ||
4892 | id_h = hapd.dpp_bootstrap_gen(chan="81/1", mac=True) | |
4893 | uri = hapd.request("DPP_BOOTSTRAP_GET_URI %d" % id_h) | |
4894 | ||
4895 | conf_id = dev[0].dpp_configurator_add() | |
4896 | dev[0].dpp_auth_init(uri=uri, conf="ap-dpp", configurator=conf_id) | |
4897 | wait_auth_success(hapd, dev[0], configurator=dev[0], enrollee=hapd) | |
4898 | update_hapd_config(hapd) | |
4cab417a JM |
4899 | |
4900 | def test_dpp_config_save(dev, apdev, params): | |
4901 | """DPP configuration saving""" | |
4902 | config = os.path.join(params['logdir'], 'dpp_config_save.conf') | |
4903 | run_dpp_config_save(dev, apdev, config, "test", '"test"') | |
4904 | ||
4905 | def test_dpp_config_save2(dev, apdev, params): | |
4906 | """DPP configuration saving (2)""" | |
4907 | config = os.path.join(params['logdir'], 'dpp_config_save2.conf') | |
4908 | run_dpp_config_save(dev, apdev, config, "\\u0001*", '012a') | |
4909 | ||
4910 | def test_dpp_config_save3(dev, apdev, params): | |
4911 | """DPP configuration saving (3)""" | |
4912 | config = os.path.join(params['logdir'], 'dpp_config_save3.conf') | |
4913 | run_dpp_config_save(dev, apdev, config, "\\u0001*\\u00c2\\u00bc\\u00c3\\u009e\\u00c3\\u00bf", '012ac2bcc39ec3bf') | |
4914 | ||
4915 | def run_dpp_config_save(dev, apdev, config, conf_ssid, exp_ssid): | |
5bf51d38 | 4916 | check_dpp_capab(dev[1]) |
4cab417a JM |
4917 | with open(config, "w") as f: |
4918 | f.write("update_config=1\n" + | |
4919 | "dpp_config_processing=1\n") | |
4920 | wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') | |
4921 | wpas.interface_add("wlan5", config=config) | |
4922 | check_dpp_capab(wpas) | |
4923 | conf = '{"wi-fi_tech":"infra", "discovery":{"ssid":"' + conf_ssid + '"},"cred":{"akm":"psk","pass":"secret passphrase"}}' | |
4924 | dev[1].set("dpp_config_obj_override", conf) | |
4925 | dpp_dev = [wpas, dev[1]] | |
4926 | run_dpp_qr_code_auth_unicast(dpp_dev, apdev, "prime256v1", | |
4927 | require_conf_success=True) | |
4928 | if "OK" not in wpas.request("SAVE_CONFIG"): | |
4929 | raise Exception("Failed to save configuration file") | |
4930 | with open(config, "r") as f: | |
4931 | data = f.read() | |
4932 | logger.info("Saved configuration:\n" + data) | |
4933 | if 'ssid=' + exp_ssid + '\n' not in data: | |
4934 | raise Exception("SSID not saved") | |
4935 | if 'psk="secret passphrase"' not in data: | |
4936 | raise Exception("Passphtase not saved") | |
4a667b01 JM |
4937 | |
4938 | def test_dpp_nfc_uri(dev, apdev): | |
4939 | """DPP bootstrapping via NFC URI record""" | |
4940 | check_dpp_capab(dev[0]) | |
4941 | check_dpp_capab(dev[1]) | |
4942 | ||
4943 | id = dev[0].dpp_bootstrap_gen(type="nfc-uri", chan="81/1", mac=True) | |
4944 | uri = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id) | |
4945 | logger.info("Generated URI: " + uri) | |
4946 | info = dev[0].request("DPP_BOOTSTRAP_INFO %d" % id) | |
4947 | logger.info("Bootstrapping info:\n" + info) | |
4948 | if "type=NFC-URI" not in info: | |
4949 | raise Exception("Unexpected bootstrapping info contents") | |
4950 | ||
4951 | dev[0].dpp_listen(2412) | |
4952 | conf_id = dev[1].dpp_configurator_add() | |
4953 | dev[1].dpp_auth_init(nfc_uri=uri, configurator=conf_id, conf="sta-dpp") | |
4954 | wait_auth_success(dev[0], dev[1], configurator=dev[1], enrollee=dev[0]) | |
f94e677d | 4955 | |
db1aa8f1 JM |
4956 | def test_dpp_nfc_negotiated_handover(dev, apdev): |
4957 | """DPP bootstrapping via NFC negotiated handover""" | |
4958 | run_dpp_nfc_negotiated_handover(dev, apdev) | |
4959 | ||
4960 | def test_dpp_nfc_negotiated_handover_diff_curve(dev, apdev): | |
4961 | """DPP bootstrapping via NFC negotiated handover (different curve)""" | |
4962 | run_dpp_nfc_negotiated_handover(dev, apdev, curve0="prime256v1", | |
4963 | curve1="secp384r1") | |
4964 | ||
4965 | def run_dpp_nfc_negotiated_handover(dev, apdev, curve0=None, curve1=None): | |
4966 | check_dpp_capab(dev[0]) | |
4967 | check_dpp_capab(dev[1]) | |
4968 | ||
4969 | id0 = dev[0].dpp_bootstrap_gen(type="nfc-uri", chan="81/6,11", mac=True, | |
4970 | curve=curve0) | |
4971 | uri0 = dev[0].request("DPP_BOOTSTRAP_GET_URI %d" % id0) | |
4972 | logger.info("Generated URI[0]: " + uri0) | |
4973 | id1 = dev[1].dpp_bootstrap_gen(type="nfc-uri", chan="81/1,6,11", mac=True, | |
4974 | curve=curve1) | |
4975 | uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1) | |
4976 | logger.info("Generated URI[1]: " + uri1) | |
4977 | ||
4978 | # dev[0] acting as NFC Handover Requestor | |
4979 | # dev[1] acting as NFC Handover Selector | |
4980 | res = dev[1].request("DPP_NFC_HANDOVER_REQ own=%d uri=%s" % (id1, uri0)) | |
4981 | if "FAIL" in res: | |
4982 | raise Exception("Failed to process NFC Handover Request") | |
4983 | info = dev[1].request("DPP_BOOTSTRAP_INFO %d" % id1) | |
4984 | logger.info("Updated local bootstrapping info:\n" + info) | |
4985 | freq = None | |
4986 | for line in info.splitlines(): | |
4987 | if line.startswith("use_freq="): | |
4988 | freq = int(line.split('=')[1]) | |
4989 | if freq is None: | |
4990 | raise Exception("Selected channel not indicated") | |
4991 | uri1 = dev[1].request("DPP_BOOTSTRAP_GET_URI %d" % id1) | |
4992 | logger.info("Updated URI[1]: " + uri1) | |
4993 | dev[1].dpp_listen(freq) | |
4994 | res = dev[0].request("DPP_NFC_HANDOVER_SEL own=%d uri=%s" % (id0, uri1)) | |
4995 | if "FAIL" in res: | |
4996 | raise Exception("Failed to process NFC Handover Select") | |
4997 | peer = int(res) | |
4998 | ||
4999 | conf_id = dev[0].dpp_configurator_add() | |
5000 | dev[0].dpp_auth_init(peer=peer, own=id0, configurator=conf_id, | |
5001 | conf="sta-dpp") | |
5002 | wait_auth_success(dev[1], dev[0], configurator=dev[0], enrollee=dev[1]) | |
5003 | ||
f94e677d JM |
5004 | def test_dpp_with_p2p_device(dev, apdev): |
5005 | """DPP exchange when driver uses a separate P2P Device interface""" | |
5006 | check_dpp_capab(dev[0]) | |
5007 | with HWSimRadio(use_p2p_device=True) as (radio, iface): | |
5008 | wpas = WpaSupplicant(global_iface='/tmp/wpas-wlan5') | |
5009 | wpas.interface_add(iface) | |
5010 | check_dpp_capab(wpas) | |
5011 | id1 = wpas.dpp_bootstrap_gen(chan="81/1", mac=True) | |
5012 | uri1 = wpas.request("DPP_BOOTSTRAP_GET_URI %d" % id1) | |
5013 | wpas.dpp_listen(2412) | |
5014 | time.sleep(7) | |
5015 | dev[0].dpp_auth_init(uri=uri1) | |
5016 | wait_auth_success(wpas, dev[0], configurator=dev[0], enrollee=wpas, | |
5017 | allow_enrollee_failure=True) |