1// 2// Copyright (C) 2014 The Android Open Source Project 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include <string> 18 19#include <brillo/bind_lambda.h> 20#include <brillo/dbus/dbus_object_test_helpers.h> 21#include <dbus/mock_bus.h> 22#include <dbus/mock_exported_object.h> 23#include <gmock/gmock.h> 24#include <gtest/gtest.h> 25 26#include "attestation/common/dbus_interface.h" 27#include "attestation/common/mock_attestation_interface.h" 28#include "attestation/server/dbus_service.h" 29 30using testing::_; 31using testing::Invoke; 32using testing::NiceMock; 33using testing::Return; 34using testing::StrictMock; 35using testing::WithArgs; 36 37namespace attestation { 38 39class DBusServiceTest : public testing::Test { 40 public: 41 ~DBusServiceTest() override = default; 42 void SetUp() override { 43 dbus::Bus::Options options; 44 mock_bus_ = new NiceMock<dbus::MockBus>(options); 45 dbus::ObjectPath path(kAttestationServicePath); 46 mock_exported_object_ = 47 new NiceMock<dbus::MockExportedObject>(mock_bus_.get(), path); 48 ON_CALL(*mock_bus_, GetExportedObject(path)) 49 .WillByDefault(Return(mock_exported_object_.get())); 50 dbus_service_.reset(new DBusService(mock_bus_, &mock_service_)); 51 dbus_service_->Register( 52 brillo::dbus_utils::AsyncEventSequencer::GetDefaultCompletionAction()); 53 } 54 55 std::unique_ptr<dbus::Response> CallMethod(dbus::MethodCall* method_call) { 56 return brillo::dbus_utils::testing::CallMethod(dbus_service_->dbus_object_, 57 method_call); 58 } 59 60 std::unique_ptr<dbus::MethodCall> CreateMethodCall( 61 const std::string& method_name) { 62 std::unique_ptr<dbus::MethodCall> call( 63 new dbus::MethodCall(kAttestationInterface, method_name)); 64 call->SetSerial(1); 65 return call; 66 } 67 68 protected: 69 scoped_refptr<dbus::MockBus> mock_bus_; 70 scoped_refptr<dbus::MockExportedObject> mock_exported_object_; 71 StrictMock<MockAttestationInterface> mock_service_; 72 std::unique_ptr<DBusService> dbus_service_; 73}; 74 75TEST_F(DBusServiceTest, CreateGoogleAttestedKey) { 76 CreateGoogleAttestedKeyRequest request; 77 request.set_key_label("label"); 78 request.set_key_type(KEY_TYPE_ECC); 79 request.set_key_usage(KEY_USAGE_SIGN); 80 request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE); 81 request.set_username("username"); 82 request.set_origin("origin"); 83 EXPECT_CALL(mock_service_, CreateGoogleAttestedKey(_, _)) 84 .WillOnce( 85 Invoke([](const CreateGoogleAttestedKeyRequest& request, 86 const AttestationInterface::CreateGoogleAttestedKeyCallback& 87 callback) { 88 EXPECT_EQ("label", request.key_label()); 89 EXPECT_EQ(KEY_TYPE_ECC, request.key_type()); 90 EXPECT_EQ(KEY_USAGE_SIGN, request.key_usage()); 91 EXPECT_EQ(ENTERPRISE_MACHINE_CERTIFICATE, 92 request.certificate_profile()); 93 EXPECT_EQ("username", request.username()); 94 EXPECT_EQ("origin", request.origin()); 95 CreateGoogleAttestedKeyReply reply; 96 reply.set_status(STATUS_SUCCESS); 97 reply.set_certificate_chain("certificate"); 98 reply.set_server_error("server_error"); 99 callback.Run(reply); 100 })); 101 std::unique_ptr<dbus::MethodCall> call = 102 CreateMethodCall(kCreateGoogleAttestedKey); 103 dbus::MessageWriter writer(call.get()); 104 writer.AppendProtoAsArrayOfBytes(request); 105 auto response = CallMethod(call.get()); 106 dbus::MessageReader reader(response.get()); 107 CreateGoogleAttestedKeyReply reply; 108 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 109 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 110 EXPECT_EQ("certificate", reply.certificate_chain()); 111 EXPECT_EQ("server_error", reply.server_error()); 112} 113 114TEST_F(DBusServiceTest, CopyableCallback) { 115 EXPECT_CALL(mock_service_, CreateGoogleAttestedKey(_, _)) 116 .WillOnce(WithArgs<1>( 117 Invoke([](const AttestationInterface::CreateGoogleAttestedKeyCallback& 118 callback) { 119 // Copy the callback, then call the original. 120 CreateGoogleAttestedKeyReply reply; 121 base::Closure copy = base::Bind(callback, reply); 122 callback.Run(reply); 123 }))); 124 std::unique_ptr<dbus::MethodCall> call = 125 CreateMethodCall(kCreateGoogleAttestedKey); 126 CreateGoogleAttestedKeyRequest request; 127 dbus::MessageWriter writer(call.get()); 128 writer.AppendProtoAsArrayOfBytes(request); 129 auto response = CallMethod(call.get()); 130 dbus::MessageReader reader(response.get()); 131 CreateGoogleAttestedKeyReply reply; 132 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 133} 134 135TEST_F(DBusServiceTest, GetKeyInfo) { 136 GetKeyInfoRequest request; 137 request.set_key_label("label"); 138 request.set_username("username"); 139 EXPECT_CALL(mock_service_, GetKeyInfo(_, _)) 140 .WillOnce( 141 Invoke([](const GetKeyInfoRequest& request, 142 const AttestationInterface::GetKeyInfoCallback& callback) { 143 EXPECT_EQ("label", request.key_label()); 144 EXPECT_EQ("username", request.username()); 145 GetKeyInfoReply reply; 146 reply.set_status(STATUS_SUCCESS); 147 reply.set_key_type(KEY_TYPE_ECC); 148 reply.set_key_usage(KEY_USAGE_SIGN); 149 reply.set_public_key("public_key"); 150 reply.set_certify_info("certify"); 151 reply.set_certify_info_signature("signature"); 152 reply.set_certificate("certificate"); 153 callback.Run(reply); 154 })); 155 std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kGetKeyInfo); 156 dbus::MessageWriter writer(call.get()); 157 writer.AppendProtoAsArrayOfBytes(request); 158 auto response = CallMethod(call.get()); 159 dbus::MessageReader reader(response.get()); 160 GetKeyInfoReply reply; 161 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 162 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 163 EXPECT_EQ(KEY_TYPE_ECC, reply.key_type()); 164 EXPECT_EQ(KEY_USAGE_SIGN, reply.key_usage()); 165 EXPECT_EQ("public_key", reply.public_key()); 166 EXPECT_EQ("certify", reply.certify_info()); 167 EXPECT_EQ("signature", reply.certify_info_signature()); 168 EXPECT_EQ("certificate", reply.certificate()); 169} 170 171TEST_F(DBusServiceTest, GetEndorsementInfo) { 172 GetEndorsementInfoRequest request; 173 request.set_key_type(KEY_TYPE_ECC); 174 EXPECT_CALL(mock_service_, GetEndorsementInfo(_, _)) 175 .WillOnce(Invoke( 176 [](const GetEndorsementInfoRequest& request, 177 const AttestationInterface::GetEndorsementInfoCallback& callback) { 178 EXPECT_EQ(KEY_TYPE_ECC, request.key_type()); 179 GetEndorsementInfoReply reply; 180 reply.set_status(STATUS_SUCCESS); 181 reply.set_ek_public_key("public_key"); 182 reply.set_ek_certificate("certificate"); 183 callback.Run(reply); 184 })); 185 std::unique_ptr<dbus::MethodCall> call = 186 CreateMethodCall(kGetEndorsementInfo); 187 dbus::MessageWriter writer(call.get()); 188 writer.AppendProtoAsArrayOfBytes(request); 189 auto response = CallMethod(call.get()); 190 dbus::MessageReader reader(response.get()); 191 GetEndorsementInfoReply reply; 192 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 193 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 194 EXPECT_EQ("public_key", reply.ek_public_key()); 195 EXPECT_EQ("certificate", reply.ek_certificate()); 196} 197 198TEST_F(DBusServiceTest, GetAttestationKeyInfo) { 199 GetAttestationKeyInfoRequest request; 200 request.set_key_type(KEY_TYPE_ECC); 201 EXPECT_CALL(mock_service_, GetAttestationKeyInfo(_, _)) 202 .WillOnce(Invoke([]( 203 const GetAttestationKeyInfoRequest& request, 204 const AttestationInterface::GetAttestationKeyInfoCallback& callback) { 205 EXPECT_EQ(KEY_TYPE_ECC, request.key_type()); 206 GetAttestationKeyInfoReply reply; 207 reply.set_status(STATUS_SUCCESS); 208 reply.set_public_key("public_key"); 209 reply.set_public_key_tpm_format("public_key_tpm_format"); 210 reply.set_certificate("certificate"); 211 reply.mutable_pcr0_quote()->set_quote("pcr0"); 212 reply.mutable_pcr1_quote()->set_quote("pcr1"); 213 callback.Run(reply); 214 })); 215 std::unique_ptr<dbus::MethodCall> call = 216 CreateMethodCall(kGetAttestationKeyInfo); 217 dbus::MessageWriter writer(call.get()); 218 writer.AppendProtoAsArrayOfBytes(request); 219 auto response = CallMethod(call.get()); 220 dbus::MessageReader reader(response.get()); 221 GetAttestationKeyInfoReply reply; 222 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 223 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 224 EXPECT_EQ("public_key", reply.public_key()); 225 EXPECT_EQ("public_key_tpm_format", reply.public_key_tpm_format()); 226 EXPECT_EQ("certificate", reply.certificate()); 227 EXPECT_EQ("pcr0", reply.pcr0_quote().quote()); 228 EXPECT_EQ("pcr1", reply.pcr1_quote().quote()); 229} 230 231TEST_F(DBusServiceTest, ActivateAttestationKey) { 232 ActivateAttestationKeyRequest request; 233 request.set_key_type(KEY_TYPE_ECC); 234 request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1"); 235 request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2"); 236 request.set_save_certificate(true); 237 EXPECT_CALL(mock_service_, ActivateAttestationKey(_, _)) 238 .WillOnce( 239 Invoke([](const ActivateAttestationKeyRequest& request, 240 const AttestationInterface::ActivateAttestationKeyCallback& 241 callback) { 242 EXPECT_EQ(KEY_TYPE_ECC, request.key_type()); 243 EXPECT_EQ("encrypted1", 244 request.encrypted_certificate().asym_ca_contents()); 245 EXPECT_EQ("encrypted2", 246 request.encrypted_certificate().sym_ca_attestation()); 247 EXPECT_TRUE(request.save_certificate()); 248 ActivateAttestationKeyReply reply; 249 reply.set_status(STATUS_SUCCESS); 250 reply.set_certificate("certificate"); 251 callback.Run(reply); 252 })); 253 std::unique_ptr<dbus::MethodCall> call = 254 CreateMethodCall(kActivateAttestationKey); 255 dbus::MessageWriter writer(call.get()); 256 writer.AppendProtoAsArrayOfBytes(request); 257 auto response = CallMethod(call.get()); 258 dbus::MessageReader reader(response.get()); 259 ActivateAttestationKeyReply reply; 260 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 261 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 262 EXPECT_EQ("certificate", reply.certificate()); 263} 264 265TEST_F(DBusServiceTest, CreateCertifiableKey) { 266 CreateCertifiableKeyRequest request; 267 request.set_key_label("label"); 268 request.set_key_type(KEY_TYPE_ECC); 269 request.set_key_usage(KEY_USAGE_SIGN); 270 request.set_username("user"); 271 EXPECT_CALL(mock_service_, CreateCertifiableKey(_, _)) 272 .WillOnce(Invoke([]( 273 const CreateCertifiableKeyRequest& request, 274 const AttestationInterface::CreateCertifiableKeyCallback& callback) { 275 EXPECT_EQ("label", request.key_label()); 276 EXPECT_EQ(KEY_TYPE_ECC, request.key_type()); 277 EXPECT_EQ(KEY_USAGE_SIGN, request.key_usage()); 278 EXPECT_EQ("user", request.username()); 279 CreateCertifiableKeyReply reply; 280 reply.set_status(STATUS_SUCCESS); 281 reply.set_public_key("public_key"); 282 reply.set_certify_info("certify_info"); 283 reply.set_certify_info_signature("signature"); 284 callback.Run(reply); 285 })); 286 std::unique_ptr<dbus::MethodCall> call = 287 CreateMethodCall(kCreateCertifiableKey); 288 dbus::MessageWriter writer(call.get()); 289 writer.AppendProtoAsArrayOfBytes(request); 290 auto response = CallMethod(call.get()); 291 dbus::MessageReader reader(response.get()); 292 CreateCertifiableKeyReply reply; 293 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 294 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 295 EXPECT_EQ("public_key", reply.public_key()); 296 EXPECT_EQ("certify_info", reply.certify_info()); 297 EXPECT_EQ("signature", reply.certify_info_signature()); 298} 299 300TEST_F(DBusServiceTest, Decrypt) { 301 DecryptRequest request; 302 request.set_key_label("label"); 303 request.set_username("user"); 304 request.set_encrypted_data("data"); 305 EXPECT_CALL(mock_service_, Decrypt(_, _)) 306 .WillOnce( 307 Invoke([](const DecryptRequest& request, 308 const AttestationInterface::DecryptCallback& callback) { 309 EXPECT_EQ("label", request.key_label()); 310 EXPECT_EQ("user", request.username()); 311 EXPECT_EQ("data", request.encrypted_data()); 312 DecryptReply reply; 313 reply.set_status(STATUS_SUCCESS); 314 reply.set_decrypted_data("data"); 315 callback.Run(reply); 316 })); 317 std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kDecrypt); 318 dbus::MessageWriter writer(call.get()); 319 writer.AppendProtoAsArrayOfBytes(request); 320 auto response = CallMethod(call.get()); 321 dbus::MessageReader reader(response.get()); 322 DecryptReply reply; 323 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 324 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 325 EXPECT_EQ("data", reply.decrypted_data()); 326} 327 328TEST_F(DBusServiceTest, Sign) { 329 SignRequest request; 330 request.set_key_label("label"); 331 request.set_username("user"); 332 request.set_data_to_sign("data"); 333 EXPECT_CALL(mock_service_, Sign(_, _)) 334 .WillOnce(Invoke([](const SignRequest& request, 335 const AttestationInterface::SignCallback& callback) { 336 EXPECT_EQ("label", request.key_label()); 337 EXPECT_EQ("user", request.username()); 338 EXPECT_EQ("data", request.data_to_sign()); 339 SignReply reply; 340 reply.set_status(STATUS_SUCCESS); 341 reply.set_signature("signature"); 342 callback.Run(reply); 343 })); 344 std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kSign); 345 dbus::MessageWriter writer(call.get()); 346 writer.AppendProtoAsArrayOfBytes(request); 347 auto response = CallMethod(call.get()); 348 dbus::MessageReader reader(response.get()); 349 SignReply reply; 350 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 351 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 352 EXPECT_EQ("signature", reply.signature()); 353} 354 355TEST_F(DBusServiceTest, RegisterKeyWithChapsToken) { 356 RegisterKeyWithChapsTokenRequest request; 357 request.set_key_label("label"); 358 request.set_username("user"); 359 EXPECT_CALL(mock_service_, RegisterKeyWithChapsToken(_, _)) 360 .WillOnce(Invoke( 361 [](const RegisterKeyWithChapsTokenRequest& request, 362 const AttestationInterface::RegisterKeyWithChapsTokenCallback& 363 callback) { 364 EXPECT_EQ("label", request.key_label()); 365 EXPECT_EQ("user", request.username()); 366 RegisterKeyWithChapsTokenReply reply; 367 reply.set_status(STATUS_SUCCESS); 368 callback.Run(reply); 369 })); 370 std::unique_ptr<dbus::MethodCall> call = 371 CreateMethodCall(kRegisterKeyWithChapsToken); 372 dbus::MessageWriter writer(call.get()); 373 writer.AppendProtoAsArrayOfBytes(request); 374 auto response = CallMethod(call.get()); 375 dbus::MessageReader reader(response.get()); 376 RegisterKeyWithChapsTokenReply reply; 377 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 378 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 379} 380 381} // namespace attestation 382