class SecurityTest(GdBaseTestClass): """ Collection of tests that each sample results from different (unique) combinations of io capabilities, authentication requirements, and oob data. """ def setup_class(self): super().setup_class(dut_module='SECURITY', cert_module='L2CAP') def setup_test(self): super().setup_test() self.dut.neighbor.EnablePageScan( neighbor_facade.EnableMsg(enabled=True)) self.cert.neighbor.EnablePageScan( neighbor_facade.EnableMsg(enabled=True)) self.dut.name = b'DUT Device' self.dut.address = self.dut.hci_controller.GetMacAddress( empty_proto.Empty()).address self.cert.name = b'Cert Device' self.cert.address = self.cert.hci_controller.GetMacAddress( empty_proto.Empty()).address # TODO(optedoblivion): Make this happen in PySecurity or GdDevice self.dut.hci_controller.WriteLocalName( controller_facade.NameMsg(name=self.dut.name)) self.cert.hci_controller.WriteLocalName( controller_facade.NameMsg(name=self.cert.name)) self.dut_security = PySecurity(self.dut) self.cert_security = CertSecurity(self.cert) def teardown_test(self): self.dut_security.close() self.cert_security.close() super().teardown_test() # SSP Numeric Comparison test cases def _run_ssp_numeric_comparison( self, initiator, responder, init_ui_response, resp_ui_response, expected_init_ui_event, expected_resp_ui_event, expected_init_bond_event, expected_resp_bond_event): initiator.enable_secure_simple_pairing() responder.enable_secure_simple_pairing() initiator.create_bond( responder.get_address(), common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) responder.accept_pairing(initiator.get_address(), resp_ui_response) initiator.on_user_input(responder.get_address(), init_ui_response, expected_init_ui_event) initiator.wait_for_bond_event(expected_init_bond_event) responder.wait_for_bond_event(expected_resp_bond_event) def test_setup_teardown(self): """ Make sure our setup and teardown is sane """ pass ###### JustWorks (Numeric Comparison w/ no UI) ###### ## Needs dialog as per security a bug unless pairing is temporary # display_only + display_only is JustWorks no confirmation def test_dut_initiated_display_only_display_only(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.DISPLAY_ONLY) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities(IoCapabilities.DISPLAY_ONLY) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # display_yes_no + display_only is JustWorks no confirmation def test_dut_initiated_display_yes_no_display_only(self): # Arrange self.dut_security.set_io_capabilities( IoCapabilities.DISPLAY_YES_NO_IO_CAP) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities(IoCapabilities.DISPLAY_ONLY) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=UiMsgType.DISPLAY_YES_NO_WITH_VALUE, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # keyboard_only + display_only is JustWorks no confirmation def test_dut_initiated_keyboard_only_display_only(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.KEYBOARD_ONLY) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities(IoCapabilities.DISPLAY_ONLY) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # no_input_no_output + display_only is JustWorks no confirmation def test_dut_initiated_no_input_no_output_display_only(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities(IoCapabilities.DISPLAY_ONLY) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # display_only + display_yes_no is JustWorks no confirmation def test_dut_initiated_display_only_display_yes_no(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.DISPLAY_ONLY) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities( IoCapabilities.DISPLAY_YES_NO_IO_CAP) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # display_yes_no + display_yes_no is JustWorks no confirmation def test_dut_initiated_display_yes_no_display_yes_no(self): # Arrange self.dut_security.set_io_capabilities( IoCapabilities.DISPLAY_YES_NO_IO_CAP) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities( IoCapabilities.DISPLAY_YES_NO_IO_CAP) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=UiMsgType.DISPLAY_YES_NO_WITH_VALUE, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # keyboard_only + display_yes_no is JustWorks no confirmation def test_dut_initiated_keyboard_only_display_yes_no(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.KEYBOARD_ONLY) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities( IoCapabilities.DISPLAY_YES_NO_IO_CAP) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # no_input_no_output + display_yes_no is JustWorks no confirmation def test_dut_initiated_no_input_no_output_display_yes_no(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities( IoCapabilities.DISPLAY_YES_NO_IO_CAP) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # display_only + keyboard_only is JustWorks no confirmation def test_dut_initiated_display_only_keyboard_only(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.DISPLAY_ONLY) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities(IoCapabilities.KEYBOARD_ONLY) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # display_yes_no + keyboard_only is JustWorks no confirmation def test_dut_initiated_display_yes_no_keyboard_only(self): # Arrange self.dut_security.set_io_capabilities( IoCapabilities.DISPLAY_YES_NO_IO_CAP) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities(IoCapabilities.KEYBOARD_ONLY) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=UiMsgType.DISPLAY_PASSKEY, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # keyboard_only + display_yes_no is JustWorks no confirmation def test_dut_initiated_keyboard_only_keyboard_only(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.KEYBOARD_ONLY) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities(IoCapabilities.KEYBOARD_ONLY) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # no_input_no_output + keyboard_only is JustWorks no confirmation def test_dut_initiated_no_input_no_output_keyboard_only(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities( IoCapabilities.DISPLAY_YES_NO_IO_CAP) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # display_only + no_input_no_output is JustWorks no confirmation def test_dut_initiated_display_only_keyboard_only(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.DISPLAY_ONLY) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities( IoCapabilities.NO_INPUT_NO_OUTPUT) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # display_yes_no + keyboard_only is JustWorks no confirmation def test_dut_initiated_display_yes_no_no_input_no_output(self): # Arrange self.dut_security.set_io_capabilities( IoCapabilities.DISPLAY_YES_NO_IO_CAP) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities( IoCapabilities.NO_INPUT_NO_OUTPUT) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=UiMsgType.DISPLAY_YES_NO_WITH_VALUE, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # keyboard_only + display_yes_no is JustWorks no confirmation def test_dut_initiated_keyboard_only_no_input_no_output(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.KEYBOARD_ONLY) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities( IoCapabilities.NO_INPUT_NO_OUTPUT) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) # no_input_no_output + keyboard_only is JustWorks no confirmation def test_dut_initiated_no_input_no_output_no_input_no_output(self): # Arrange self.dut_security.set_io_capabilities(IoCapabilities.NO_INPUT_NO_OUTPUT) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities( IoCapabilities.NO_INPUT_NO_OUTPUT) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None)
class SecurityTest(GdBaseTestClass): """ Collection of tests that each sample results from different (unique) combinations of io capabilities, authentication requirements, and oob data. """ _io_capabilities_name_lookup = { IoCapabilities.DISPLAY_ONLY: "DISPLAY_ONLY", IoCapabilities.DISPLAY_YES_NO_IO_CAP: "DISPLAY_YES_NO_IO_CAP", #IoCapabilities.KEYBOARD_ONLY:"KEYBOARD_ONLY", IoCapabilities.NO_INPUT_NO_OUTPUT: "NO_INPUT_NO_OUTPUT", } _auth_reqs_name_lookup = { AuthenticationRequirements.NO_BONDING: "NO_BONDING", AuthenticationRequirements.NO_BONDING_MITM_PROTECTION: "NO_BONDING_MITM_PROTECTION", AuthenticationRequirements.DEDICATED_BONDING: "DEDICATED_BONDING", AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION: "DEDICATED_BONDING_MITM_PROTECTION", AuthenticationRequirements.GENERAL_BONDING: "GENERAL_BONDING", AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION: "GENERAL_BONDING_MITM_PROTECTION", } # Possible IO Capabilities io_capabilities = ( IoCapabilities.DISPLAY_ONLY, IoCapabilities.DISPLAY_YES_NO_IO_CAP, # TODO(optedoblivion): Uncomment when Passkey Entry is implemented in ClassicPairingHandler #IoCapabilities.KEYBOARD_ONLY, IoCapabilities.NO_INPUT_NO_OUTPUT) # Possible Authentication Requirements auth_reqs = (AuthenticationRequirements.NO_BONDING, AuthenticationRequirements.NO_BONDING_MITM_PROTECTION, AuthenticationRequirements.DEDICATED_BONDING, AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION, AuthenticationRequirements.GENERAL_BONDING, AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION) # Possible Out-of-Band data options oob_present = ( OobDataPresent.NOT_PRESENT, # TODO(optedoblivion): Uncomment when OOB is implemented in root canal #"P192_PRESENT", #"P256_PRESENT", #"P192_AND_256_PRESENT" ) mitm_auth_reqs = ( AuthenticationRequirements.DEDICATED_BONDING_MITM_PROTECTION, AuthenticationRequirements.GENERAL_BONDING_MITM_PROTECTION, AuthenticationRequirements.NO_BONDING_MITM_PROTECTION) def setup_class(self): super().setup_class(dut_module='SECURITY', cert_module='L2CAP') def setup_test(self): super().setup_test() self.dut.neighbor.EnablePageScan( neighbor_facade.EnableMsg(enabled=True)) self.cert.neighbor.EnablePageScan( neighbor_facade.EnableMsg(enabled=True)) self.dut.name = b'DUT Device' self.dut.address = self.dut.hci_controller.GetMacAddress( empty_proto.Empty()).address self.cert.name = b'Cert Device' self.cert.address = self.cert.hci_controller.GetMacAddress( empty_proto.Empty()).address # TODO(optedoblivion): Make this happen in PySecurity or GdDevice self.dut.hci_controller.WriteLocalName( controller_facade.NameMsg(name=self.dut.name)) self.cert.hci_controller.WriteLocalName( controller_facade.NameMsg(name=self.cert.name)) self.dut_security = PySecurity(self.dut) self.cert_security = CertSecurity(self.cert) self.dut_address = common.BluetoothAddressWithType( address=common.BluetoothAddress( address=bytes(b'DD:05:04:03:02:01')), type=common.RANDOM_DEVICE_ADDRESS) privacy_policy = le_initiator_address_facade.PrivacyPolicy( address_policy=le_initiator_address_facade.AddressPolicy. USE_STATIC_ADDRESS, address_with_type=self.dut_address) self.dut.security.SetLeInitiatorAddressPolicy(privacy_policy) def teardown_test(self): self.dut_security.close() self.cert_security.close() super().teardown_test() # Initiates the numeric comparison test def _run_ssp_numeric_comparison(self, initiator, responder, init_ui_response, resp_ui_response, expected_init_ui_event, expected_resp_ui_event, expected_init_bond_event, expected_resp_bond_event): initiator.enable_secure_simple_pairing() responder.enable_secure_simple_pairing() initiator.create_bond( responder.get_address(), common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) self._verify_ssp_numeric_comparison(initiator, responder, init_ui_response, resp_ui_response, expected_init_ui_event, expected_resp_ui_event, expected_init_bond_event, expected_resp_bond_event) # Verifies the events for the numeric comparion test def _verify_ssp_numeric_comparison(self, initiator, responder, init_ui_response, resp_ui_response, expected_init_ui_event, expected_resp_ui_event, expected_init_bond_event, expected_resp_bond_event): responder.accept_pairing(initiator.get_address(), resp_ui_response) initiator.on_user_input(responder.get_address(), init_ui_response, expected_init_ui_event) initiator.wait_for_bond_event(expected_init_bond_event) responder.wait_for_bond_event(expected_resp_bond_event) def test_setup_teardown(self): """ Make sure our setup and teardown is sane """ pass # no_input_no_output + no_input_no_output is JustWorks no confirmation def test_dut_initiated_no_input_no_output_no_input_no_output_twice_bond_and_enforce( self): # Arrange self.dut_security.set_io_capabilities( IoCapabilities.NO_INPUT_NO_OUTPUT) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities( IoCapabilities.NO_INPUT_NO_OUTPUT) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) self.dut_security.enforce_security_policy( self.cert.address, common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS, ClassicSecurityPolicy.ENCRYPTED_TRANSPORT) # TODO: We verify enforcement when we make sure EncryptionChange is received on DUT # no_input_no_output + no_input_no_output is JustWorks no confirmation def test_dut_initiated_no_input_no_output_no_input_no_output_twice_with_remove_bond( self): # Arrange self.dut_security.set_io_capabilities( IoCapabilities.NO_INPUT_NO_OUTPUT) self.dut_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING) self.dut_security.set_oob_data(OobDataPresent.NOT_PRESENT) self.cert_security.set_io_capabilities( IoCapabilities.NO_INPUT_NO_OUTPUT) self.cert_security.set_authentication_requirements( AuthenticationRequirements.DEDICATED_BONDING) self.cert_security.set_oob_data(OobDataPresent.NOT_PRESENT) # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) self.dut_security.remove_bond( self.cert.address, common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS) self.dut_security.wait_for_disconnect_event() self.cert_security.wait_for_disconnect_event() # Act and Assert self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=True, resp_ui_response=True, expected_init_ui_event=None, expected_resp_ui_event=None, expected_init_bond_event=BondMsgType.DEVICE_BONDED, expected_resp_bond_event=None) def test_successful_dut_initiated_ssp_numeric_comparison(self): test_count = len(self.io_capabilities) * len(self.auth_reqs) * len( self.oob_present) * len(self.io_capabilities) * len( self.auth_reqs) * len(self.oob_present) logging.info("Loading %d test combinations" % test_count) i = 0 for dut_io_capability in self.io_capabilities: for dut_auth_reqs in self.auth_reqs: for dut_oob_present in self.oob_present: for cert_io_capability in self.io_capabilities: for cert_auth_reqs in self.auth_reqs: for cert_oob_present in self.oob_present: i = i + 1 logging.info("") logging.info( "===================================================" ) logging.info("Running test %d of %d" % (i, test_count)) logging.info( "DUT Test Config: %s ; %s ; %s " % (self._io_capabilities_name_lookup.get( dut_io_capability, "ERROR"), self._auth_reqs_name_lookup.get( dut_auth_reqs, "ERROR"), dut_oob_present)) logging.info( "CERT Test Config: %s ; %s ; %s " % (self._io_capabilities_name_lookup.get( cert_io_capability, "ERROR"), self._auth_reqs_name_lookup.get( cert_auth_reqs, "ERROR"), cert_oob_present)) logging.info( "===================================================" ) logging.info("") self.dut_security.set_io_capabilities( dut_io_capability) self.dut_security.set_authentication_requirements( dut_auth_reqs) self.dut_security.set_oob_data(dut_oob_present) self.cert_security.set_io_capabilities( cert_io_capability) self.cert_security.set_authentication_requirements( cert_auth_reqs) self.cert_security.set_oob_data( cert_oob_present) init_ui_response = True resp_ui_response = True expected_init_ui_event = None # None is auto accept expected_resp_ui_event = None # None is auto accept expected_init_bond_event = BondMsgType.DEVICE_BONDED expected_resp_bond_event = None if dut_io_capability == IoCapabilities.DISPLAY_ONLY: if cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: expected_resp_ui_event = UiMsgType.DISPLAY_YES_NO_WITH_VALUE if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED elif cert_io_capability == IoCapabilities.KEYBOARD_ONLY: expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY elif cert_io_capability == IoCapabilities.DISPLAY_ONLY: if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED elif cert_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED elif dut_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: expected_init_ui_event = UiMsgType.DISPLAY_YES_NO_WITH_VALUE if cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: expected_resp_ui_event = UiMsgType.DISPLAY_YES_NO_WITH_VALUE elif cert_io_capability == IoCapabilities.KEYBOARD_ONLY: expected_init_ui_event = UiMsgType.DISPLAY_PASSKEY expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY elif cert_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: expected_init_ui_event = UiMsgType.DISPLAY_YES_NO # No value elif dut_io_capability == IoCapabilities.KEYBOARD_ONLY: expected_init_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY if cert_io_capability == IoCapabilities.DISPLAY_ONLY: expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY elif cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY elif cert_io_capability == IoCapabilities.KEYBOARD_ONLY: expected_resp_ui_event = UiMsgType.DISPLAY_PASSKEY_ENTRY elif cert_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED elif dut_io_capability == IoCapabilities.NO_INPUT_NO_OUTPUT: if cert_io_capability == IoCapabilities.DISPLAY_YES_NO_IO_CAP: expected_resp_ui_event = UiMsgType.DISPLAY_YES_NO # No value if dut_auth_reqs in self.mitm_auth_reqs or cert_auth_reqs in self.mitm_auth_reqs: expected_init_bond_event = BondMsgType.DEVICE_BOND_FAILED self._run_ssp_numeric_comparison( initiator=self.dut_security, responder=self.cert_security, init_ui_response=init_ui_response, resp_ui_response=resp_ui_response, expected_init_ui_event= expected_init_ui_event, expected_resp_ui_event= expected_resp_ui_event, expected_init_bond_event= expected_init_bond_event, expected_resp_bond_event= expected_resp_bond_event) self.dut_security.remove_bond( self.cert_security.get_address(), common.BluetoothAddressTypeEnum. PUBLIC_DEVICE_ADDRESS) self.cert_security.remove_bond( self.dut_security.get_address(), common.BluetoothAddressTypeEnum. PUBLIC_DEVICE_ADDRESS) self.dut_security.wait_for_bond_event( BondMsgType.DEVICE_UNBONDED) self.cert_security.wait_for_bond_event( BondMsgType.DEVICE_UNBONDED) self.dut_security.wait_for_disconnect_event() self.cert_security.wait_for_disconnect_event()