| // |
| // Copyright (C) 2015 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 <string> |
| |
| #include <brillo/bind_lambda.h> |
| #include <dbus/mock_object_proxy.h> |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include "attestation/client/dbus_proxy.h" |
| |
| using testing::_; |
| using testing::Invoke; |
| using testing::StrictMock; |
| using testing::WithArgs; |
| |
| namespace attestation { |
| |
| class DBusProxyTest : public testing::Test { |
| public: |
| ~DBusProxyTest() override = default; |
| void SetUp() override { |
| mock_object_proxy_ = new StrictMock<dbus::MockObjectProxy>( |
| nullptr, "", dbus::ObjectPath("")); |
| proxy_.set_object_proxy(mock_object_proxy_.get()); |
| } |
| |
| protected: |
| scoped_refptr<StrictMock<dbus::MockObjectProxy>> mock_object_proxy_; |
| DBusProxy proxy_; |
| }; |
| |
| TEST_F(DBusProxyTest, CreateGoogleAttestedKey) { |
| auto fake_dbus_call = []( |
| dbus::MethodCall* method_call, |
| const dbus::MockObjectProxy::ResponseCallback& response_callback) { |
| // Verify request protobuf. |
| dbus::MessageReader reader(method_call); |
| CreateGoogleAttestedKeyRequest request_proto; |
| EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); |
| EXPECT_EQ("label", request_proto.key_label()); |
| EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type()); |
| EXPECT_EQ(KEY_USAGE_SIGN, request_proto.key_usage()); |
| EXPECT_EQ(ENTERPRISE_MACHINE_CERTIFICATE, |
| request_proto.certificate_profile()); |
| EXPECT_EQ("user", request_proto.username()); |
| EXPECT_EQ("origin", request_proto.origin()); |
| // Create reply protobuf. |
| auto response = dbus::Response::CreateEmpty(); |
| dbus::MessageWriter writer(response.get()); |
| CreateGoogleAttestedKeyReply reply_proto; |
| reply_proto.set_status(STATUS_SUCCESS); |
| reply_proto.set_certificate_chain("certificate"); |
| reply_proto.set_server_error("server_error"); |
| writer.AppendProtoAsArrayOfBytes(reply_proto); |
| response_callback.Run(response.release()); |
| }; |
| EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); |
| |
| // Set expectations on the outputs. |
| int callback_count = 0; |
| auto callback = [&callback_count](const CreateGoogleAttestedKeyReply& reply) { |
| callback_count++; |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| EXPECT_EQ("certificate", reply.certificate_chain()); |
| EXPECT_EQ("server_error", reply.server_error()); |
| }; |
| CreateGoogleAttestedKeyRequest request; |
| request.set_key_label("label"); |
| request.set_key_type(KEY_TYPE_ECC); |
| request.set_key_usage(KEY_USAGE_SIGN); |
| request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE); |
| request.set_username("user"); |
| request.set_origin("origin"); |
| proxy_.CreateGoogleAttestedKey(request, base::Bind(callback)); |
| EXPECT_EQ(1, callback_count); |
| } |
| |
| TEST_F(DBusProxyTest, GetKeyInfo) { |
| auto fake_dbus_call = []( |
| dbus::MethodCall* method_call, |
| const dbus::MockObjectProxy::ResponseCallback& response_callback) { |
| // Verify request protobuf. |
| dbus::MessageReader reader(method_call); |
| GetKeyInfoRequest request_proto; |
| EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); |
| EXPECT_EQ("label", request_proto.key_label()); |
| EXPECT_EQ("username", request_proto.username()); |
| // Create reply protobuf. |
| auto response = dbus::Response::CreateEmpty(); |
| dbus::MessageWriter writer(response.get()); |
| GetKeyInfoReply reply_proto; |
| reply_proto.set_status(STATUS_SUCCESS); |
| reply_proto.set_key_type(KEY_TYPE_ECC); |
| reply_proto.set_key_usage(KEY_USAGE_SIGN); |
| reply_proto.set_public_key("public_key"); |
| reply_proto.set_certify_info("certify_info"); |
| reply_proto.set_certify_info_signature("signature"); |
| reply_proto.set_certificate("certificate"); |
| writer.AppendProtoAsArrayOfBytes(reply_proto); |
| response_callback.Run(response.release()); |
| }; |
| EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); |
| |
| // Set expectations on the outputs. |
| int callback_count = 0; |
| auto callback = [&callback_count](const GetKeyInfoReply& reply) { |
| callback_count++; |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| EXPECT_EQ(KEY_TYPE_ECC, reply.key_type()); |
| EXPECT_EQ(KEY_USAGE_SIGN, reply.key_usage()); |
| EXPECT_EQ("public_key", reply.public_key()); |
| EXPECT_EQ("certify_info", reply.certify_info()); |
| EXPECT_EQ("signature", reply.certify_info_signature()); |
| EXPECT_EQ("certificate", reply.certificate()); |
| }; |
| GetKeyInfoRequest request; |
| request.set_key_label("label"); |
| request.set_username("username"); |
| proxy_.GetKeyInfo(request, base::Bind(callback)); |
| EXPECT_EQ(1, callback_count); |
| } |
| |
| TEST_F(DBusProxyTest, GetEndorsementInfo) { |
| auto fake_dbus_call = []( |
| dbus::MethodCall* method_call, |
| const dbus::MockObjectProxy::ResponseCallback& response_callback) { |
| // Verify request protobuf. |
| dbus::MessageReader reader(method_call); |
| GetEndorsementInfoRequest request_proto; |
| EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); |
| EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type()); |
| // Create reply protobuf. |
| auto response = dbus::Response::CreateEmpty(); |
| dbus::MessageWriter writer(response.get()); |
| GetEndorsementInfoReply reply_proto; |
| reply_proto.set_status(STATUS_SUCCESS); |
| reply_proto.set_ek_public_key("public_key"); |
| reply_proto.set_ek_certificate("certificate"); |
| writer.AppendProtoAsArrayOfBytes(reply_proto); |
| response_callback.Run(response.release()); |
| }; |
| EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); |
| |
| // Set expectations on the outputs. |
| int callback_count = 0; |
| auto callback = [&callback_count](const GetEndorsementInfoReply& reply) { |
| callback_count++; |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| EXPECT_EQ("public_key", reply.ek_public_key()); |
| EXPECT_EQ("certificate", reply.ek_certificate()); |
| }; |
| GetEndorsementInfoRequest request; |
| request.set_key_type(KEY_TYPE_ECC); |
| proxy_.GetEndorsementInfo(request, base::Bind(callback)); |
| EXPECT_EQ(1, callback_count); |
| } |
| |
| TEST_F(DBusProxyTest, GetAttestationKeyInfo) { |
| auto fake_dbus_call = []( |
| dbus::MethodCall* method_call, |
| const dbus::MockObjectProxy::ResponseCallback& response_callback) { |
| // Verify request protobuf. |
| dbus::MessageReader reader(method_call); |
| GetAttestationKeyInfoRequest request_proto; |
| EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); |
| EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type()); |
| // Create reply protobuf. |
| auto response = dbus::Response::CreateEmpty(); |
| dbus::MessageWriter writer(response.get()); |
| GetAttestationKeyInfoReply reply_proto; |
| reply_proto.set_status(STATUS_SUCCESS); |
| reply_proto.set_public_key("public_key"); |
| reply_proto.set_public_key_tpm_format("public_key_tpm_format"); |
| reply_proto.set_certificate("certificate"); |
| reply_proto.mutable_pcr0_quote()->set_quote("pcr0"); |
| reply_proto.mutable_pcr1_quote()->set_quote("pcr1"); |
| writer.AppendProtoAsArrayOfBytes(reply_proto); |
| response_callback.Run(response.release()); |
| }; |
| EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); |
| |
| // Set expectations on the outputs. |
| int callback_count = 0; |
| auto callback = [&callback_count](const GetAttestationKeyInfoReply& reply) { |
| callback_count++; |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| EXPECT_EQ("public_key", reply.public_key()); |
| EXPECT_EQ("public_key_tpm_format", reply.public_key_tpm_format()); |
| EXPECT_EQ("certificate", reply.certificate()); |
| EXPECT_EQ("pcr0", reply.pcr0_quote().quote()); |
| EXPECT_EQ("pcr1", reply.pcr1_quote().quote()); |
| }; |
| GetAttestationKeyInfoRequest request; |
| request.set_key_type(KEY_TYPE_ECC); |
| proxy_.GetAttestationKeyInfo(request, base::Bind(callback)); |
| EXPECT_EQ(1, callback_count); |
| } |
| |
| TEST_F(DBusProxyTest, ActivateAttestationKey) { |
| auto fake_dbus_call = []( |
| dbus::MethodCall* method_call, |
| const dbus::MockObjectProxy::ResponseCallback& response_callback) { |
| // Verify request protobuf. |
| dbus::MessageReader reader(method_call); |
| ActivateAttestationKeyRequest request_proto; |
| EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); |
| EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type()); |
| EXPECT_EQ("encrypted1", |
| request_proto.encrypted_certificate().asym_ca_contents()); |
| EXPECT_EQ("encrypted2", |
| request_proto.encrypted_certificate().sym_ca_attestation()); |
| EXPECT_TRUE(request_proto.save_certificate()); |
| // Create reply protobuf. |
| auto response = dbus::Response::CreateEmpty(); |
| dbus::MessageWriter writer(response.get()); |
| ActivateAttestationKeyReply reply_proto; |
| reply_proto.set_status(STATUS_SUCCESS); |
| reply_proto.set_certificate("certificate"); |
| writer.AppendProtoAsArrayOfBytes(reply_proto); |
| response_callback.Run(response.release()); |
| }; |
| EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); |
| |
| // Set expectations on the outputs. |
| int callback_count = 0; |
| auto callback = [&callback_count](const ActivateAttestationKeyReply& reply) { |
| callback_count++; |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| EXPECT_EQ("certificate", reply.certificate()); |
| }; |
| ActivateAttestationKeyRequest request; |
| request.set_key_type(KEY_TYPE_ECC); |
| request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1"); |
| request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2"); |
| request.set_save_certificate(true); |
| proxy_.ActivateAttestationKey(request, base::Bind(callback)); |
| EXPECT_EQ(1, callback_count); |
| } |
| |
| TEST_F(DBusProxyTest, CreateCertifiableKey) { |
| auto fake_dbus_call = []( |
| dbus::MethodCall* method_call, |
| const dbus::MockObjectProxy::ResponseCallback& response_callback) { |
| // Verify request protobuf. |
| dbus::MessageReader reader(method_call); |
| CreateCertifiableKeyRequest request_proto; |
| EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); |
| EXPECT_EQ("label", request_proto.key_label()); |
| EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type()); |
| EXPECT_EQ(KEY_USAGE_SIGN, request_proto.key_usage()); |
| EXPECT_EQ("user", request_proto.username()); |
| // Create reply protobuf. |
| auto response = dbus::Response::CreateEmpty(); |
| dbus::MessageWriter writer(response.get()); |
| CreateCertifiableKeyReply reply_proto; |
| reply_proto.set_status(STATUS_SUCCESS); |
| reply_proto.set_public_key("public_key"); |
| reply_proto.set_certify_info("certify_info"); |
| reply_proto.set_certify_info_signature("signature"); |
| writer.AppendProtoAsArrayOfBytes(reply_proto); |
| response_callback.Run(response.release()); |
| }; |
| EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); |
| |
| // Set expectations on the outputs. |
| int callback_count = 0; |
| auto callback = [&callback_count](const CreateCertifiableKeyReply& reply) { |
| callback_count++; |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| EXPECT_EQ("public_key", reply.public_key()); |
| EXPECT_EQ("certify_info", reply.certify_info()); |
| EXPECT_EQ("signature", reply.certify_info_signature()); |
| }; |
| CreateCertifiableKeyRequest request; |
| request.set_key_label("label"); |
| request.set_key_type(KEY_TYPE_ECC); |
| request.set_key_usage(KEY_USAGE_SIGN); |
| request.set_username("user"); |
| proxy_.CreateCertifiableKey(request, base::Bind(callback)); |
| EXPECT_EQ(1, callback_count); |
| } |
| |
| TEST_F(DBusProxyTest, Decrypt) { |
| auto fake_dbus_call = []( |
| dbus::MethodCall* method_call, |
| const dbus::MockObjectProxy::ResponseCallback& response_callback) { |
| // Verify request protobuf. |
| dbus::MessageReader reader(method_call); |
| DecryptRequest request_proto; |
| EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); |
| EXPECT_EQ("label", request_proto.key_label()); |
| EXPECT_EQ("user", request_proto.username()); |
| EXPECT_EQ("data", request_proto.encrypted_data()); |
| // Create reply protobuf. |
| scoped_ptr<dbus::Response> response = dbus::Response::CreateEmpty(); |
| dbus::MessageWriter writer(response.get()); |
| DecryptReply reply_proto; |
| reply_proto.set_status(STATUS_SUCCESS); |
| reply_proto.set_decrypted_data("data"); |
| writer.AppendProtoAsArrayOfBytes(reply_proto); |
| response_callback.Run(response.release()); |
| }; |
| EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); |
| |
| // Set expectations on the outputs. |
| int callback_count = 0; |
| auto callback = [&callback_count](const DecryptReply& reply) { |
| callback_count++; |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| EXPECT_EQ("data", reply.decrypted_data()); |
| }; |
| DecryptRequest request; |
| request.set_key_label("label"); |
| request.set_username("user"); |
| request.set_encrypted_data("data"); |
| proxy_.Decrypt(request, base::Bind(callback)); |
| EXPECT_EQ(1, callback_count); |
| } |
| |
| TEST_F(DBusProxyTest, Sign) { |
| auto fake_dbus_call = []( |
| dbus::MethodCall* method_call, |
| const dbus::MockObjectProxy::ResponseCallback& response_callback) { |
| // Verify request protobuf. |
| dbus::MessageReader reader(method_call); |
| SignRequest request_proto; |
| EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); |
| EXPECT_EQ("label", request_proto.key_label()); |
| EXPECT_EQ("user", request_proto.username()); |
| EXPECT_EQ("data", request_proto.data_to_sign()); |
| // Create reply protobuf. |
| auto response = dbus::Response::CreateEmpty(); |
| dbus::MessageWriter writer(response.get()); |
| SignReply reply_proto; |
| reply_proto.set_status(STATUS_SUCCESS); |
| reply_proto.set_signature("signature"); |
| writer.AppendProtoAsArrayOfBytes(reply_proto); |
| response_callback.Run(response.release()); |
| }; |
| EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); |
| |
| // Set expectations on the outputs. |
| int callback_count = 0; |
| auto callback = [&callback_count](const SignReply& reply) { |
| callback_count++; |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| EXPECT_EQ("signature", reply.signature()); |
| }; |
| SignRequest request; |
| request.set_key_label("label"); |
| request.set_username("user"); |
| request.set_data_to_sign("data"); |
| proxy_.Sign(request, base::Bind(callback)); |
| EXPECT_EQ(1, callback_count); |
| } |
| |
| TEST_F(DBusProxyTest, RegisterKeyWithChapsToken) { |
| auto fake_dbus_call = []( |
| dbus::MethodCall* method_call, |
| const dbus::MockObjectProxy::ResponseCallback& response_callback) { |
| // Verify request protobuf. |
| dbus::MessageReader reader(method_call); |
| RegisterKeyWithChapsTokenRequest request_proto; |
| EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); |
| EXPECT_EQ("label", request_proto.key_label()); |
| EXPECT_EQ("user", request_proto.username()); |
| // Create reply protobuf. |
| auto response = dbus::Response::CreateEmpty(); |
| dbus::MessageWriter writer(response.get()); |
| RegisterKeyWithChapsTokenReply reply_proto; |
| reply_proto.set_status(STATUS_SUCCESS); |
| writer.AppendProtoAsArrayOfBytes(reply_proto); |
| response_callback.Run(response.release()); |
| }; |
| EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) |
| .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); |
| |
| // Set expectations on the outputs. |
| int callback_count = 0; |
| auto callback = |
| [&callback_count](const RegisterKeyWithChapsTokenReply& reply) { |
| callback_count++; |
| EXPECT_EQ(STATUS_SUCCESS, reply.status()); |
| }; |
| RegisterKeyWithChapsTokenRequest request; |
| request.set_key_label("label"); |
| request.set_username("user"); |
| proxy_.RegisterKeyWithChapsToken(request, base::Bind(callback)); |
| EXPECT_EQ(1, callback_count); |
| } |
| |
| } // namespace attestation |