Loading system/gd/cert/py_security.py +12 −4 Original line number Diff line number Diff line Loading @@ -125,7 +125,7 @@ class PySecurity(Closable): auth_reqs, "ERROR")) self._device.security.SetAuthenticationRequirements(AuthenticationRequirementsMessage(requirement=auth_reqs)) def send_ui_callback(self, address, callback_type, b, uid): def __send_ui_callback(self, address, callback_type, b, uid, pin): """ Send a callback from the UI as if the user pressed a button on the dialog """ Loading @@ -135,6 +135,7 @@ class PySecurity(Closable): message_type=callback_type, boolean=b, unique_id=uid, pin=bytes(pin), address=common.BluetoothAddressWithType( address=common.BluetoothAddress(address=address), type=common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS))) Loading Loading @@ -183,7 +184,14 @@ class PySecurity(Closable): assertThat(self._ui_event_stream).emits(get_unique_id) return passkey def on_user_input(self, cert_address, reply_boolean, expected_ui_event): def input_pin(self, cert_address, pin): """ Respond to the UI event """ self.on_user_input( cert_address=cert_address, reply_boolean=True, expected_ui_event=UiMsgType.DISPLAY_PIN_ENTRY, pin=pin) def on_user_input(self, cert_address, reply_boolean, expected_ui_event, pin=[]): """ Respond to the UI event """ Loading @@ -201,8 +209,8 @@ class PySecurity(Closable): logging.debug("DUT: Waiting for expected UI event") assertThat(self._ui_event_stream).emits(get_unique_id) # TODO(optedoblivion): Make UiCallbackType dynamic for PASSKEY when added self.send_ui_callback(cert_address, UiCallbackType.YES_NO, reply_boolean, ui_id) callback_type = UiCallbackType.YES_NO if len(pin) == 0 else UiCallbackType.PIN self.__send_ui_callback(cert_address, callback_type, reply_boolean, ui_id, pin) def get_address(self): return self._device.address Loading system/gd/security/cert/cert_security.py +20 −1 Original line number Diff line number Diff line Loading @@ -74,6 +74,9 @@ class CertSecurity(PySecurity): _hci = None MAX_PIN_LENGTH = 16 MIN_PIN_LENGTH = 1 def _enqueue_hci_command(self, command, expect_complete): if (expect_complete): self._hci.send_command_with_complete(command) Loading Loading @@ -230,7 +233,23 @@ class CertSecurity(PySecurity): True) self._enqueue_hci_command(hci_packets.UserPasskeyRequestReplyBuilder(peer, passkey), True) def send_ui_callback(self, address, callback_type, b, uid): def input_pin(self, address, pin): """ Pretend to answer the pairing dialog as a user """ if len(pin) > self.MAX_PIN_LENGTH or len(pin) < self.MIN_PIN_LENGTH: raise Exception("Pin code must be within range") logging.info("Cert: Waiting for PIN request") assertThat(self._hci_event_stream).emits(HciMatchers.EventWithCode(hci_packets.EventCode.PIN_CODE_REQUEST)) logging.info("Cert: Send user input PIN %s for %s" % (pin.decode(), address)) peer = address.decode('utf-8') pin_list = list(pin) # Pad for i in range(self.MAX_PIN_LENGTH - len(pin_list)): pin_list.append(0) self._enqueue_hci_command(hci_packets.PinCodeRequestReplyBuilder(peer, len(pin), pin_list), True) def __send_ui_callback(self, address, callback_type, b, uid, pin): """ Pretend to answer the pairing dailog as a user """ Loading system/gd/security/facade.cc +17 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,12 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public security_module_->GetSecurityManager()->OnPairingPromptAccepted( hci::AddressWithType(peer, remote_type), request->boolean()); break; case UiCallbackType::PIN: LOG_INFO("PIN Callback"); security_module_->GetSecurityManager()->OnPinEntry( hci::AddressWithType(peer, remote_type), std::vector<uint8_t>(request->pin().cbegin(), request->pin().cend())); break; default: LOG_ERROR("Unknown UiCallbackType %d", static_cast<int>(request->message_type())); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Unknown UiCallbackType"); Loading Loading @@ -414,6 +420,17 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public ui_events_.OnIncomingEvent(display_passkey_input); } void DisplayEnterPinDialog(ConfirmationData data) override { const bluetooth::hci::AddressWithType& peer = data.GetAddressWithType(); std::string name = data.GetName(); LOG_INFO("%s", peer.ToString().c_str()); UiMsg display_pin_input; *display_pin_input.mutable_peer() = ToFacadeAddressWithType(peer); display_pin_input.set_message_type(UiMsgType::DISPLAY_PIN_ENTRY); display_pin_input.set_unique_id(unique_id++); ui_events_.OnIncomingEvent(display_pin_input); } void Cancel(const bluetooth::hci::AddressWithType& peer) override { LOG_INFO("%s", peer.ToString().c_str()); UiMsg display_cancel; Loading system/gd/security/facade.proto +7 −4 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ enum UiMsgType { DISPLAY_PASSKEY_ENTRY = 3; DISPLAY_CANCEL = 4; DISPLAY_PAIRING_PROMPT = 5; DISPLAY_PIN_ENTRY = 6; } message UiMsg { Loading @@ -63,14 +64,16 @@ enum UiCallbackType { YES_NO = 0; PASSKEY = 1; PAIRING_PROMPT = 2; PIN = 3; } message UiCallbackMsg { UiCallbackType message_type = 1; bool boolean = 2; uint32 numeric_value = 3; uint32 unique_id = 4; facade.BluetoothAddressWithType address = 5; facade.BluetoothAddressWithType address = 2; bool boolean = 3; uint32 numeric_value = 4; uint32 unique_id = 5; bytes pin = 6; } enum BondMsgType { Loading system/gd/security/internal/security_manager_impl.cc +11 −0 Original line number Diff line number Diff line Loading @@ -414,6 +414,17 @@ void SecurityManagerImpl::OnPasskeyEntry(const bluetooth::hci::AddressWithType& } } void SecurityManagerImpl::OnPinEntry(const bluetooth::hci::AddressWithType& address, std::vector<uint8_t> pin) { auto entry = pairing_handler_map_.find(address.GetAddress()); if (entry != pairing_handler_map_.end()) { LOG_INFO("PIN for %s", address.ToString().c_str()); entry->second->OnPinEntry(address, pin); } else { LOG_WARN("No handler found for PIN for %s", address.ToString().c_str()); // TODO(jpawlowski): Implement LE version } } void SecurityManagerImpl::OnPairingHandlerComplete(hci::Address address, PairingResultOrFailure status) { auto entry = pairing_handler_map_.find(address); if (entry != pairing_handler_map_.end()) { Loading Loading
system/gd/cert/py_security.py +12 −4 Original line number Diff line number Diff line Loading @@ -125,7 +125,7 @@ class PySecurity(Closable): auth_reqs, "ERROR")) self._device.security.SetAuthenticationRequirements(AuthenticationRequirementsMessage(requirement=auth_reqs)) def send_ui_callback(self, address, callback_type, b, uid): def __send_ui_callback(self, address, callback_type, b, uid, pin): """ Send a callback from the UI as if the user pressed a button on the dialog """ Loading @@ -135,6 +135,7 @@ class PySecurity(Closable): message_type=callback_type, boolean=b, unique_id=uid, pin=bytes(pin), address=common.BluetoothAddressWithType( address=common.BluetoothAddress(address=address), type=common.BluetoothAddressTypeEnum.PUBLIC_DEVICE_ADDRESS))) Loading Loading @@ -183,7 +184,14 @@ class PySecurity(Closable): assertThat(self._ui_event_stream).emits(get_unique_id) return passkey def on_user_input(self, cert_address, reply_boolean, expected_ui_event): def input_pin(self, cert_address, pin): """ Respond to the UI event """ self.on_user_input( cert_address=cert_address, reply_boolean=True, expected_ui_event=UiMsgType.DISPLAY_PIN_ENTRY, pin=pin) def on_user_input(self, cert_address, reply_boolean, expected_ui_event, pin=[]): """ Respond to the UI event """ Loading @@ -201,8 +209,8 @@ class PySecurity(Closable): logging.debug("DUT: Waiting for expected UI event") assertThat(self._ui_event_stream).emits(get_unique_id) # TODO(optedoblivion): Make UiCallbackType dynamic for PASSKEY when added self.send_ui_callback(cert_address, UiCallbackType.YES_NO, reply_boolean, ui_id) callback_type = UiCallbackType.YES_NO if len(pin) == 0 else UiCallbackType.PIN self.__send_ui_callback(cert_address, callback_type, reply_boolean, ui_id, pin) def get_address(self): return self._device.address Loading
system/gd/security/cert/cert_security.py +20 −1 Original line number Diff line number Diff line Loading @@ -74,6 +74,9 @@ class CertSecurity(PySecurity): _hci = None MAX_PIN_LENGTH = 16 MIN_PIN_LENGTH = 1 def _enqueue_hci_command(self, command, expect_complete): if (expect_complete): self._hci.send_command_with_complete(command) Loading Loading @@ -230,7 +233,23 @@ class CertSecurity(PySecurity): True) self._enqueue_hci_command(hci_packets.UserPasskeyRequestReplyBuilder(peer, passkey), True) def send_ui_callback(self, address, callback_type, b, uid): def input_pin(self, address, pin): """ Pretend to answer the pairing dialog as a user """ if len(pin) > self.MAX_PIN_LENGTH or len(pin) < self.MIN_PIN_LENGTH: raise Exception("Pin code must be within range") logging.info("Cert: Waiting for PIN request") assertThat(self._hci_event_stream).emits(HciMatchers.EventWithCode(hci_packets.EventCode.PIN_CODE_REQUEST)) logging.info("Cert: Send user input PIN %s for %s" % (pin.decode(), address)) peer = address.decode('utf-8') pin_list = list(pin) # Pad for i in range(self.MAX_PIN_LENGTH - len(pin_list)): pin_list.append(0) self._enqueue_hci_command(hci_packets.PinCodeRequestReplyBuilder(peer, len(pin), pin_list), True) def __send_ui_callback(self, address, callback_type, b, uid, pin): """ Pretend to answer the pairing dailog as a user """ Loading
system/gd/security/facade.cc +17 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,12 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public security_module_->GetSecurityManager()->OnPairingPromptAccepted( hci::AddressWithType(peer, remote_type), request->boolean()); break; case UiCallbackType::PIN: LOG_INFO("PIN Callback"); security_module_->GetSecurityManager()->OnPinEntry( hci::AddressWithType(peer, remote_type), std::vector<uint8_t>(request->pin().cbegin(), request->pin().cend())); break; default: LOG_ERROR("Unknown UiCallbackType %d", static_cast<int>(request->message_type())); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Unknown UiCallbackType"); Loading Loading @@ -414,6 +420,17 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public ui_events_.OnIncomingEvent(display_passkey_input); } void DisplayEnterPinDialog(ConfirmationData data) override { const bluetooth::hci::AddressWithType& peer = data.GetAddressWithType(); std::string name = data.GetName(); LOG_INFO("%s", peer.ToString().c_str()); UiMsg display_pin_input; *display_pin_input.mutable_peer() = ToFacadeAddressWithType(peer); display_pin_input.set_message_type(UiMsgType::DISPLAY_PIN_ENTRY); display_pin_input.set_unique_id(unique_id++); ui_events_.OnIncomingEvent(display_pin_input); } void Cancel(const bluetooth::hci::AddressWithType& peer) override { LOG_INFO("%s", peer.ToString().c_str()); UiMsg display_cancel; Loading
system/gd/security/facade.proto +7 −4 Original line number Diff line number Diff line Loading @@ -50,6 +50,7 @@ enum UiMsgType { DISPLAY_PASSKEY_ENTRY = 3; DISPLAY_CANCEL = 4; DISPLAY_PAIRING_PROMPT = 5; DISPLAY_PIN_ENTRY = 6; } message UiMsg { Loading @@ -63,14 +64,16 @@ enum UiCallbackType { YES_NO = 0; PASSKEY = 1; PAIRING_PROMPT = 2; PIN = 3; } message UiCallbackMsg { UiCallbackType message_type = 1; bool boolean = 2; uint32 numeric_value = 3; uint32 unique_id = 4; facade.BluetoothAddressWithType address = 5; facade.BluetoothAddressWithType address = 2; bool boolean = 3; uint32 numeric_value = 4; uint32 unique_id = 5; bytes pin = 6; } enum BondMsgType { Loading
system/gd/security/internal/security_manager_impl.cc +11 −0 Original line number Diff line number Diff line Loading @@ -414,6 +414,17 @@ void SecurityManagerImpl::OnPasskeyEntry(const bluetooth::hci::AddressWithType& } } void SecurityManagerImpl::OnPinEntry(const bluetooth::hci::AddressWithType& address, std::vector<uint8_t> pin) { auto entry = pairing_handler_map_.find(address.GetAddress()); if (entry != pairing_handler_map_.end()) { LOG_INFO("PIN for %s", address.ToString().c_str()); entry->second->OnPinEntry(address, pin); } else { LOG_WARN("No handler found for PIN for %s", address.ToString().c_str()); // TODO(jpawlowski): Implement LE version } } void SecurityManagerImpl::OnPairingHandlerComplete(hci::Address address, PairingResultOrFailure status) { auto entry = pairing_handler_map_.find(address); if (entry != pairing_handler_map_.end()) { Loading