Loading system/gd/cert/py_security.py +19 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ class PySecurity(Closable): _ui_event_stream = None _bond_event_stream = None _oob_data_event_stream = None def __init__(self, device): logging.debug("DUT: Init") Loading @@ -72,6 +73,8 @@ class PySecurity(Closable): self._enforce_security_policy_stream = EventStream( self._device.security.FetchEnforceSecurityPolicyEvents(empty_proto.Empty())) self._disconnect_event_stream = EventStream(self._device.security.FetchDisconnectEvents(empty_proto.Empty())) self._oob_data_event_stream = EventStream( self._device.security.FetchGetOutOfBandDataEvents(empty_proto.Empty())) def create_bond(self, address, type): """ Loading Loading @@ -253,8 +256,24 @@ class PySecurity(Closable): address=common.BluetoothAddressWithType(address=common.BluetoothAddress(address=address), type=type), policy=policy)) def get_oob_data_from_controller(self, oob_data_present): self._device.security.GetOutOfBandData(empty_proto.Empty()) oob_data = [] def get_oob_data(event): nonlocal oob_data oob_data = [ list(event.p192_data.confirmation_value), list(event.p192_data.random_value), [0 for i in range(0, 16)], [0 for i in range(0, 16)] ] return True assertThat(self._oob_data_event_stream).emits(get_oob_data) return oob_data def close(self): safeClose(self._ui_event_stream) safeClose(self._bond_event_stream) safeClose(self._enforce_security_policy_stream) safeClose(self._disconnect_event_stream) safeClose(self._oob_data_event_stream) system/gd/security/cert/security_test.py +17 −5 Original line number Diff line number Diff line Loading @@ -357,7 +357,19 @@ class SecurityTest(GdBaseTestClass): self.dut_security.enable_secure_connections() self.cert_security.enable_secure_connections() def test_get_oob_data_from_controller_not_present(self): def test_get_oob_data_from_dut_controller_p192_present(self): oob_data = self.dut_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) assertThat(len(oob_data)).isEqualTo(4) has192C = not all([i == 0 for i in oob_data[0]]) has192R = not all([i == 0 for i in oob_data[1]]) has256C = not all([i == 0 for i in oob_data[2]]) has256R = not all([i == 0 for i in oob_data[3]]) assertThat(has192C).isTrue() assertThat(has192R).isTrue() assertThat(has256C).isFalse() assertThat(has256R).isFalse() def test_get_oob_data_from_cert_controller_not_present(self): oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.NOT_PRESENT) assertThat(len(oob_data)).isEqualTo(4) has192C = not all([i == 0 for i in oob_data[0]]) Loading @@ -369,7 +381,7 @@ class SecurityTest(GdBaseTestClass): assertThat(has256C).isFalse() assertThat(has256R).isFalse() def test_get_oob_data_from_controller_p192_present_no_secure_connections(self): def test_get_oob_data_from_cert_controller_p192_present_no_secure_connections(self): oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) assertThat(len(oob_data)).isEqualTo(4) has192C = not all([i == 0 for i in oob_data[0]]) Loading @@ -381,7 +393,7 @@ class SecurityTest(GdBaseTestClass): assertThat(has256C).isFalse() assertThat(has256R).isFalse() def test_get_oob_data_from_controller_p192_present(self): def test_get_oob_data_from_cert_controller_p192_present(self): self.cert_security.enable_secure_simple_pairing() self.cert_security.enable_secure_connections() oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) Loading @@ -395,7 +407,7 @@ class SecurityTest(GdBaseTestClass): assertThat(has256C).isFalse() assertThat(has256R).isFalse() def test_get_oob_data_from_controller_p256_present(self): def test_get_oob_data_from_cert_controller_p256_present(self): self.cert_security.enable_secure_simple_pairing() self.cert_security.enable_secure_connections() oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P256_PRESENT) Loading @@ -409,7 +421,7 @@ class SecurityTest(GdBaseTestClass): assertThat(has256C).isTrue() assertThat(has256R).isTrue() def test_get_oob_data_from_controller_p192_and_p256_present(self): def test_get_oob_data_from_cert_controller_p192_and_p256_present(self): self.cert_security.enable_secure_simple_pairing() self.cert_security.enable_secure_connections() oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_AND_256_PRESENT) Loading system/gd/security/channel/security_manager_channel.cc +5 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,11 @@ void SecurityManagerChannel::SendCommand(std::unique_ptr<hci::SecurityCommandBui handler_->BindOnceOn(this, &SecurityManagerChannel::OnCommandComplete)); } void SecurityManagerChannel::SendCommand( std::unique_ptr<hci::SecurityCommandBuilder> command, SecurityCommandStatusCallback callback) { hci_security_interface_->EnqueueCommand(std::move(command), std::forward<SecurityCommandStatusCallback>(callback)); } void SecurityManagerChannel::OnHciEventReceived(hci::EventPacketView packet) { ASSERT_LOG(listener_ != nullptr, "No listener set!"); ASSERT(packet.IsValid()); Loading system/gd/security/channel/security_manager_channel.h +11 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <unordered_map> #include <vector> #include "common/contextual_callback.h" #include "hci/address_with_type.h" #include "hci/hci_layer.h" #include "hci/hci_packets.h" Loading @@ -32,6 +33,8 @@ namespace bluetooth { namespace security { namespace channel { using SecurityCommandStatusCallback = common::ContextualOnceCallback<void(hci::CommandCompleteView)>; /** * Interface for listening to the channel for SMP commands. */ Loading Loading @@ -83,6 +86,14 @@ class SecurityManagerChannel : public l2cap::classic::LinkSecurityInterfaceListe */ void SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command); /** * Send a given SMP command over the SecurityManagerChannel * * @param command smp command to send * @param callback listener to call when command status complete */ void SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command, SecurityCommandStatusCallback callback); /** * Sets the listener to listen for channel events * Loading system/gd/security/facade.cc +50 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,22 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public return ::grpc::Status::OK; } ::grpc::Status GetOutOfBandData( ::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::Empty* response) override { security_module_->GetSecurityManager()->GetOutOfBandData( security_handler_->BindOnceOn(this, &SecurityModuleFacadeService::OobDataEventOccurred)); return ::grpc::Status::OK; } ::grpc::Status FetchGetOutOfBandDataEvents( ::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::grpc::ServerWriter<OobDataBondMessage>* writer) override { return oob_events_.RunLoop(context, writer); } ::grpc::Status CreateBondLe(::grpc::ServerContext* context, const facade::BluetoothAddressWithType* request, ::google::protobuf::Empty* response) override { hci::Address peer; Loading Loading @@ -356,6 +372,39 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public return disconnect_events_.RunLoop(context, writer); } void OobDataEventOccurred(bluetooth::hci::CommandCompleteView packet) { LOG_INFO("Got OOB Data event"); ASSERT(packet.IsValid()); auto cc = bluetooth::hci::ReadLocalOobDataCompleteView::Create(packet); ASSERT(cc.IsValid()); OobDataBondMessage msg; OobDataMessage p192; // Just need this to satisfy the proto message bluetooth::hci::AddressWithType peer; *p192.mutable_address() = ToFacadeAddressWithType(peer); auto c = cc.GetC(); p192.set_confirmation_value(c.data(), c.size()); auto r = cc.GetR(); p192.set_random_value(r.data(), r.size()); // Only the Extended version returns 256 also. // The API has a parameter for both, so we set it // empty and the module and test suite will ignore it. OobDataMessage p256; *p256.mutable_address() = ToFacadeAddressWithType(peer); std::array<uint8_t, 16> empty_val; p256.set_confirmation_value(empty_val.data(), empty_val.size()); p256.set_random_value(empty_val.data(), empty_val.size()); *msg.mutable_address() = ToFacadeAddressWithType(peer); *msg.mutable_p192_data() = p192; *msg.mutable_p256_data() = p256; oob_events_.OnIncomingEvent(msg); } void DisconnectEventOccurred(bluetooth::hci::AddressWithType peer) { LOG_INFO("%s", peer.ToString().c_str()); DisconnectMsg msg; Loading Loading @@ -483,6 +532,7 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public ::bluetooth::grpc::GrpcEventQueue<EnforceSecurityPolicyMsg> enforce_security_policy_events_{ "Enforce Security Policy Events"}; ::bluetooth::grpc::GrpcEventQueue<DisconnectMsg> disconnect_events_{"Disconnect events"}; ::bluetooth::grpc::GrpcEventQueue<OobDataBondMessage> oob_events_{"OOB Data events"}; uint32_t unique_id{1}; std::map<uint32_t, common::OnceCallback<void(bool)>> user_yes_no_callbacks_; std::map<uint32_t, common::OnceCallback<void(uint32_t)>> user_passkey_callbacks_; Loading Loading
system/gd/cert/py_security.py +19 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ class PySecurity(Closable): _ui_event_stream = None _bond_event_stream = None _oob_data_event_stream = None def __init__(self, device): logging.debug("DUT: Init") Loading @@ -72,6 +73,8 @@ class PySecurity(Closable): self._enforce_security_policy_stream = EventStream( self._device.security.FetchEnforceSecurityPolicyEvents(empty_proto.Empty())) self._disconnect_event_stream = EventStream(self._device.security.FetchDisconnectEvents(empty_proto.Empty())) self._oob_data_event_stream = EventStream( self._device.security.FetchGetOutOfBandDataEvents(empty_proto.Empty())) def create_bond(self, address, type): """ Loading Loading @@ -253,8 +256,24 @@ class PySecurity(Closable): address=common.BluetoothAddressWithType(address=common.BluetoothAddress(address=address), type=type), policy=policy)) def get_oob_data_from_controller(self, oob_data_present): self._device.security.GetOutOfBandData(empty_proto.Empty()) oob_data = [] def get_oob_data(event): nonlocal oob_data oob_data = [ list(event.p192_data.confirmation_value), list(event.p192_data.random_value), [0 for i in range(0, 16)], [0 for i in range(0, 16)] ] return True assertThat(self._oob_data_event_stream).emits(get_oob_data) return oob_data def close(self): safeClose(self._ui_event_stream) safeClose(self._bond_event_stream) safeClose(self._enforce_security_policy_stream) safeClose(self._disconnect_event_stream) safeClose(self._oob_data_event_stream)
system/gd/security/cert/security_test.py +17 −5 Original line number Diff line number Diff line Loading @@ -357,7 +357,19 @@ class SecurityTest(GdBaseTestClass): self.dut_security.enable_secure_connections() self.cert_security.enable_secure_connections() def test_get_oob_data_from_controller_not_present(self): def test_get_oob_data_from_dut_controller_p192_present(self): oob_data = self.dut_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) assertThat(len(oob_data)).isEqualTo(4) has192C = not all([i == 0 for i in oob_data[0]]) has192R = not all([i == 0 for i in oob_data[1]]) has256C = not all([i == 0 for i in oob_data[2]]) has256R = not all([i == 0 for i in oob_data[3]]) assertThat(has192C).isTrue() assertThat(has192R).isTrue() assertThat(has256C).isFalse() assertThat(has256R).isFalse() def test_get_oob_data_from_cert_controller_not_present(self): oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.NOT_PRESENT) assertThat(len(oob_data)).isEqualTo(4) has192C = not all([i == 0 for i in oob_data[0]]) Loading @@ -369,7 +381,7 @@ class SecurityTest(GdBaseTestClass): assertThat(has256C).isFalse() assertThat(has256R).isFalse() def test_get_oob_data_from_controller_p192_present_no_secure_connections(self): def test_get_oob_data_from_cert_controller_p192_present_no_secure_connections(self): oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) assertThat(len(oob_data)).isEqualTo(4) has192C = not all([i == 0 for i in oob_data[0]]) Loading @@ -381,7 +393,7 @@ class SecurityTest(GdBaseTestClass): assertThat(has256C).isFalse() assertThat(has256R).isFalse() def test_get_oob_data_from_controller_p192_present(self): def test_get_oob_data_from_cert_controller_p192_present(self): self.cert_security.enable_secure_simple_pairing() self.cert_security.enable_secure_connections() oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_PRESENT) Loading @@ -395,7 +407,7 @@ class SecurityTest(GdBaseTestClass): assertThat(has256C).isFalse() assertThat(has256R).isFalse() def test_get_oob_data_from_controller_p256_present(self): def test_get_oob_data_from_cert_controller_p256_present(self): self.cert_security.enable_secure_simple_pairing() self.cert_security.enable_secure_connections() oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P256_PRESENT) Loading @@ -409,7 +421,7 @@ class SecurityTest(GdBaseTestClass): assertThat(has256C).isTrue() assertThat(has256R).isTrue() def test_get_oob_data_from_controller_p192_and_p256_present(self): def test_get_oob_data_from_cert_controller_p192_and_p256_present(self): self.cert_security.enable_secure_simple_pairing() self.cert_security.enable_secure_connections() oob_data = self.cert_security.get_oob_data_from_controller(OobDataPresent.P192_AND_256_PRESENT) Loading
system/gd/security/channel/security_manager_channel.cc +5 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,11 @@ void SecurityManagerChannel::SendCommand(std::unique_ptr<hci::SecurityCommandBui handler_->BindOnceOn(this, &SecurityManagerChannel::OnCommandComplete)); } void SecurityManagerChannel::SendCommand( std::unique_ptr<hci::SecurityCommandBuilder> command, SecurityCommandStatusCallback callback) { hci_security_interface_->EnqueueCommand(std::move(command), std::forward<SecurityCommandStatusCallback>(callback)); } void SecurityManagerChannel::OnHciEventReceived(hci::EventPacketView packet) { ASSERT_LOG(listener_ != nullptr, "No listener set!"); ASSERT(packet.IsValid()); Loading
system/gd/security/channel/security_manager_channel.h +11 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <unordered_map> #include <vector> #include "common/contextual_callback.h" #include "hci/address_with_type.h" #include "hci/hci_layer.h" #include "hci/hci_packets.h" Loading @@ -32,6 +33,8 @@ namespace bluetooth { namespace security { namespace channel { using SecurityCommandStatusCallback = common::ContextualOnceCallback<void(hci::CommandCompleteView)>; /** * Interface for listening to the channel for SMP commands. */ Loading Loading @@ -83,6 +86,14 @@ class SecurityManagerChannel : public l2cap::classic::LinkSecurityInterfaceListe */ void SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command); /** * Send a given SMP command over the SecurityManagerChannel * * @param command smp command to send * @param callback listener to call when command status complete */ void SendCommand(std::unique_ptr<hci::SecurityCommandBuilder> command, SecurityCommandStatusCallback callback); /** * Sets the listener to listen for channel events * Loading
system/gd/security/facade.cc +50 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,22 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public return ::grpc::Status::OK; } ::grpc::Status GetOutOfBandData( ::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::Empty* response) override { security_module_->GetSecurityManager()->GetOutOfBandData( security_handler_->BindOnceOn(this, &SecurityModuleFacadeService::OobDataEventOccurred)); return ::grpc::Status::OK; } ::grpc::Status FetchGetOutOfBandDataEvents( ::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::grpc::ServerWriter<OobDataBondMessage>* writer) override { return oob_events_.RunLoop(context, writer); } ::grpc::Status CreateBondLe(::grpc::ServerContext* context, const facade::BluetoothAddressWithType* request, ::google::protobuf::Empty* response) override { hci::Address peer; Loading Loading @@ -356,6 +372,39 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public return disconnect_events_.RunLoop(context, writer); } void OobDataEventOccurred(bluetooth::hci::CommandCompleteView packet) { LOG_INFO("Got OOB Data event"); ASSERT(packet.IsValid()); auto cc = bluetooth::hci::ReadLocalOobDataCompleteView::Create(packet); ASSERT(cc.IsValid()); OobDataBondMessage msg; OobDataMessage p192; // Just need this to satisfy the proto message bluetooth::hci::AddressWithType peer; *p192.mutable_address() = ToFacadeAddressWithType(peer); auto c = cc.GetC(); p192.set_confirmation_value(c.data(), c.size()); auto r = cc.GetR(); p192.set_random_value(r.data(), r.size()); // Only the Extended version returns 256 also. // The API has a parameter for both, so we set it // empty and the module and test suite will ignore it. OobDataMessage p256; *p256.mutable_address() = ToFacadeAddressWithType(peer); std::array<uint8_t, 16> empty_val; p256.set_confirmation_value(empty_val.data(), empty_val.size()); p256.set_random_value(empty_val.data(), empty_val.size()); *msg.mutable_address() = ToFacadeAddressWithType(peer); *msg.mutable_p192_data() = p192; *msg.mutable_p256_data() = p256; oob_events_.OnIncomingEvent(msg); } void DisconnectEventOccurred(bluetooth::hci::AddressWithType peer) { LOG_INFO("%s", peer.ToString().c_str()); DisconnectMsg msg; Loading Loading @@ -483,6 +532,7 @@ class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public ::bluetooth::grpc::GrpcEventQueue<EnforceSecurityPolicyMsg> enforce_security_policy_events_{ "Enforce Security Policy Events"}; ::bluetooth::grpc::GrpcEventQueue<DisconnectMsg> disconnect_events_{"Disconnect events"}; ::bluetooth::grpc::GrpcEventQueue<OobDataBondMessage> oob_events_{"OOB Data events"}; uint32_t unique_id{1}; std::map<uint32_t, common::OnceCallback<void(bool)>> user_yes_no_callbacks_; std::map<uint32_t, common::OnceCallback<void(uint32_t)>> user_passkey_callbacks_; Loading