1# 2# Copyright 2019 - The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import logging 17import time 18 19from bluetooth_packets_python3 import hci_packets 20from cert.event_stream import EventStream 21from cert.gd_base_test import GdBaseTestClass 22from cert.py_security import PySecurity 23from cert.truth import assertThat 24from facade import common_pb2 as common 25from google.protobuf import empty_pb2 as empty_proto 26from hci.facade import controller_facade_pb2 as controller_facade 27from hci.facade import le_initiator_address_facade_pb2 as le_initiator_address_facade 28from l2cap.classic.facade_pb2 import ClassicSecurityPolicy 29from neighbor.facade import facade_pb2 as neighbor_facade 30from security.cert.cert_security import CertSecurity 31from security.facade_pb2 import AuthenticationRequirements 32from security.facade_pb2 import BondMsgType 33from security.facade_pb2 import IoCapabilities 34from security.facade_pb2 import OobDataPresent 35from security.facade_pb2 import UiMsgType 36 37 38class SecurityTest(GdBaseTestClass): 39 """ 40 Collection of tests that each sample results from 41 different (unique) combinations of io capabilities, authentication requirements, and oob data. 42 """ 43 44 _io_capabilities_name_lookup = { 45 IoCapabilities.DISPLAY_ONLY: "DISPLAY_ONLY", 46 IoCapabilities.DISPLAY_YES_NO_IO_CAP: "DISPLAY_YES_NO_IO_CAP", 47 #IoCapabilities.KEYBOARD_ONLY:"KEYBOARD_ONLY", 48 IoCapabilities.NO_INPUT_NO_OUTPUT: "NO_INPUT_NO_OUTPUT", 49 } 50 51 _auth_reqs_name_lookup = { 52 AuthenticationRequirements.NO_BONDING: "NO_BONDING", 53 AuthenticationRequirements.NO_BONDING_MITM_PROTECTION: "NO_BONDING_MITM_PROTECTION", 54 AuthenticationRequirements.DEDICATED_BONDING: "DEDICATED_BONDING", 55 AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION: "DEDICATED_BONDING_MITM_PROTECTION", 56 AuthenticationRequirements.GENERAL_BONDING: "GENERAL_BONDING", 57 AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION: "GENERAL_BONDING_MITM_PROTECTION", 58 } 59 60 # Possible IO Capabilities 61 io_capabilities = ( 62 IoCapabilities.DISPLAY_ONLY, 63 IoCapabilities.DISPLAY_YES_NO_IO_CAP, 64 # TODO(optedoblivion): Uncomment when Passkey Entry is implemented in ClassicPairingHandler 65 #IoCapabilities.KEYBOARD_ONLY, 66 IoCapabilities.NO_INPUT_NO_OUTPUT) 67 68 # Possible Authentication Requirements 69 auth_reqs = (AuthenticationRequirements.NO_BONDING, AuthenticationRequirements.NO_BONDING_MITM_PROTECTION, 70 AuthenticationRequirements.DEDICATED_BONDING, 71 AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION, 72 AuthenticationRequirements.GENERAL_BONDING, AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION) 73 74 # Possible Out-of-Band data options 75 oob_present = ( 76 OobDataPresent.NOT_PRESENT, 77 # TODO(optedoblivion): Uncomment when OOB is implemented in root canal 78 #"P192_PRESENT", 79 #"P256_PRESENT", 80 #"P192_AND_256_PRESENT" 81 ) 82 83 mitm_auth_reqs = (AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION, 84 AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION, 85 AuthenticationRequirements.NO_BONDING_MITM_PROTECTION) 86 87 def setup_class(self): 88 super().setup_class(dut_module='SECURITY', cert_module='L2CAP') 89 90 def setup_test(self): 91 super().setup_test() 92 93 self.dut.neighbor.EnablePageScan(neighbor_facade.EnableMsg(enabled=True)) 94 self.cert.neighbor.EnablePageScan(neighbor_facade.EnableMsg(enabled=True)) 95 96 self.dut.name = b'DUT Device' 97 self.dut.address = self.dut.hci_controller.GetMacAddress(empty_proto.Empty()).address 98 self.cert.name = b'Cert Device' 99 self.cert.address = self.cert.hci_controller.GetMacAddress(empty_proto.Empty()).address 100 101 # TODO(optedoblivion): Make this happen in PySecurity or GdDevice 102 self.dut.hci_controller.WriteLocalName(controller_facade.NameMsg(name=self.dut.name)) 103 self.cert.hci_controller.WriteLocalName(controller_facade.NameMsg(name=self.cert.name)) 104 105 self.dut_security = PySecurity(self.dut) 106 self.cert_security = CertSecurity(self.cert) 107 108 self.dut_address = common.BluetoothAddressWithType( 109 address=common.BluetoothAddress(address=bytes(b'DD:05:04:03:02:01')), type=common.RANDOM_DEVICE_ADDRESS) 110 privacy_policy = le_initiator_address_facade.PrivacyPolicy( 111 address_policy=le_initiator_address_facade.AddressPolicy.USE_STATIC_ADDRESS, 112 address_with_type=self.dut_address) 113 self.dut.security.SetLeInitiatorAddressPolicy(privacy_policy) 114 115 def teardown_test(self): 116 self.dut_security.close() 117 self.cert_security.close() 118 super().teardown_test() 119 120 # Initiates the numeric comparison test 121 def _run_ssp_numeric_comparison(self, initiator, responder, init_ui_response, resp_ui_response, 122 expected_init_ui_event, expected_resp_ui_event, expected_init_bond_event, 123 expected_resp_bond_event): 124 initiator.enable_secure_simple_pairing() 125 responder.enable_secure_simple_pairing() 126 initiator.create_bond(responder.get_address(), common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 127 self._verify_ssp_numeric_comparison(initiator, responder, init_ui_response, resp_ui_response, 128 expected_init_ui_event, expected_resp_ui_event, expected_init_bond_event, 129 expected_resp_bond_event) 130 131 # Verifies the events for the numeric comparion test 132 def _verify_ssp_numeric_comparison(self, initiator, responder, init_ui_response, resp_ui_response, 133 expected_init_ui_event, expected_resp_ui_event, expected_init_bond_event, 134 expected_resp_bond_event): 135 responder.accept_pairing(initiator.get_address(), resp_ui_response) 136 initiator.on_user_input(responder.get_address(), init_ui_response, expected_init_ui_event) 137 initiator.wait_for_bond_event(expected_init_bond_event) 138 responder.wait_for_bond_event(expected_resp_bond_event) 139 140 def _run_ssp_oob(self, initiator, responder, init_ui_response, resp_ui_response, expected_init_ui_event, 141 expected_resp_ui_event, expected_init_bond_event, expected_resp_bond_event, p192_oob_data, 142 p256_oob_data): 143 initiator.enable_secure_simple_pairing() 144 responder.enable_secure_simple_pairing() 145 initiator.create_bond_out_of_band(responder.get_address(), 146 common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS, p192_oob_data, 147 p256_oob_data) 148 self._verify_ssp_oob(initiator, responder, init_ui_response, resp_ui_response, expected_init_ui_event, 149 expected_resp_ui_event, expected_init_bond_event, expected_resp_bond_event, p192_oob_data, 150 p256_oob_data) 151 152 # Verifies the events for the numeric comparion test 153 def _verify_ssp_oob(self, initiator, responder, init_ui_response, resp_ui_response, expected_init_ui_event, 154 expected_resp_ui_event, expected_init_bond_event, expected_resp_bond_event, p192_oob_data, 155 p256_oob_data): 156 responder.accept_oob_pairing(initiator.get_address()) 157 initiator.on_user_input(responder.get_address(), init_ui_response, expected_init_ui_event) 158 initiator.wait_for_bond_event(expected_init_bond_event) 159 responder.wait_for_bond_event(expected_resp_bond_event) 160 161 def _run_ssp_passkey(self, initiator, responder, expected_init_bond_event, expected_resp_bond_event): 162 initiator.enable_secure_simple_pairing() 163 responder.enable_secure_simple_pairing() 164 initiator.create_bond(responder.get_address(), common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 165 self._verify_ssp_passkey(initiator, responder, expected_init_bond_event, expected_resp_bond_event) 166 167 def _verify_ssp_passkey(self, initiator, responder, expected_init_bond_event, expected_resp_bond_event): 168 responder.send_io_caps(initiator.get_address()) 169 passkey = initiator.wait_for_passkey(responder.get_address()) 170 responder.input_passkey(initiator.get_address(), passkey) 171 initiator.wait_for_bond_event(expected_init_bond_event) 172 responder.wait_for_bond_event(expected_resp_bond_event) 173 174 def _run_pin(self, initiator, responder, expected_init_bond_event, expected_resp_bond_event): 175 initiator.create_bond(responder.get_address(), common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 176 self._verify_pin(initiator, responder, expected_init_bond_event, expected_resp_bond_event) 177 178 def _verify_pin(self, initiator, responder, expected_init_bond_event, expected_resp_bond_event): 179 pin = b'123456789A' 180 logging.info("pin: %s" % pin) 181 initiator.input_pin(responder.get_address(), pin) 182 responder.input_pin(initiator.get_address(), pin) 183 initiator.wait_for_bond_event(expected_init_bond_event) 184 responder.wait_for_bond_event(expected_resp_bond_event) 185 186 def test_setup_teardown(self): 187 """ 188 Make sure our setup and teardown is sane 189 """ 190 pass 191 192 # no_input_no_output + no_input_no_output is JustWorks no confirmation 193 def test_dut_initiated_no_input_no_output_no_input_no_output_twice_bond_and_enforce(self): 194 # Arrange 195 self.dut_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) 196 self.dut_security.set_authentication_requirements(AuthenticationRequirements.DEDICATED_BONDING) 197 self.cert_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) 198 self.cert_security.set_authentication_requirements(AuthenticationRequirements.DEDICATED_BONDING) 199 200 # Act and Assert 201 self._run_ssp_numeric_comparison( 202 initiator=self.dut_security, 203 responder=self.cert_security, 204 init_ui_response=True, 205 resp_ui_response=True, 206 expected_init_ui_event=None, 207 expected_resp_ui_event=None, 208 expected_init_bond_event=BondMsgType.DEVICE_BONDED, 209 expected_resp_bond_event=None) 210 211 self.dut_security.enforce_security_policy(self.cert.address, 212 common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS, 213 ClassicSecurityPolicy.ENCRYPTED_TRANSPORT) 214 215 # TODO: We verify enforcement when we make sure EncryptionChange is received on DUT 216 217 # no_input_no_output + no_input_no_output is JustWorks no confirmation 218 def test_dut_initiated_no_input_no_output_no_input_no_output_twice_with_remove_bond(self): 219 # Arrange 220 self.dut_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) 221 self.dut_security.set_authentication_requirements(AuthenticationRequirements.DEDICATED_BONDING) 222 self.cert_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) 223 self.cert_security.set_authentication_requirements(AuthenticationRequirements.DEDICATED_BONDING) 224 225 # Act and Assert 226 self._run_ssp_numeric_comparison( 227 initiator=self.dut_security, 228 responder=self.cert_security, 229 init_ui_response=True, 230 resp_ui_response=True, 231 expected_init_ui_event=None, 232 expected_resp_ui_event=None, 233 expected_init_bond_event=BondMsgType.DEVICE_BONDED, 234 expected_resp_bond_event=None) 235 236 self.dut_security.remove_bond(self.cert.address, common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 237 self.cert_security.remove_bond(self.cert.address, common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 238 self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 239 self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 240 241 self.dut_security.wait_for_disconnect_event() 242 self.cert_security.wait_for_disconnect_event() 243 244 # Act and Assert 245 self._run_ssp_numeric_comparison( 246 initiator=self.dut_security, 247 responder=self.cert_security, 248 init_ui_response=True, 249 resp_ui_response=True, 250 expected_init_ui_event=None, 251 expected_resp_ui_event=None, 252 expected_init_bond_event=BondMsgType.DEVICE_BONDED, 253 expected_resp_bond_event=None) 254 255 self.dut_security.remove_bond(self.cert.address, common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 256 self.cert_security.remove_bond(self.cert.address, common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 257 self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 258 self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 259 260 self.dut_security.wait_for_disconnect_event() 261 self.cert_security.wait_for_disconnect_event() 262 263 def test_successful_dut_initiated_ssp_numeric_comparison(self): 264 test_count = len(self.io_capabilities) * len(self.auth_reqs) * len(self.oob_present) * len( 265 self.io_capabilities) * len(self.auth_reqs) * len(self.oob_present) 266 logging.info("Loading %d test combinations" % test_count) 267 i = 0 268 for dut_io_capability in self.io_capabilities: 269 for dut_auth_reqs in self.auth_reqs: 270 for dut_oob_present in self.oob_present: 271 for cert_io_capability in self.io_capabilities: 272 for cert_auth_reqs in self.auth_reqs: 273 for cert_oob_present in self.oob_present: 274 i = i + 1 275 logging.info("") 276 logging.info("===================================================") 277 logging.info("Running test %d of %d" % (i, test_count)) 278 logging.info("DUT Test Config: %s ; %s ; %s " % (self._io_capabilities_name_lookup.get( 279 dut_io_capability, "ERROR"), self._auth_reqs_name_lookup.get( 280 dut_auth_reqs, "ERROR"), dut_oob_present)) 281 logging.info( 282 "CERT Test Config: %s ; %s ; %s " % 283 (self._io_capabilities_name_lookup.get(cert_io_capability, "ERROR"), 284 self._auth_reqs_name_lookup.get(cert_auth_reqs, "ERROR"), cert_oob_present)) 285 logging.info("===================================================") 286 logging.info("") 287 self.dut_security.set_io_capabilities(dut_io_capability) 288 self.dut_security.set_authentication_requirements(dut_auth_reqs) 289 self.cert_security.set_io_capabilities(cert_io_capability) 290 self.cert_security.set_authentication_requirements(cert_auth_reqs) 291 init_ui_response = True 292 resp_ui_response = True 293 expected_init_ui_event = None # None is auto accept 294 expected_resp_ui_event = None # None is auto accept 295 expected_init_bond_event = BondMsgType.DEVICE_BONDED 296 expected_resp_bond_event = None 297 if dut_io_capability == IoCapabilities.DISPLAY_ONLY: 298 if cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: 299 expected_resp_ui_event = UiMsgType.DISPLAY_YES_NO_WITH_VALUE 300 if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: 301 expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED 302 elif cert_io_capability == IoCapabilities.KEYBOARD_ONLY: 303 expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY 304 elif cert_io_capability == IoCapabilities.DISPLAY_ONLY: 305 if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: 306 expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED 307 elif cert_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: 308 if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: 309 expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED 310 elif dut_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: 311 expected_init_ui_event = UiMsgType.DISPLAY_YES_NO_WITH_VALUE 312 if cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: 313 expected_resp_ui_event = UiMsgType.DISPLAY_YES_NO_WITH_VALUE 314 elif cert_io_capability == IoCapabilities.KEYBOARD_ONLY: 315 expected_init_ui_event = UiMsgType.DISPLAY_PASSKEY 316 expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY 317 elif cert_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: 318 expected_init_ui_event = UiMsgType.DISPLAY_YES_NO # No value 319 elif dut_io_capability == IoCapabilities.KEYBOARD_ONLY: 320 expected_init_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY 321 if cert_io_capability == IoCapabilities.DISPLAY_ONLY: 322 expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY 323 elif cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: 324 expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY 325 elif cert_io_capability == IoCapabilities.KEYBOARD_ONLY: 326 expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY 327 elif cert_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: 328 if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: 329 expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED 330 elif dut_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: 331 if cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: 332 expected_resp_ui_event = UiMsgType.DISPLAY_YES_NO # No value 333 334 if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: 335 expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED 336 337 if cert_oob_present == OobDataPresent.NOT_PRESENT: 338 self._run_ssp_numeric_comparison( 339 initiator=self.dut_security, 340 responder=self.cert_security, 341 init_ui_response=init_ui_response, 342 resp_ui_response=resp_ui_response, 343 expected_init_ui_event=expected_init_ui_event, 344 expected_resp_ui_event=expected_resp_ui_event, 345 expected_init_bond_event=expected_init_bond_event, 346 expected_resp_bond_event=expected_resp_bond_event) 347 else: 348 logging.error("Code path not yet implemented") 349 assertThat(False).isTrue() 350 351 self.dut_security.remove_bond(self.cert_security.get_address(), 352 common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 353 self.cert_security.remove_bond(self.dut_security.get_address(), 354 common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 355 356 self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 357 self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 358 359 self.dut_security.wait_for_disconnect_event() 360 self.cert_security.wait_for_disconnect_event() 361 362 def test_enable_secure_simple_pairing(self): 363 self.dut_security.enable_secure_simple_pairing() 364 self.cert_security.enable_secure_simple_pairing() 365 366 def test_enable_secure_connections(self): 367 self.dut_security.enable_secure_simple_pairing() 368 self.cert_security.enable_secure_simple_pairing() 369 self.dut_security.enable_secure_connections() 370 self.cert_security.enable_secure_connections() 371 372 def test_get_oob_data_from_dut_controller_p192_present(self): 373 oob_data = self.dut_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) 374 assertThat(len(oob_data)).isEqualTo(4) 375 has192C = not all([i == 0 for i in oob_data[0]]) 376 has192R = not all([i == 0 for i in oob_data[1]]) 377 has256C = not all([i == 0 for i in oob_data[2]]) 378 has256R = not all([i == 0 for i in oob_data[3]]) 379 assertThat(has192C).isTrue() 380 assertThat(has192R).isTrue() 381 assertThat(has256C).isFalse() 382 assertThat(has256R).isFalse() 383 384 def test_get_oob_data_from_cert_controller_not_present(self): 385 oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.NOT_PRESENT) 386 assertThat(len(oob_data)).isEqualTo(4) 387 has192C = not all([i == 0 for i in oob_data[0]]) 388 has192R = not all([i == 0 for i in oob_data[1]]) 389 has256C = not all([i == 0 for i in oob_data[2]]) 390 has256R = not all([i == 0 for i in oob_data[3]]) 391 assertThat(has192C).isFalse() 392 assertThat(has192R).isFalse() 393 assertThat(has256C).isFalse() 394 assertThat(has256R).isFalse() 395 396 def test_get_oob_data_from_cert_controller_p192_present_no_secure_connections(self): 397 oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) 398 assertThat(len(oob_data)).isEqualTo(4) 399 has192C = not all([i == 0 for i in oob_data[0]]) 400 has192R = not all([i == 0 for i in oob_data[1]]) 401 has256C = not all([i == 0 for i in oob_data[2]]) 402 has256R = not all([i == 0 for i in oob_data[3]]) 403 assertThat(has192C).isTrue() 404 assertThat(has192R).isTrue() 405 assertThat(has256C).isFalse() 406 assertThat(has256R).isFalse() 407 408 def test_get_oob_data_from_cert_controller_p192_present(self): 409 self.cert_security.enable_secure_simple_pairing() 410 self.cert_security.enable_secure_connections() 411 oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) 412 assertThat(len(oob_data)).isEqualTo(4) 413 has192C = not all([i == 0 for i in oob_data[0]]) 414 has192R = not all([i == 0 for i in oob_data[1]]) 415 has256C = not all([i == 0 for i in oob_data[2]]) 416 has256R = not all([i == 0 for i in oob_data[3]]) 417 assertThat(has192C).isTrue() 418 assertThat(has192R).isTrue() 419 assertThat(has256C).isFalse() 420 assertThat(has256R).isFalse() 421 422 def test_get_oob_data_from_cert_controller_p256_present(self): 423 self.cert_security.enable_secure_simple_pairing() 424 self.cert_security.enable_secure_connections() 425 oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P256_PRESENT) 426 assertThat(len(oob_data)).isEqualTo(4) 427 has192C = not all([i == 0 for i in oob_data[0]]) 428 has192R = not all([i == 0 for i in oob_data[1]]) 429 has256C = not all([i == 0 for i in oob_data[2]]) 430 has256R = not all([i == 0 for i in oob_data[3]]) 431 assertThat(has192C).isFalse() 432 assertThat(has192R).isFalse() 433 assertThat(has256C).isTrue() 434 assertThat(has256R).isTrue() 435 436 def test_get_oob_data_from_cert_controller_p192_and_p256_present(self): 437 self.cert_security.enable_secure_simple_pairing() 438 self.cert_security.enable_secure_connections() 439 oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_AND_256_PRESENT) 440 assertThat(len(oob_data)).isEqualTo(4) 441 has192C = not all([i == 0 for i in oob_data[0]]) 442 has192R = not all([i == 0 for i in oob_data[1]]) 443 has256C = not all([i == 0 for i in oob_data[2]]) 444 has256R = not all([i == 0 for i in oob_data[3]]) 445 assertThat(has192C).isTrue() 446 assertThat(has192R).isTrue() 447 assertThat(has256C).isTrue() 448 assertThat(has256R).isTrue() 449 450 def test_successful_dut_initiated_ssp_oob(self): 451 dut_io_capability = IoCapabilities.NO_INPUT_NO_OUTPUT 452 cert_io_capability = IoCapabilities.NO_INPUT_NO_OUTPUT 453 dut_auth_reqs = AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION 454 cert_auth_reqs = AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION 455 cert_oob_present = OobDataPresent.P192_PRESENT 456 self.dut_security.enable_secure_simple_pairing() 457 self.dut_security.enable_secure_connections() 458 self.cert_security.enable_secure_simple_pairing() 459 self.cert_security.enable_secure_connections() 460 self.dut_security.set_io_capabilities(dut_io_capability) 461 self.dut_security.set_authentication_requirements(dut_auth_reqs) 462 self.cert_security.set_io_capabilities(cert_io_capability) 463 self.cert_security.set_authentication_requirements(cert_auth_reqs) 464 init_ui_response = True 465 resp_ui_response = True 466 expected_init_ui_event = None # None is auto accept 467 expected_resp_ui_event = None # None is auto accept 468 expected_init_bond_event = BondMsgType.DEVICE_BONDED 469 expected_resp_bond_event = None 470 # get_oob_data returns a tuple of bytes (p192c,p192r,p256c,p256r) 471 local_oob_data = self.cert_security.get_oob_data_from_controller(cert_oob_present) 472 p192_oob_data = local_oob_data[0:2] 473 p256_oob_data = local_oob_data[2:4] 474 self._run_ssp_oob( 475 initiator=self.dut_security, 476 responder=self.cert_security, 477 init_ui_response=init_ui_response, 478 resp_ui_response=resp_ui_response, 479 expected_init_ui_event=expected_init_ui_event, 480 expected_resp_ui_event=expected_resp_ui_event, 481 expected_init_bond_event=expected_init_bond_event, 482 expected_resp_bond_event=expected_resp_bond_event, 483 p192_oob_data=p192_oob_data, 484 p256_oob_data=p256_oob_data) 485 self.dut_security.remove_bond(self.cert_security.get_address(), 486 common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 487 self.cert_security.remove_bond(self.dut_security.get_address(), 488 common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 489 self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 490 self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 491 self.dut_security.wait_for_disconnect_event() 492 self.cert_security.wait_for_disconnect_event() 493 494 def test_successful_dut_initiated_ssp_keyboard(self): 495 dut_io_capability = IoCapabilities.DISPLAY_YES_NO_IO_CAP 496 dut_auth_reqs = AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION 497 dut_oob_present = OobDataPresent.NOT_PRESENT 498 cert_io_capability = IoCapabilities.KEYBOARD_ONLY 499 cert_auth_reqs = AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION 500 cert_oob_present = OobDataPresent.NOT_PRESENT 501 self.dut_security.set_io_capabilities(dut_io_capability) 502 self.dut_security.set_authentication_requirements(dut_auth_reqs) 503 self.cert_security.set_io_capabilities(cert_io_capability) 504 self.cert_security.set_authentication_requirements(cert_auth_reqs) 505 506 self._run_ssp_passkey( 507 initiator=self.dut_security, 508 responder=self.cert_security, 509 expected_init_bond_event=BondMsgType.DEVICE_BONDED, 510 expected_resp_bond_event=BondMsgType.DEVICE_BONDED) 511 512 self.dut_security.remove_bond(self.cert_security.get_address(), 513 common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 514 self.cert_security.remove_bond(self.dut_security.get_address(), 515 common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 516 517 self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 518 self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 519 520 self.dut_security.wait_for_disconnect_event() 521 self.cert_security.wait_for_disconnect_event() 522 523 def test_successful_dut_initiated_pin(self): 524 self.dut_security.set_io_capabilities(IoCapabilities.DISPLAY_YES_NO_IO_CAP) 525 self.dut_security.set_authentication_requirements(AuthenticationRequirements.DEDICATED_BONDING) 526 527 self._run_pin( 528 initiator=self.dut_security, 529 responder=self.cert_security, 530 expected_init_bond_event=BondMsgType.DEVICE_BONDED, 531 expected_resp_bond_event=BondMsgType.DEVICE_BONDED) 532 533 self.dut_security.remove_bond(self.cert_security.get_address(), 534 common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 535 self.cert_security.remove_bond(self.dut_security.get_address(), 536 common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) 537 538 self.dut_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 539 self.cert_security.wait_for_bond_event(BondMsgType.DEVICE_UNBONDED) 540 541 self.dut_security.wait_for_disconnect_event() 542 self.cert_security.wait_for_disconnect_event() 543 544 def test_make_sure_oob_data_different(self): 545 oob_data = self.dut_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) 546 oob_data2 = self.dut_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) 547 assertThat(oob_data).isNotEqualTo(oob_data2) 548