Loading system/gd/security/Android.bp +6 −2 Original line number Diff line number Diff line Loading @@ -7,8 +7,11 @@ filegroup { "pairing_handler_le.cc", "pairing_handler_le_legacy.cc", "pairing_handler_le_secure_connections.cc", "security_manager.cc", "internal/security_manager_impl.cc", "security_module.cc", ] ":BluetoothSecurityChannelSources", ], } filegroup { Loading @@ -18,5 +21,6 @@ filegroup { "pairing_handler_le_unittest.cc", "test/fake_l2cap_test.cc", "test/pairing_handler_le_pair_test.cc", ] ":BluetoothSecurityChannelTestSources", ], } system/gd/security/channel/Android.bp 0 → 100644 +13 −0 Original line number Diff line number Diff line filegroup { name: "BluetoothSecurityChannelSources", srcs: [ "security_manager_channel.cc", ] } filegroup { name: "BluetoothSecurityChannelTestSources", srcs: [ "security_manager_channel_unittest.cc", ] } system/gd/security/channel/security_manager_channel.cc 0 → 100644 +93 −0 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ #include "security_manager_channel.h" #include "security/smp_packets.h" using namespace bluetooth::hci; using namespace bluetooth::packet; using namespace bluetooth::security::channel; void SecurityManagerChannel::SendCommand(std::shared_ptr<hci::Device> device, std::unique_ptr<SecurityCommandBuilder> command) { hci_security_interface_->EnqueueCommand( std::move(command), common::BindOnce(&SecurityManagerChannel::OnCommandComplete, common::Unretained(this)), handler_); } void SecurityManagerChannel::OnCommandComplete(CommandCompleteView packet) { ASSERT_LOG(packet.IsValid(), "Received invalid packet: %hx", packet.GetCommandOpCode()); // TODO(optedoblivion): Verify HCI commands } void SecurityManagerChannel::OnHciEventReceived(EventPacketView packet) { ASSERT_LOG(listener_ != nullptr, "No listener set!"); std::shared_ptr<Device> device = nullptr; auto event = EventPacketView::Create(std::move(packet)); ASSERT_LOG(event.IsValid(), "Received invalid packet: %hhx", event.GetEventCode()); const hci::EventCode code = event.GetEventCode(); switch (code) { case hci::EventCode::CHANGE_CONNECTION_LINK_KEY_COMPLETE: listener_->OnChangeConnectionLinkKeyComplete(device, hci::ChangeConnectionLinkKeyCompleteView::Create(std::move(event))); break; case hci::EventCode::MASTER_LINK_KEY_COMPLETE: listener_->OnMasterLinkKeyComplete(device, hci::MasterLinkKeyCompleteView::Create(std::move(event))); break; case hci::EventCode::PIN_CODE_REQUEST: listener_->OnPinCodeRequest(device, hci::PinCodeRequestView::Create(std::move(event))); break; case hci::EventCode::LINK_KEY_REQUEST: listener_->OnLinkKeyRequest(device, hci::LinkKeyRequestView::Create(std::move(event))); break; case hci::EventCode::LINK_KEY_NOTIFICATION: listener_->OnLinkKeyNotification(device, hci::LinkKeyNotificationView::Create(std::move(event))); break; case hci::EventCode::IO_CAPABILITY_REQUEST: listener_->OnIoCapabilityRequest(device, hci::IoCapabilityRequestView::Create(std::move(event))); break; case hci::EventCode::IO_CAPABILITY_RESPONSE: listener_->OnIoCapabilityResponse(device, IoCapabilityResponseView::Create(std::move(event))); break; case hci::EventCode::SIMPLE_PAIRING_COMPLETE: listener_->OnSimplePairingComplete(device, SimplePairingCompleteView::Create(std::move(event))); break; case hci::EventCode::RETURN_LINK_KEYS: listener_->OnReturnLinkKeys(device, hci::ReturnLinkKeysView::Create(std::move(event))); break; case hci::EventCode::ENCRYPTION_CHANGE: listener_->OnEncryptionChange(device, hci::EncryptionChangeView::Create(std::move(event))); break; case hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE: listener_->OnEncryptionKeyRefreshComplete(device, hci::EncryptionKeyRefreshCompleteView::Create(std::move(event))); break; case hci::EventCode::REMOTE_OOB_DATA_REQUEST: listener_->OnRemoteOobDataRequest(device, hci::RemoteOobDataRequestView::Create(std::move(event))); break; case hci::EventCode::USER_PASSKEY_NOTIFICATION: // listener_->OnUserPasskeyNotification(device, <packet>); break; case hci::EventCode::KEYPRESS_NOTIFICATION: // listener_->OnSendKeypressNotification(device, <packet>); break; default: ASSERT_LOG(false, "Invalid packet received: %hhx", code); break; } } system/gd/security/channel/security_manager_channel.h 0 → 100644 +113 −0 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0; * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ #pragma once #include <memory> #include <vector> #include "hci/classic_device.h" #include "hci/hci_layer.h" #include "hci/security_interface.h" #include "security/smp_packets.h" namespace bluetooth { namespace security { namespace channel { using hci::CommandCompleteView; using hci::EventPacketView; using hci::SecurityCommandBuilder; using hci::SecurityCommandView; /** * Interface for listening to the channel for SMP commands. */ class ISecurityManagerChannelListener { public: virtual ~ISecurityManagerChannelListener() = default; virtual void OnChangeConnectionLinkKeyComplete(std::shared_ptr<hci::Device> device, hci::ChangeConnectionLinkKeyCompleteView packet) = 0; virtual void OnMasterLinkKeyComplete(std::shared_ptr<hci::Device> device, hci::MasterLinkKeyCompleteView packet) = 0; virtual void OnPinCodeRequest(std::shared_ptr<hci::Device> device, hci::PinCodeRequestView packet) = 0; virtual void OnLinkKeyRequest(std::shared_ptr<hci::Device> device, hci::LinkKeyRequestView packet) = 0; virtual void OnLinkKeyNotification(std::shared_ptr<hci::Device> device, hci::LinkKeyNotificationView packet) = 0; virtual void OnIoCapabilityRequest(std::shared_ptr<hci::Device> device, hci::IoCapabilityRequestView packet) = 0; virtual void OnIoCapabilityResponse(std::shared_ptr<hci::Device> device, hci::IoCapabilityResponseView packet) = 0; virtual void OnSimplePairingComplete(std::shared_ptr<hci::Device> device, hci::SimplePairingCompleteView packet) = 0; virtual void OnReturnLinkKeys(std::shared_ptr<hci::Device> device, hci::ReturnLinkKeysView packet) = 0; virtual void OnEncryptionChange(std::shared_ptr<hci::Device> device, hci::EncryptionChangeView packet) = 0; virtual void OnEncryptionKeyRefreshComplete(std::shared_ptr<hci::Device> device, hci::EncryptionKeyRefreshCompleteView packet) = 0; virtual void OnRemoteOobDataRequest(std::shared_ptr<hci::Device> device, hci::RemoteOobDataRequestView packet) = 0; }; /** * Channel for consolidating traffic and making the transport agnostic. */ class SecurityManagerChannel { public: explicit SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer) : listener_(nullptr), hci_security_interface_(hci_layer->GetSecurityInterface( common::Bind(&SecurityManagerChannel::OnHciEventReceived, common::Unretained(this)), handler)), handler_(handler) {} ~SecurityManagerChannel() { delete listener_; } /** * Send a given SMP command over the SecurityManagerChannel * * @param device target where command will be sent * @param command smp command to send */ void SendCommand(std::shared_ptr<hci::Device> device, std::unique_ptr<SecurityCommandBuilder> command); /** * Sets the listener to listen for channel events * * @param listener the caller interested in events */ void SetChannelListener(ISecurityManagerChannelListener* listener) { listener_ = listener; } /** * Called when an incoming HCI event happens * * @param event_packet */ void OnHciEventReceived(EventPacketView packet); /** * Called when an HCI command is completed * * @param on_complete */ void OnCommandComplete(CommandCompleteView packet); private: ISecurityManagerChannelListener* listener_; hci::SecurityInterface* hci_security_interface_; os::Handler* handler_; }; } // namespace channel } // namespace security } // namespace bluetooth system/gd/security/channel/security_manager_channel_unittest.cc 0 → 100644 +276 −0 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ #include "security_manager_channel.h" #include <gtest/gtest.h> #include "hci/device.h" #include "hci/device_database.h" #include "hci/hci_packets.h" #include "packet/raw_builder.h" #include "security/smp_packets.h" #include "security/test/fake_hci_layer.h" namespace bluetooth { namespace security { namespace channel { namespace { using bluetooth::security::channel::SecurityManagerChannel; using hci::AuthenticationRequirements; using hci::CommandCompleteBuilder; using hci::Device; using hci::DeviceDatabase; using hci::IoCapabilityRequestReplyBuilder; using hci::IoCapabilityRequestView; using hci::OobDataPresent; using hci::OpCode; using os::Handler; using os::Thread; using packet::RawBuilder; static DeviceDatabase kDeviceDatabase; class TestPayloadBuilder : public PacketBuilder<kLittleEndian> { public: ~TestPayloadBuilder() override = default; size_t size() const override { return 1; } void Serialize(BitInserter& inserter) const override {} static std::unique_ptr<TestPayloadBuilder> Create() { return std::unique_ptr<TestPayloadBuilder>(new TestPayloadBuilder()); } private: TestPayloadBuilder() : PacketBuilder<kLittleEndian>(){}; }; class SecurityManagerChannelCallback : public ISecurityManagerChannelListener { public: // HCI bool receivedChangeConnectionLinkKeyComplete = false; bool receivedMasterLinkKeyComplete = false; bool receivedPinCodeRequest = false; bool receivedLinkKeyRequest = false; bool receivedLinkKeyNotification = false; bool receivedIoCapabilityRequest = false; bool receivedIoCapabilityResponse = false; bool receivedSimplePairingComplete = false; bool receivedReturnLinkKeys = false; bool receivedEncryptionChange = false; bool receivedEncryptionKeyRefreshComplete = false; bool receivedRemoteOobDataRequest = false; void OnChangeConnectionLinkKeyComplete(std::shared_ptr<hci::Device> device, hci::ChangeConnectionLinkKeyCompleteView packet) { EXPECT_TRUE(packet.IsValid()); receivedChangeConnectionLinkKeyComplete = true; } void OnMasterLinkKeyComplete(std::shared_ptr<hci::Device> device, hci::MasterLinkKeyCompleteView packet) { EXPECT_TRUE(packet.IsValid()); receivedMasterLinkKeyComplete = true; } void OnPinCodeRequest(std::shared_ptr<hci::Device> device, hci::PinCodeRequestView packet) { EXPECT_TRUE(packet.IsValid()); receivedPinCodeRequest = true; } void OnLinkKeyRequest(std::shared_ptr<hci::Device> device, hci::LinkKeyRequestView packet) { EXPECT_TRUE(packet.IsValid()); receivedLinkKeyRequest = true; } void OnLinkKeyNotification(std::shared_ptr<hci::Device> device, hci::LinkKeyNotificationView packet) { EXPECT_TRUE(packet.IsValid()); receivedLinkKeyNotification = true; } void OnIoCapabilityRequest(std::shared_ptr<Device> device, hci::IoCapabilityRequestView packet) { EXPECT_TRUE(packet.IsValid()); receivedIoCapabilityRequest = true; } void OnIoCapabilityResponse(std::shared_ptr<Device> device, hci::IoCapabilityResponseView packet) { EXPECT_TRUE(packet.IsValid()); receivedIoCapabilityResponse = true; } void OnSimplePairingComplete(std::shared_ptr<Device> device, hci::SimplePairingCompleteView packet) { EXPECT_TRUE(packet.IsValid()); receivedSimplePairingComplete = true; } void OnReturnLinkKeys(std::shared_ptr<Device> device, hci::ReturnLinkKeysView packet) { EXPECT_TRUE(packet.IsValid()); receivedReturnLinkKeys = true; } void OnEncryptionChange(std::shared_ptr<Device> device, hci::EncryptionChangeView packet) { EXPECT_TRUE(packet.IsValid()); receivedEncryptionChange = true; } void OnEncryptionKeyRefreshComplete(std::shared_ptr<Device> device, hci::EncryptionKeyRefreshCompleteView packet) { EXPECT_TRUE(packet.IsValid()); receivedEncryptionKeyRefreshComplete = true; } void OnRemoteOobDataRequest(std::shared_ptr<Device> device, hci::RemoteOobDataRequestView packet) { EXPECT_TRUE(packet.IsValid()); receivedRemoteOobDataRequest = true; } }; class SecurityManagerChannelTest : public ::testing::Test { protected: void SetUp() override { device_ = kDeviceDatabase.CreateClassicDevice(hci::Address({0x01, 0x02, 0x03, 0x04, 0x05, 0x06})); handler_ = new Handler(&thread_); callback_ = new SecurityManagerChannelCallback(); hci_layer_ = new FakeHciLayer(); fake_registry_.InjectTestModule(&FakeHciLayer::Factory, hci_layer_); fake_registry_.Start<FakeHciLayer>(&thread_); channel_ = new SecurityManagerChannel(handler_, hci_layer_); channel_->SetChannelListener(callback_); } void TearDown() override { channel_->SetChannelListener(nullptr); handler_->Clear(); fake_registry_.SynchronizeModuleHandler(&FakeHciLayer::Factory, std::chrono::milliseconds(20)); fake_registry_.StopAll(); delete handler_; delete channel_; delete callback_; } TestModuleRegistry fake_registry_; Thread& thread_ = fake_registry_.GetTestThread(); Handler* handler_ = nullptr; FakeHciLayer* hci_layer_ = nullptr; SecurityManagerChannel* channel_ = nullptr; SecurityManagerChannelCallback* callback_ = nullptr; std::shared_ptr<Device> device_ = nullptr; }; TEST_F(SecurityManagerChannelTest, setup_teardown) {} TEST_F(SecurityManagerChannelTest, recv_io_cap_request) { hci_layer_->IncomingEvent(hci::IoCapabilityRequestBuilder::Create(device_->GetAddress())); EXPECT_TRUE(callback_->receivedIoCapabilityRequest); } TEST_F(SecurityManagerChannelTest, send_io_cap_request_reply) { // Arrange hci::IoCapability io_capability = (hci::IoCapability)0x00; OobDataPresent oob_present = (OobDataPresent)0x00; AuthenticationRequirements authentication_requirements = (AuthenticationRequirements)0x00; auto packet = hci::IoCapabilityRequestReplyBuilder::Create(device_->GetAddress(), io_capability, oob_present, authentication_requirements); // Act channel_->SendCommand(device_, std::move(packet)); auto last_command = std::move(hci_layer_->GetLastCommand()->command); auto command_packet = GetPacketView(std::move(last_command)); hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet); // Assert EXPECT_TRUE(packet_view.IsValid()); EXPECT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, packet_view.GetOpCode()); } TEST_F(SecurityManagerChannelTest, send_io_cap_request_neg_reply) { // Arrange auto packet = hci::IoCapabilityRequestNegativeReplyBuilder::Create(device_->GetAddress(), hci::ErrorCode::COMMAND_DISALLOWED); // Act channel_->SendCommand(device_, std::move(packet)); auto last_command = std::move(hci_layer_->GetLastCommand()->command); auto command_packet = GetPacketView(std::move(last_command)); hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet); // Assert EXPECT_TRUE(packet_view.IsValid()); EXPECT_EQ(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode()); } TEST_F(SecurityManagerChannelTest, recv_io_cap_response) { hci::IoCapability io_capability = (hci::IoCapability)0x00; OobDataPresent oob_present = (OobDataPresent)0x00; AuthenticationRequirements authentication_requirements = (AuthenticationRequirements)0x00; hci_layer_->IncomingEvent(hci::IoCapabilityResponseBuilder::Create(device_->GetAddress(), io_capability, oob_present, authentication_requirements)); EXPECT_TRUE(callback_->receivedIoCapabilityResponse); } TEST_F(SecurityManagerChannelTest, recv_pin_code_request) { hci_layer_->IncomingEvent(hci::PinCodeRequestBuilder::Create(device_->GetAddress())); EXPECT_TRUE(callback_->receivedPinCodeRequest); } TEST_F(SecurityManagerChannelTest, send_pin_code_request_reply) {} TEST_F(SecurityManagerChannelTest, send_pin_code_request_neg_reply) {} TEST_F(SecurityManagerChannelTest, recv_user_passkey_notification) {} TEST_F(SecurityManagerChannelTest, send_user_confirmation_request_reply) {} TEST_F(SecurityManagerChannelTest, send_user_confirmation_request_neg_reply) {} TEST_F(SecurityManagerChannelTest, recv_remote_oob_data_request) {} TEST_F(SecurityManagerChannelTest, send_remote_oob_data_request_reply) {} TEST_F(SecurityManagerChannelTest, send_remote_oob_data_request_neg_reply) {} TEST_F(SecurityManagerChannelTest, send_read_local_oob_data) {} TEST_F(SecurityManagerChannelTest, send_read_local_oob_extended_data) {} TEST_F(SecurityManagerChannelTest, recv_link_key_request) {} TEST_F(SecurityManagerChannelTest, recv_link_key_notification) {} TEST_F(SecurityManagerChannelTest, recv_master_link_complete) {} TEST_F(SecurityManagerChannelTest, recv_change_connection_link_key_complete) {} TEST_F(SecurityManagerChannelTest, recv_return_link_keys) {} TEST_F(SecurityManagerChannelTest, send_link_key_reply) {} TEST_F(SecurityManagerChannelTest, send_link_key_neg_reply) {} TEST_F(SecurityManagerChannelTest, send_read_stored_link_key) {} TEST_F(SecurityManagerChannelTest, send_write_stored_link_key) {} TEST_F(SecurityManagerChannelTest, send_delete_stored_link_key) {} TEST_F(SecurityManagerChannelTest, recv_encryption_change) {} TEST_F(SecurityManagerChannelTest, send_refresh_encryption_key) {} TEST_F(SecurityManagerChannelTest, send_read_encryption_key_size) {} TEST_F(SecurityManagerChannelTest, recv_simple_pairing_complete) {} TEST_F(SecurityManagerChannelTest, send_read_simple_pairing_mode) {} TEST_F(SecurityManagerChannelTest, send_write_simple_pairing_mode) {} TEST_F(SecurityManagerChannelTest, send_keypress_notification) {} } // namespace } // namespace channel } // namespace security } // namespace bluetooth Loading
system/gd/security/Android.bp +6 −2 Original line number Diff line number Diff line Loading @@ -7,8 +7,11 @@ filegroup { "pairing_handler_le.cc", "pairing_handler_le_legacy.cc", "pairing_handler_le_secure_connections.cc", "security_manager.cc", "internal/security_manager_impl.cc", "security_module.cc", ] ":BluetoothSecurityChannelSources", ], } filegroup { Loading @@ -18,5 +21,6 @@ filegroup { "pairing_handler_le_unittest.cc", "test/fake_l2cap_test.cc", "test/pairing_handler_le_pair_test.cc", ] ":BluetoothSecurityChannelTestSources", ], }
system/gd/security/channel/Android.bp 0 → 100644 +13 −0 Original line number Diff line number Diff line filegroup { name: "BluetoothSecurityChannelSources", srcs: [ "security_manager_channel.cc", ] } filegroup { name: "BluetoothSecurityChannelTestSources", srcs: [ "security_manager_channel_unittest.cc", ] }
system/gd/security/channel/security_manager_channel.cc 0 → 100644 +93 −0 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ #include "security_manager_channel.h" #include "security/smp_packets.h" using namespace bluetooth::hci; using namespace bluetooth::packet; using namespace bluetooth::security::channel; void SecurityManagerChannel::SendCommand(std::shared_ptr<hci::Device> device, std::unique_ptr<SecurityCommandBuilder> command) { hci_security_interface_->EnqueueCommand( std::move(command), common::BindOnce(&SecurityManagerChannel::OnCommandComplete, common::Unretained(this)), handler_); } void SecurityManagerChannel::OnCommandComplete(CommandCompleteView packet) { ASSERT_LOG(packet.IsValid(), "Received invalid packet: %hx", packet.GetCommandOpCode()); // TODO(optedoblivion): Verify HCI commands } void SecurityManagerChannel::OnHciEventReceived(EventPacketView packet) { ASSERT_LOG(listener_ != nullptr, "No listener set!"); std::shared_ptr<Device> device = nullptr; auto event = EventPacketView::Create(std::move(packet)); ASSERT_LOG(event.IsValid(), "Received invalid packet: %hhx", event.GetEventCode()); const hci::EventCode code = event.GetEventCode(); switch (code) { case hci::EventCode::CHANGE_CONNECTION_LINK_KEY_COMPLETE: listener_->OnChangeConnectionLinkKeyComplete(device, hci::ChangeConnectionLinkKeyCompleteView::Create(std::move(event))); break; case hci::EventCode::MASTER_LINK_KEY_COMPLETE: listener_->OnMasterLinkKeyComplete(device, hci::MasterLinkKeyCompleteView::Create(std::move(event))); break; case hci::EventCode::PIN_CODE_REQUEST: listener_->OnPinCodeRequest(device, hci::PinCodeRequestView::Create(std::move(event))); break; case hci::EventCode::LINK_KEY_REQUEST: listener_->OnLinkKeyRequest(device, hci::LinkKeyRequestView::Create(std::move(event))); break; case hci::EventCode::LINK_KEY_NOTIFICATION: listener_->OnLinkKeyNotification(device, hci::LinkKeyNotificationView::Create(std::move(event))); break; case hci::EventCode::IO_CAPABILITY_REQUEST: listener_->OnIoCapabilityRequest(device, hci::IoCapabilityRequestView::Create(std::move(event))); break; case hci::EventCode::IO_CAPABILITY_RESPONSE: listener_->OnIoCapabilityResponse(device, IoCapabilityResponseView::Create(std::move(event))); break; case hci::EventCode::SIMPLE_PAIRING_COMPLETE: listener_->OnSimplePairingComplete(device, SimplePairingCompleteView::Create(std::move(event))); break; case hci::EventCode::RETURN_LINK_KEYS: listener_->OnReturnLinkKeys(device, hci::ReturnLinkKeysView::Create(std::move(event))); break; case hci::EventCode::ENCRYPTION_CHANGE: listener_->OnEncryptionChange(device, hci::EncryptionChangeView::Create(std::move(event))); break; case hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE: listener_->OnEncryptionKeyRefreshComplete(device, hci::EncryptionKeyRefreshCompleteView::Create(std::move(event))); break; case hci::EventCode::REMOTE_OOB_DATA_REQUEST: listener_->OnRemoteOobDataRequest(device, hci::RemoteOobDataRequestView::Create(std::move(event))); break; case hci::EventCode::USER_PASSKEY_NOTIFICATION: // listener_->OnUserPasskeyNotification(device, <packet>); break; case hci::EventCode::KEYPRESS_NOTIFICATION: // listener_->OnSendKeypressNotification(device, <packet>); break; default: ASSERT_LOG(false, "Invalid packet received: %hhx", code); break; } }
system/gd/security/channel/security_manager_channel.h 0 → 100644 +113 −0 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0; * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ #pragma once #include <memory> #include <vector> #include "hci/classic_device.h" #include "hci/hci_layer.h" #include "hci/security_interface.h" #include "security/smp_packets.h" namespace bluetooth { namespace security { namespace channel { using hci::CommandCompleteView; using hci::EventPacketView; using hci::SecurityCommandBuilder; using hci::SecurityCommandView; /** * Interface for listening to the channel for SMP commands. */ class ISecurityManagerChannelListener { public: virtual ~ISecurityManagerChannelListener() = default; virtual void OnChangeConnectionLinkKeyComplete(std::shared_ptr<hci::Device> device, hci::ChangeConnectionLinkKeyCompleteView packet) = 0; virtual void OnMasterLinkKeyComplete(std::shared_ptr<hci::Device> device, hci::MasterLinkKeyCompleteView packet) = 0; virtual void OnPinCodeRequest(std::shared_ptr<hci::Device> device, hci::PinCodeRequestView packet) = 0; virtual void OnLinkKeyRequest(std::shared_ptr<hci::Device> device, hci::LinkKeyRequestView packet) = 0; virtual void OnLinkKeyNotification(std::shared_ptr<hci::Device> device, hci::LinkKeyNotificationView packet) = 0; virtual void OnIoCapabilityRequest(std::shared_ptr<hci::Device> device, hci::IoCapabilityRequestView packet) = 0; virtual void OnIoCapabilityResponse(std::shared_ptr<hci::Device> device, hci::IoCapabilityResponseView packet) = 0; virtual void OnSimplePairingComplete(std::shared_ptr<hci::Device> device, hci::SimplePairingCompleteView packet) = 0; virtual void OnReturnLinkKeys(std::shared_ptr<hci::Device> device, hci::ReturnLinkKeysView packet) = 0; virtual void OnEncryptionChange(std::shared_ptr<hci::Device> device, hci::EncryptionChangeView packet) = 0; virtual void OnEncryptionKeyRefreshComplete(std::shared_ptr<hci::Device> device, hci::EncryptionKeyRefreshCompleteView packet) = 0; virtual void OnRemoteOobDataRequest(std::shared_ptr<hci::Device> device, hci::RemoteOobDataRequestView packet) = 0; }; /** * Channel for consolidating traffic and making the transport agnostic. */ class SecurityManagerChannel { public: explicit SecurityManagerChannel(os::Handler* handler, hci::HciLayer* hci_layer) : listener_(nullptr), hci_security_interface_(hci_layer->GetSecurityInterface( common::Bind(&SecurityManagerChannel::OnHciEventReceived, common::Unretained(this)), handler)), handler_(handler) {} ~SecurityManagerChannel() { delete listener_; } /** * Send a given SMP command over the SecurityManagerChannel * * @param device target where command will be sent * @param command smp command to send */ void SendCommand(std::shared_ptr<hci::Device> device, std::unique_ptr<SecurityCommandBuilder> command); /** * Sets the listener to listen for channel events * * @param listener the caller interested in events */ void SetChannelListener(ISecurityManagerChannelListener* listener) { listener_ = listener; } /** * Called when an incoming HCI event happens * * @param event_packet */ void OnHciEventReceived(EventPacketView packet); /** * Called when an HCI command is completed * * @param on_complete */ void OnCommandComplete(CommandCompleteView packet); private: ISecurityManagerChannelListener* listener_; hci::SecurityInterface* hci_security_interface_; os::Handler* handler_; }; } // namespace channel } // namespace security } // namespace bluetooth
system/gd/security/channel/security_manager_channel_unittest.cc 0 → 100644 +276 −0 Original line number Diff line number Diff line /****************************************************************************** * * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ******************************************************************************/ #include "security_manager_channel.h" #include <gtest/gtest.h> #include "hci/device.h" #include "hci/device_database.h" #include "hci/hci_packets.h" #include "packet/raw_builder.h" #include "security/smp_packets.h" #include "security/test/fake_hci_layer.h" namespace bluetooth { namespace security { namespace channel { namespace { using bluetooth::security::channel::SecurityManagerChannel; using hci::AuthenticationRequirements; using hci::CommandCompleteBuilder; using hci::Device; using hci::DeviceDatabase; using hci::IoCapabilityRequestReplyBuilder; using hci::IoCapabilityRequestView; using hci::OobDataPresent; using hci::OpCode; using os::Handler; using os::Thread; using packet::RawBuilder; static DeviceDatabase kDeviceDatabase; class TestPayloadBuilder : public PacketBuilder<kLittleEndian> { public: ~TestPayloadBuilder() override = default; size_t size() const override { return 1; } void Serialize(BitInserter& inserter) const override {} static std::unique_ptr<TestPayloadBuilder> Create() { return std::unique_ptr<TestPayloadBuilder>(new TestPayloadBuilder()); } private: TestPayloadBuilder() : PacketBuilder<kLittleEndian>(){}; }; class SecurityManagerChannelCallback : public ISecurityManagerChannelListener { public: // HCI bool receivedChangeConnectionLinkKeyComplete = false; bool receivedMasterLinkKeyComplete = false; bool receivedPinCodeRequest = false; bool receivedLinkKeyRequest = false; bool receivedLinkKeyNotification = false; bool receivedIoCapabilityRequest = false; bool receivedIoCapabilityResponse = false; bool receivedSimplePairingComplete = false; bool receivedReturnLinkKeys = false; bool receivedEncryptionChange = false; bool receivedEncryptionKeyRefreshComplete = false; bool receivedRemoteOobDataRequest = false; void OnChangeConnectionLinkKeyComplete(std::shared_ptr<hci::Device> device, hci::ChangeConnectionLinkKeyCompleteView packet) { EXPECT_TRUE(packet.IsValid()); receivedChangeConnectionLinkKeyComplete = true; } void OnMasterLinkKeyComplete(std::shared_ptr<hci::Device> device, hci::MasterLinkKeyCompleteView packet) { EXPECT_TRUE(packet.IsValid()); receivedMasterLinkKeyComplete = true; } void OnPinCodeRequest(std::shared_ptr<hci::Device> device, hci::PinCodeRequestView packet) { EXPECT_TRUE(packet.IsValid()); receivedPinCodeRequest = true; } void OnLinkKeyRequest(std::shared_ptr<hci::Device> device, hci::LinkKeyRequestView packet) { EXPECT_TRUE(packet.IsValid()); receivedLinkKeyRequest = true; } void OnLinkKeyNotification(std::shared_ptr<hci::Device> device, hci::LinkKeyNotificationView packet) { EXPECT_TRUE(packet.IsValid()); receivedLinkKeyNotification = true; } void OnIoCapabilityRequest(std::shared_ptr<Device> device, hci::IoCapabilityRequestView packet) { EXPECT_TRUE(packet.IsValid()); receivedIoCapabilityRequest = true; } void OnIoCapabilityResponse(std::shared_ptr<Device> device, hci::IoCapabilityResponseView packet) { EXPECT_TRUE(packet.IsValid()); receivedIoCapabilityResponse = true; } void OnSimplePairingComplete(std::shared_ptr<Device> device, hci::SimplePairingCompleteView packet) { EXPECT_TRUE(packet.IsValid()); receivedSimplePairingComplete = true; } void OnReturnLinkKeys(std::shared_ptr<Device> device, hci::ReturnLinkKeysView packet) { EXPECT_TRUE(packet.IsValid()); receivedReturnLinkKeys = true; } void OnEncryptionChange(std::shared_ptr<Device> device, hci::EncryptionChangeView packet) { EXPECT_TRUE(packet.IsValid()); receivedEncryptionChange = true; } void OnEncryptionKeyRefreshComplete(std::shared_ptr<Device> device, hci::EncryptionKeyRefreshCompleteView packet) { EXPECT_TRUE(packet.IsValid()); receivedEncryptionKeyRefreshComplete = true; } void OnRemoteOobDataRequest(std::shared_ptr<Device> device, hci::RemoteOobDataRequestView packet) { EXPECT_TRUE(packet.IsValid()); receivedRemoteOobDataRequest = true; } }; class SecurityManagerChannelTest : public ::testing::Test { protected: void SetUp() override { device_ = kDeviceDatabase.CreateClassicDevice(hci::Address({0x01, 0x02, 0x03, 0x04, 0x05, 0x06})); handler_ = new Handler(&thread_); callback_ = new SecurityManagerChannelCallback(); hci_layer_ = new FakeHciLayer(); fake_registry_.InjectTestModule(&FakeHciLayer::Factory, hci_layer_); fake_registry_.Start<FakeHciLayer>(&thread_); channel_ = new SecurityManagerChannel(handler_, hci_layer_); channel_->SetChannelListener(callback_); } void TearDown() override { channel_->SetChannelListener(nullptr); handler_->Clear(); fake_registry_.SynchronizeModuleHandler(&FakeHciLayer::Factory, std::chrono::milliseconds(20)); fake_registry_.StopAll(); delete handler_; delete channel_; delete callback_; } TestModuleRegistry fake_registry_; Thread& thread_ = fake_registry_.GetTestThread(); Handler* handler_ = nullptr; FakeHciLayer* hci_layer_ = nullptr; SecurityManagerChannel* channel_ = nullptr; SecurityManagerChannelCallback* callback_ = nullptr; std::shared_ptr<Device> device_ = nullptr; }; TEST_F(SecurityManagerChannelTest, setup_teardown) {} TEST_F(SecurityManagerChannelTest, recv_io_cap_request) { hci_layer_->IncomingEvent(hci::IoCapabilityRequestBuilder::Create(device_->GetAddress())); EXPECT_TRUE(callback_->receivedIoCapabilityRequest); } TEST_F(SecurityManagerChannelTest, send_io_cap_request_reply) { // Arrange hci::IoCapability io_capability = (hci::IoCapability)0x00; OobDataPresent oob_present = (OobDataPresent)0x00; AuthenticationRequirements authentication_requirements = (AuthenticationRequirements)0x00; auto packet = hci::IoCapabilityRequestReplyBuilder::Create(device_->GetAddress(), io_capability, oob_present, authentication_requirements); // Act channel_->SendCommand(device_, std::move(packet)); auto last_command = std::move(hci_layer_->GetLastCommand()->command); auto command_packet = GetPacketView(std::move(last_command)); hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet); // Assert EXPECT_TRUE(packet_view.IsValid()); EXPECT_EQ(OpCode::IO_CAPABILITY_REQUEST_REPLY, packet_view.GetOpCode()); } TEST_F(SecurityManagerChannelTest, send_io_cap_request_neg_reply) { // Arrange auto packet = hci::IoCapabilityRequestNegativeReplyBuilder::Create(device_->GetAddress(), hci::ErrorCode::COMMAND_DISALLOWED); // Act channel_->SendCommand(device_, std::move(packet)); auto last_command = std::move(hci_layer_->GetLastCommand()->command); auto command_packet = GetPacketView(std::move(last_command)); hci::CommandPacketView packet_view = hci::CommandPacketView::Create(command_packet); // Assert EXPECT_TRUE(packet_view.IsValid()); EXPECT_EQ(OpCode::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, packet_view.GetOpCode()); } TEST_F(SecurityManagerChannelTest, recv_io_cap_response) { hci::IoCapability io_capability = (hci::IoCapability)0x00; OobDataPresent oob_present = (OobDataPresent)0x00; AuthenticationRequirements authentication_requirements = (AuthenticationRequirements)0x00; hci_layer_->IncomingEvent(hci::IoCapabilityResponseBuilder::Create(device_->GetAddress(), io_capability, oob_present, authentication_requirements)); EXPECT_TRUE(callback_->receivedIoCapabilityResponse); } TEST_F(SecurityManagerChannelTest, recv_pin_code_request) { hci_layer_->IncomingEvent(hci::PinCodeRequestBuilder::Create(device_->GetAddress())); EXPECT_TRUE(callback_->receivedPinCodeRequest); } TEST_F(SecurityManagerChannelTest, send_pin_code_request_reply) {} TEST_F(SecurityManagerChannelTest, send_pin_code_request_neg_reply) {} TEST_F(SecurityManagerChannelTest, recv_user_passkey_notification) {} TEST_F(SecurityManagerChannelTest, send_user_confirmation_request_reply) {} TEST_F(SecurityManagerChannelTest, send_user_confirmation_request_neg_reply) {} TEST_F(SecurityManagerChannelTest, recv_remote_oob_data_request) {} TEST_F(SecurityManagerChannelTest, send_remote_oob_data_request_reply) {} TEST_F(SecurityManagerChannelTest, send_remote_oob_data_request_neg_reply) {} TEST_F(SecurityManagerChannelTest, send_read_local_oob_data) {} TEST_F(SecurityManagerChannelTest, send_read_local_oob_extended_data) {} TEST_F(SecurityManagerChannelTest, recv_link_key_request) {} TEST_F(SecurityManagerChannelTest, recv_link_key_notification) {} TEST_F(SecurityManagerChannelTest, recv_master_link_complete) {} TEST_F(SecurityManagerChannelTest, recv_change_connection_link_key_complete) {} TEST_F(SecurityManagerChannelTest, recv_return_link_keys) {} TEST_F(SecurityManagerChannelTest, send_link_key_reply) {} TEST_F(SecurityManagerChannelTest, send_link_key_neg_reply) {} TEST_F(SecurityManagerChannelTest, send_read_stored_link_key) {} TEST_F(SecurityManagerChannelTest, send_write_stored_link_key) {} TEST_F(SecurityManagerChannelTest, send_delete_stored_link_key) {} TEST_F(SecurityManagerChannelTest, recv_encryption_change) {} TEST_F(SecurityManagerChannelTest, send_refresh_encryption_key) {} TEST_F(SecurityManagerChannelTest, send_read_encryption_key_size) {} TEST_F(SecurityManagerChannelTest, recv_simple_pairing_complete) {} TEST_F(SecurityManagerChannelTest, send_read_simple_pairing_mode) {} TEST_F(SecurityManagerChannelTest, send_write_simple_pairing_mode) {} TEST_F(SecurityManagerChannelTest, send_keypress_notification) {} } // namespace } // namespace channel } // namespace security } // namespace bluetooth