summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUtkarsh Sanghi <usanghi@google.com>2015-10-01 10:45:24 -0700
committerUtkarsh Sanghi <usanghi@google.com>2015-10-06 10:39:03 -0700
commit98ad76f641c31a4e3ca99a6c2631305d53013484 (patch)
tree4c7e35f3a9c66c94f6f0fb52413cf1f306a950f3
parentc1871b10f64f774fc7c6364e3f5a6edb12b251f1 (diff)
downloadtpm-98ad76f641c31a4e3ca99a6c2631305d53013484.tar.gz
tpm_manager: Expose server side NVRAM API
This CL adds the server side implementation of the NVRAM api to receive and process NVRAM methods on the server side Bug: 24059574 TEST=FEATURES=test emerge-link tpm_manager Change-Id: Id248c17f21adcb17d2142aa18738635df90f592e
-rw-r--r--common/tpm_manager_interface.h1
-rw-r--r--server/dbus_service.cc111
-rw-r--r--server/dbus_service.h28
-rw-r--r--server/dbus_service_test.cc202
4 files changed, 275 insertions, 67 deletions
diff --git a/common/tpm_manager_interface.h b/common/tpm_manager_interface.h
index 967f2a2..f16ec93 100644
--- a/common/tpm_manager_interface.h
+++ b/common/tpm_manager_interface.h
@@ -26,6 +26,7 @@ namespace tpm_manager {
// This is the main TpmManager interface that is implemented by the proxies
// and services.
+// TODO(usanghi): Break up the DBus interface (b/24659038).
class TPM_MANAGER_EXPORT TpmManagerInterface {
public:
virtual ~TpmManagerInterface() = default;
diff --git a/server/dbus_service.cc b/server/dbus_service.cc
index e2b6d4a..2520232 100644
--- a/server/dbus_service.cc
+++ b/server/dbus_service.cc
@@ -25,8 +25,6 @@
#include "tpm_manager/common/dbus_interface.h"
-using chromeos::dbus_utils::DBusMethodResponse;
-
namespace tpm_manager {
DBusService::DBusService(const scoped_refptr<dbus::Bus>& bus,
@@ -38,43 +36,98 @@ void DBusService::Register(const CompletionAction& callback) {
chromeos::dbus_utils::DBusInterface* dbus_interface =
dbus_object_.AddOrGetInterface(kTpmManagerInterface);
- dbus_interface->AddMethodHandler(kGetTpmStatus, base::Unretained(this),
- &DBusService::HandleGetTpmStatus);
- dbus_interface->AddMethodHandler(kTakeOwnership, base::Unretained(this),
- &DBusService::HandleTakeOwnership);
- dbus_object_.RegisterAsync(callback);
-}
+ dbus_interface->AddMethodHandler(
+ kGetTpmStatus,
+ base::Unretained(this),
+ &DBusService::HandleDBusMethod<
+ GetTpmStatusRequest,
+ GetTpmStatusReply,
+ &TpmManagerInterface::GetTpmStatus>);
-void DBusService::HandleGetTpmStatus(
- std::unique_ptr<DBusMethodResponse<const GetTpmStatusReply&>> response,
- const GetTpmStatusRequest& request) {
- // Convert |response| to a shared_ptr so |service_| can safely copy the
- // callback.
- using SharedResponsePointer = std::shared_ptr<
- DBusMethodResponse<const GetTpmStatusReply&>>;
- // A callback that sends off the reply protobuf.
- auto callback = [](const SharedResponsePointer& response,
- const GetTpmStatusReply& reply) {
- response->Return(reply);
- };
- service_->GetTpmStatus(
- request,
- base::Bind(callback, SharedResponsePointer(std::move(response))));
+ dbus_interface->AddMethodHandler(
+ kTakeOwnership,
+ base::Unretained(this),
+ &DBusService::HandleDBusMethod<
+ TakeOwnershipRequest,
+ TakeOwnershipReply,
+ &TpmManagerInterface::TakeOwnership>);
+
+ dbus_interface->AddMethodHandler(
+ kDefineNvram,
+ base::Unretained(this),
+ &DBusService::HandleDBusMethod<
+ DefineNvramRequest,
+ DefineNvramReply,
+ &TpmManagerInterface::DefineNvram>);
+
+ dbus_interface->AddMethodHandler(
+ kDestroyNvram,
+ base::Unretained(this),
+ &DBusService::HandleDBusMethod<
+ DestroyNvramRequest,
+ DestroyNvramReply,
+ &TpmManagerInterface::DestroyNvram>);
+
+ dbus_interface->AddMethodHandler(
+ kWriteNvram,
+ base::Unretained(this),
+ &DBusService::HandleDBusMethod<
+ WriteNvramRequest,
+ WriteNvramReply,
+ &TpmManagerInterface::WriteNvram>);
+
+ dbus_interface->AddMethodHandler(
+ kReadNvram,
+ base::Unretained(this),
+ &DBusService::HandleDBusMethod<
+ ReadNvramRequest,
+ ReadNvramReply,
+ &TpmManagerInterface::ReadNvram>);
+
+ dbus_interface->AddMethodHandler(
+ kIsNvramDefined,
+ base::Unretained(this),
+ &DBusService::HandleDBusMethod<
+ IsNvramDefinedRequest,
+ IsNvramDefinedReply,
+ &TpmManagerInterface::IsNvramDefined>);
+
+ dbus_interface->AddMethodHandler(
+ kIsNvramLocked,
+ base::Unretained(this),
+ &DBusService::HandleDBusMethod<
+ IsNvramLockedRequest,
+ IsNvramLockedReply,
+ &TpmManagerInterface::IsNvramLocked>);
+
+ dbus_interface->AddMethodHandler(
+ kGetNvramSize,
+ base::Unretained(this),
+ &DBusService::HandleDBusMethod<
+ GetNvramSizeRequest,
+ GetNvramSizeReply,
+ &TpmManagerInterface::GetNvramSize>);
+
+ dbus_object_.RegisterAsync(callback);
}
-void DBusService::HandleTakeOwnership(
- std::unique_ptr<DBusMethodResponse<const TakeOwnershipReply&>> response,
- const TakeOwnershipRequest& request) {
+template<typename RequestProtobufType,
+ typename ReplyProtobufType,
+ DBusService::HandlerFunction<RequestProtobufType,
+ ReplyProtobufType> func>
+void DBusService::HandleDBusMethod(
+ std::unique_ptr<DBusMethodResponse<const ReplyProtobufType&>> response,
+ const RequestProtobufType& request) {
// Convert |response| to a shared_ptr so |service_| can safely copy the
// callback.
using SharedResponsePointer = std::shared_ptr<
- DBusMethodResponse<const TakeOwnershipReply&>>;
+ DBusMethodResponse<const ReplyProtobufType&>>;
// A callback that sends off the reply protobuf.
auto callback = [](const SharedResponsePointer& response,
- const TakeOwnershipReply& reply) {
+ const ReplyProtobufType& reply) {
response->Return(reply);
};
- service_->TakeOwnership(
+ (service_->*func)(
request,
base::Bind(callback, SharedResponsePointer(std::move(response))));
}
diff --git a/server/dbus_service.h b/server/dbus_service.h
index fb15fab..61d6219 100644
--- a/server/dbus_service.h
+++ b/server/dbus_service.h
@@ -27,6 +27,7 @@
namespace tpm_manager {
+using chromeos::dbus_utils::DBusMethodResponse;
using CompletionAction =
chromeos::dbus_utils::AsyncEventSequencer::CompletionAction;
@@ -42,24 +43,23 @@ class DBusService {
// Connects to D-Bus system bus and exports TpmManager methods.
void Register(const CompletionAction& callback);
- void set_service(TpmManagerInterface* service) {
- service_ = service;
- }
-
private:
friend class DBusServiceTest;
- // Handles the GetTpmStatus D-Bus call.
- void HandleGetTpmStatus(
- std::unique_ptr<chromeos::dbus_utils::DBusMethodResponse<
- const GetTpmStatusReply&>> response,
- const GetTpmStatusRequest& request);
+ template<typename RequestProtobufType,
+ typename ReplyProtobufType>
+ using HandlerFunction = void(TpmManagerInterface::*)(
+ const RequestProtobufType&,
+ const base::Callback<void(const ReplyProtobufType&)>&);
- // Handles the TakeOwnership D-Bus call.
- void HandleTakeOwnership(
- std::unique_ptr<chromeos::dbus_utils::DBusMethodResponse<
- const TakeOwnershipReply&>> response,
- const TakeOwnershipRequest& request);
+ // Template to handle D-Bus calls.
+ template<typename RequestProtobufType,
+ typename ReplyProtobufType,
+ DBusService::HandlerFunction<RequestProtobufType,
+ ReplyProtobufType> func>
+ void HandleDBusMethod(
+ std::unique_ptr<DBusMethodResponse<const ReplyProtobufType&>> response,
+ const RequestProtobufType& request);
chromeos::dbus_utils::DBusObject dbus_object_;
TpmManagerInterface* service_;
diff --git a/server/dbus_service_test.cc b/server/dbus_service_test.cc
index 058e968..1c41056 100644
--- a/server/dbus_service_test.cc
+++ b/server/dbus_service_test.cc
@@ -52,6 +52,19 @@ class DBusServiceTest : public testing::Test {
GetDefaultCompletionAction());
}
+ template<typename RequestProtobufType, typename ReplyProtobufType>
+ void ExecuteMethod(const std::string& method_name,
+ const RequestProtobufType& request,
+ ReplyProtobufType* reply) {
+ std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(method_name);
+ dbus::MessageWriter writer(call.get());
+ writer.AppendProtoAsArrayOfBytes(request);
+ auto response = CallMethod(call.get());
+ dbus::MessageReader reader(response.get());
+ EXPECT_TRUE(reader.PopArrayOfBytesAsProto(reply));
+ }
+
+ protected:
std::unique_ptr<dbus::Response> CallMethod(dbus::MethodCall* method_call) {
return chromeos::dbus_utils::testing::CallMethod(
dbus_service_->dbus_object_, method_call);
@@ -65,7 +78,6 @@ class DBusServiceTest : public testing::Test {
return call;
}
- protected:
scoped_refptr<dbus::MockBus> mock_bus_;
scoped_refptr<dbus::MockExportedObject> mock_exported_object_;
StrictMock<MockTpmManagerInterface> mock_service_;
@@ -81,14 +93,9 @@ TEST_F(DBusServiceTest, CopyableCallback) {
base::Closure copy = base::Bind(callback, reply);
callback.Run(reply);
})));
- std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kGetTpmStatus);
GetTpmStatusRequest request;
- dbus::MessageWriter writer(call.get());
- writer.AppendProtoAsArrayOfBytes(request);
- auto response = CallMethod(call.get());
- dbus::MessageReader reader(response.get());
GetTpmStatusReply reply;
- EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
+ ExecuteMethod(kGetTpmStatus, request, &reply);
}
TEST_F(DBusServiceTest, GetTpmStatus) {
@@ -98,7 +105,7 @@ TEST_F(DBusServiceTest, GetTpmStatus) {
const GetTpmStatusRequest& request,
const TpmManagerInterface::GetTpmStatusCallback& callback) {
GetTpmStatusReply reply;
- reply.set_status(STATUS_NOT_AVAILABLE);
+ reply.set_status(STATUS_SUCCESS);
reply.set_enabled(true);
reply.set_owned(true);
reply.mutable_local_data()->set_owned_by_this_install(true);
@@ -108,14 +115,9 @@ TEST_F(DBusServiceTest, GetTpmStatus) {
reply.set_dictionary_attack_lockout_seconds_remaining(5);
callback.Run(reply);
}));
- std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kGetTpmStatus);
- dbus::MessageWriter writer(call.get());
- writer.AppendProtoAsArrayOfBytes(request);
- auto response = CallMethod(call.get());
- dbus::MessageReader reader(response.get());
GetTpmStatusReply reply;
- EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
- EXPECT_EQ(STATUS_NOT_AVAILABLE, reply.status());
+ ExecuteMethod(kGetTpmStatus, request, &reply);
+ EXPECT_EQ(STATUS_SUCCESS, reply.status());
EXPECT_TRUE(reply.enabled());
EXPECT_TRUE(reply.owned());
EXPECT_TRUE(reply.local_data().owned_by_this_install());
@@ -126,23 +128,175 @@ TEST_F(DBusServiceTest, GetTpmStatus) {
}
TEST_F(DBusServiceTest, TakeOwnership) {
- TakeOwnershipRequest request;
EXPECT_CALL(mock_service_, TakeOwnership(_, _))
.WillOnce(Invoke([](
const TakeOwnershipRequest& request,
const TpmManagerInterface::TakeOwnershipCallback& callback) {
TakeOwnershipReply reply;
- reply.set_status(STATUS_NOT_AVAILABLE);
+ reply.set_status(STATUS_SUCCESS);
callback.Run(reply);
}));
- std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kTakeOwnership);
- dbus::MessageWriter writer(call.get());
- writer.AppendProtoAsArrayOfBytes(request);
- auto response = CallMethod(call.get());
- dbus::MessageReader reader(response.get());
+ TakeOwnershipRequest request;
TakeOwnershipReply reply;
- EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply));
- EXPECT_EQ(STATUS_NOT_AVAILABLE, reply.status());
+ ExecuteMethod(kTakeOwnership, request, &reply);
+ EXPECT_EQ(STATUS_SUCCESS, reply.status());
+}
+
+TEST_F(DBusServiceTest, DefineNvram) {
+ uint32_t nvram_index = 5;
+ size_t nvram_length = 32;
+ DefineNvramRequest request;
+ request.set_index(nvram_index);
+ request.set_length(nvram_length);
+ EXPECT_CALL(mock_service_, DefineNvram(_, _))
+ .WillOnce(Invoke([nvram_index, nvram_length](
+ const DefineNvramRequest& request,
+ const TpmManagerInterface::DefineNvramCallback& callback) {
+ EXPECT_TRUE(request.has_index());
+ EXPECT_EQ(nvram_index, request.index());
+ EXPECT_TRUE(request.has_length());
+ EXPECT_EQ(nvram_length, request.length());
+ DefineNvramReply reply;
+ reply.set_status(STATUS_SUCCESS);
+ callback.Run(reply);
+ }));
+ DefineNvramReply reply;
+ ExecuteMethod(kDefineNvram, request, &reply);
+ EXPECT_EQ(STATUS_SUCCESS, reply.status());
+}
+
+TEST_F(DBusServiceTest, DestroyNvram) {
+ uint32_t nvram_index = 5;
+ DestroyNvramRequest request;
+ request.set_index(nvram_index);
+ EXPECT_CALL(mock_service_, DestroyNvram(_, _))
+ .WillOnce(Invoke([nvram_index](
+ const DestroyNvramRequest& request,
+ const TpmManagerInterface::DestroyNvramCallback& callback) {
+ EXPECT_TRUE(request.has_index());
+ EXPECT_EQ(nvram_index, request.index());
+ DestroyNvramReply reply;
+ reply.set_status(STATUS_SUCCESS);
+ callback.Run(reply);
+ }));
+ DestroyNvramReply reply;
+ ExecuteMethod(kDestroyNvram, request, &reply);
+ EXPECT_EQ(STATUS_SUCCESS, reply.status());
+}
+
+TEST_F(DBusServiceTest, WriteNvram) {
+ uint32_t nvram_index = 5;
+ std::string nvram_data("nvram_data");
+ WriteNvramRequest request;
+ request.set_index(nvram_index);
+ request.set_data(nvram_data);
+ EXPECT_CALL(mock_service_, WriteNvram(_, _))
+ .WillOnce(Invoke([nvram_index, nvram_data](
+ const WriteNvramRequest& request,
+ const TpmManagerInterface::WriteNvramCallback& callback) {
+ EXPECT_TRUE(request.has_index());
+ EXPECT_EQ(nvram_index, request.index());
+ EXPECT_TRUE(request.has_data());
+ EXPECT_EQ(nvram_data, request.data());
+ WriteNvramReply reply;
+ reply.set_status(STATUS_SUCCESS);
+ callback.Run(reply);
+ }));
+ WriteNvramReply reply;
+ ExecuteMethod(kWriteNvram, request, &reply);
+ EXPECT_EQ(STATUS_SUCCESS, reply.status());
+}
+
+TEST_F(DBusServiceTest, ReadNvram) {
+ uint32_t nvram_index = 5;
+ std::string nvram_data("nvram_data");
+ ReadNvramRequest request;
+ request.set_index(nvram_index);
+ EXPECT_CALL(mock_service_, ReadNvram(_, _))
+ .WillOnce(Invoke([nvram_index, nvram_data](
+ const ReadNvramRequest& request,
+ const TpmManagerInterface::ReadNvramCallback& callback) {
+ EXPECT_TRUE(request.has_index());
+ EXPECT_EQ(nvram_index, request.index());
+ ReadNvramReply reply;
+ reply.set_status(STATUS_SUCCESS);
+ reply.set_data(nvram_data);
+ callback.Run(reply);
+ }));
+ ReadNvramReply reply;
+ ExecuteMethod(kReadNvram, request, &reply);
+ EXPECT_EQ(STATUS_SUCCESS, reply.status());
+ EXPECT_TRUE(reply.has_data());
+ EXPECT_EQ(nvram_data, reply.data());
+}
+
+TEST_F(DBusServiceTest, IsNvramDefined) {
+ uint32_t nvram_index = 5;
+ bool nvram_defined = true;
+ IsNvramDefinedRequest request;
+ request.set_index(nvram_index);
+ EXPECT_CALL(mock_service_, IsNvramDefined(_, _))
+ .WillOnce(Invoke([nvram_index, nvram_defined](
+ const IsNvramDefinedRequest& request,
+ const TpmManagerInterface::IsNvramDefinedCallback& callback) {
+ EXPECT_TRUE(request.has_index());
+ EXPECT_EQ(nvram_index, request.index());
+ IsNvramDefinedReply reply;
+ reply.set_status(STATUS_SUCCESS);
+ reply.set_is_defined(nvram_defined);
+ callback.Run(reply);
+ }));
+ IsNvramDefinedReply reply;
+ ExecuteMethod(kIsNvramDefined, request, &reply);
+ EXPECT_EQ(STATUS_SUCCESS, reply.status());
+ EXPECT_TRUE(reply.has_is_defined());
+ EXPECT_EQ(nvram_defined, reply.is_defined());
+}
+
+TEST_F(DBusServiceTest, IsNvramLocked) {
+ uint32_t nvram_index = 5;
+ bool nvram_locked = true;
+ IsNvramLockedRequest request;
+ request.set_index(nvram_index);
+ EXPECT_CALL(mock_service_, IsNvramLocked(_, _))
+ .WillOnce(Invoke([nvram_index, nvram_locked](
+ const IsNvramLockedRequest& request,
+ const TpmManagerInterface::IsNvramLockedCallback& callback) {
+ EXPECT_TRUE(request.has_index());
+ EXPECT_EQ(nvram_index, request.index());
+ IsNvramLockedReply reply;
+ reply.set_status(STATUS_SUCCESS);
+ reply.set_is_locked(nvram_locked);
+ callback.Run(reply);
+ }));
+ IsNvramLockedReply reply;
+ ExecuteMethod(kIsNvramLocked, request, &reply);
+ EXPECT_EQ(STATUS_SUCCESS, reply.status());
+ EXPECT_TRUE(reply.has_is_locked());
+ EXPECT_EQ(nvram_locked, reply.is_locked());
+}
+
+TEST_F(DBusServiceTest, GetNvramSize) {
+ uint32_t nvram_index = 5;
+ size_t nvram_size = 32;
+ GetNvramSizeRequest request;
+ request.set_index(nvram_index);
+ EXPECT_CALL(mock_service_, GetNvramSize(_, _))
+ .WillOnce(Invoke([nvram_index, nvram_size](
+ const GetNvramSizeRequest& request,
+ const TpmManagerInterface::GetNvramSizeCallback& callback) {
+ EXPECT_TRUE(request.has_index());
+ EXPECT_EQ(nvram_index, request.index());
+ GetNvramSizeReply reply;
+ reply.set_status(STATUS_SUCCESS);
+ reply.set_size(nvram_size);
+ callback.Run(reply);
+ }));
+ GetNvramSizeReply reply;
+ ExecuteMethod(kGetNvramSize, request, &reply);
+ EXPECT_EQ(STATUS_SUCCESS, reply.status());
+ EXPECT_TRUE(reply.has_size());
+ EXPECT_EQ(nvram_size, reply.size());
}
} // namespace tpm_manager