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