1// 2// Copyright (C) 2015 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 <dbus/mock_object_proxy.h> 21#include <gmock/gmock.h> 22#include <gtest/gtest.h> 23 24#include "attestation/client/dbus_proxy.h" 25 26using testing::_; 27using testing::Invoke; 28using testing::StrictMock; 29using testing::WithArgs; 30 31namespace attestation { 32 33class DBusProxyTest : public testing::Test { 34 public: 35 ~DBusProxyTest() override = default; 36 void SetUp() override { 37 mock_object_proxy_ = new StrictMock<dbus::MockObjectProxy>( 38 nullptr, "", dbus::ObjectPath("")); 39 proxy_.set_object_proxy(mock_object_proxy_.get()); 40 } 41 42 protected: 43 scoped_refptr<StrictMock<dbus::MockObjectProxy>> mock_object_proxy_; 44 DBusProxy proxy_; 45}; 46 47TEST_F(DBusProxyTest, CreateGoogleAttestedKey) { 48 auto fake_dbus_call = []( 49 dbus::MethodCall* method_call, 50 const dbus::MockObjectProxy::ResponseCallback& response_callback) { 51 // Verify request protobuf. 52 dbus::MessageReader reader(method_call); 53 CreateGoogleAttestedKeyRequest request_proto; 54 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); 55 EXPECT_EQ("label", request_proto.key_label()); 56 EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type()); 57 EXPECT_EQ(KEY_USAGE_SIGN, request_proto.key_usage()); 58 EXPECT_EQ(ENTERPRISE_MACHINE_CERTIFICATE, 59 request_proto.certificate_profile()); 60 EXPECT_EQ("user", request_proto.username()); 61 EXPECT_EQ("origin", request_proto.origin()); 62 // Create reply protobuf. 63 auto response = dbus::Response::CreateEmpty(); 64 dbus::MessageWriter writer(response.get()); 65 CreateGoogleAttestedKeyReply reply_proto; 66 reply_proto.set_status(STATUS_SUCCESS); 67 reply_proto.set_certificate_chain("certificate"); 68 reply_proto.set_server_error("server_error"); 69 writer.AppendProtoAsArrayOfBytes(reply_proto); 70 response_callback.Run(response.release()); 71 }; 72 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 73 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); 74 75 // Set expectations on the outputs. 76 int callback_count = 0; 77 auto callback = [&callback_count](const CreateGoogleAttestedKeyReply& reply) { 78 callback_count++; 79 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 80 EXPECT_EQ("certificate", reply.certificate_chain()); 81 EXPECT_EQ("server_error", reply.server_error()); 82 }; 83 CreateGoogleAttestedKeyRequest request; 84 request.set_key_label("label"); 85 request.set_key_type(KEY_TYPE_ECC); 86 request.set_key_usage(KEY_USAGE_SIGN); 87 request.set_certificate_profile(ENTERPRISE_MACHINE_CERTIFICATE); 88 request.set_username("user"); 89 request.set_origin("origin"); 90 proxy_.CreateGoogleAttestedKey(request, base::Bind(callback)); 91 EXPECT_EQ(1, callback_count); 92} 93 94TEST_F(DBusProxyTest, GetKeyInfo) { 95 auto fake_dbus_call = []( 96 dbus::MethodCall* method_call, 97 const dbus::MockObjectProxy::ResponseCallback& response_callback) { 98 // Verify request protobuf. 99 dbus::MessageReader reader(method_call); 100 GetKeyInfoRequest request_proto; 101 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); 102 EXPECT_EQ("label", request_proto.key_label()); 103 EXPECT_EQ("username", request_proto.username()); 104 // Create reply protobuf. 105 auto response = dbus::Response::CreateEmpty(); 106 dbus::MessageWriter writer(response.get()); 107 GetKeyInfoReply reply_proto; 108 reply_proto.set_status(STATUS_SUCCESS); 109 reply_proto.set_key_type(KEY_TYPE_ECC); 110 reply_proto.set_key_usage(KEY_USAGE_SIGN); 111 reply_proto.set_public_key("public_key"); 112 reply_proto.set_certify_info("certify_info"); 113 reply_proto.set_certify_info_signature("signature"); 114 reply_proto.set_certificate("certificate"); 115 writer.AppendProtoAsArrayOfBytes(reply_proto); 116 response_callback.Run(response.release()); 117 }; 118 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 119 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); 120 121 // Set expectations on the outputs. 122 int callback_count = 0; 123 auto callback = [&callback_count](const GetKeyInfoReply& reply) { 124 callback_count++; 125 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 126 EXPECT_EQ(KEY_TYPE_ECC, reply.key_type()); 127 EXPECT_EQ(KEY_USAGE_SIGN, reply.key_usage()); 128 EXPECT_EQ("public_key", reply.public_key()); 129 EXPECT_EQ("certify_info", reply.certify_info()); 130 EXPECT_EQ("signature", reply.certify_info_signature()); 131 EXPECT_EQ("certificate", reply.certificate()); 132 }; 133 GetKeyInfoRequest request; 134 request.set_key_label("label"); 135 request.set_username("username"); 136 proxy_.GetKeyInfo(request, base::Bind(callback)); 137 EXPECT_EQ(1, callback_count); 138} 139 140TEST_F(DBusProxyTest, GetEndorsementInfo) { 141 auto fake_dbus_call = []( 142 dbus::MethodCall* method_call, 143 const dbus::MockObjectProxy::ResponseCallback& response_callback) { 144 // Verify request protobuf. 145 dbus::MessageReader reader(method_call); 146 GetEndorsementInfoRequest request_proto; 147 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); 148 EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type()); 149 // Create reply protobuf. 150 auto response = dbus::Response::CreateEmpty(); 151 dbus::MessageWriter writer(response.get()); 152 GetEndorsementInfoReply reply_proto; 153 reply_proto.set_status(STATUS_SUCCESS); 154 reply_proto.set_ek_public_key("public_key"); 155 reply_proto.set_ek_certificate("certificate"); 156 writer.AppendProtoAsArrayOfBytes(reply_proto); 157 response_callback.Run(response.release()); 158 }; 159 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 160 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); 161 162 // Set expectations on the outputs. 163 int callback_count = 0; 164 auto callback = [&callback_count](const GetEndorsementInfoReply& reply) { 165 callback_count++; 166 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 167 EXPECT_EQ("public_key", reply.ek_public_key()); 168 EXPECT_EQ("certificate", reply.ek_certificate()); 169 }; 170 GetEndorsementInfoRequest request; 171 request.set_key_type(KEY_TYPE_ECC); 172 proxy_.GetEndorsementInfo(request, base::Bind(callback)); 173 EXPECT_EQ(1, callback_count); 174} 175 176TEST_F(DBusProxyTest, GetAttestationKeyInfo) { 177 auto fake_dbus_call = []( 178 dbus::MethodCall* method_call, 179 const dbus::MockObjectProxy::ResponseCallback& response_callback) { 180 // Verify request protobuf. 181 dbus::MessageReader reader(method_call); 182 GetAttestationKeyInfoRequest request_proto; 183 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); 184 EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type()); 185 // Create reply protobuf. 186 auto response = dbus::Response::CreateEmpty(); 187 dbus::MessageWriter writer(response.get()); 188 GetAttestationKeyInfoReply reply_proto; 189 reply_proto.set_status(STATUS_SUCCESS); 190 reply_proto.set_public_key("public_key"); 191 reply_proto.set_public_key_tpm_format("public_key_tpm_format"); 192 reply_proto.set_certificate("certificate"); 193 reply_proto.mutable_pcr0_quote()->set_quote("pcr0"); 194 reply_proto.mutable_pcr1_quote()->set_quote("pcr1"); 195 writer.AppendProtoAsArrayOfBytes(reply_proto); 196 response_callback.Run(response.release()); 197 }; 198 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 199 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); 200 201 // Set expectations on the outputs. 202 int callback_count = 0; 203 auto callback = [&callback_count](const GetAttestationKeyInfoReply& reply) { 204 callback_count++; 205 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 206 EXPECT_EQ("public_key", reply.public_key()); 207 EXPECT_EQ("public_key_tpm_format", reply.public_key_tpm_format()); 208 EXPECT_EQ("certificate", reply.certificate()); 209 EXPECT_EQ("pcr0", reply.pcr0_quote().quote()); 210 EXPECT_EQ("pcr1", reply.pcr1_quote().quote()); 211 }; 212 GetAttestationKeyInfoRequest request; 213 request.set_key_type(KEY_TYPE_ECC); 214 proxy_.GetAttestationKeyInfo(request, base::Bind(callback)); 215 EXPECT_EQ(1, callback_count); 216} 217 218TEST_F(DBusProxyTest, ActivateAttestationKey) { 219 auto fake_dbus_call = []( 220 dbus::MethodCall* method_call, 221 const dbus::MockObjectProxy::ResponseCallback& response_callback) { 222 // Verify request protobuf. 223 dbus::MessageReader reader(method_call); 224 ActivateAttestationKeyRequest request_proto; 225 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); 226 EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type()); 227 EXPECT_EQ("encrypted1", 228 request_proto.encrypted_certificate().asym_ca_contents()); 229 EXPECT_EQ("encrypted2", 230 request_proto.encrypted_certificate().sym_ca_attestation()); 231 EXPECT_TRUE(request_proto.save_certificate()); 232 // Create reply protobuf. 233 auto response = dbus::Response::CreateEmpty(); 234 dbus::MessageWriter writer(response.get()); 235 ActivateAttestationKeyReply reply_proto; 236 reply_proto.set_status(STATUS_SUCCESS); 237 reply_proto.set_certificate("certificate"); 238 writer.AppendProtoAsArrayOfBytes(reply_proto); 239 response_callback.Run(response.release()); 240 }; 241 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 242 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); 243 244 // Set expectations on the outputs. 245 int callback_count = 0; 246 auto callback = [&callback_count](const ActivateAttestationKeyReply& reply) { 247 callback_count++; 248 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 249 EXPECT_EQ("certificate", reply.certificate()); 250 }; 251 ActivateAttestationKeyRequest request; 252 request.set_key_type(KEY_TYPE_ECC); 253 request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1"); 254 request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2"); 255 request.set_save_certificate(true); 256 proxy_.ActivateAttestationKey(request, base::Bind(callback)); 257 EXPECT_EQ(1, callback_count); 258} 259 260TEST_F(DBusProxyTest, CreateCertifiableKey) { 261 auto fake_dbus_call = []( 262 dbus::MethodCall* method_call, 263 const dbus::MockObjectProxy::ResponseCallback& response_callback) { 264 // Verify request protobuf. 265 dbus::MessageReader reader(method_call); 266 CreateCertifiableKeyRequest request_proto; 267 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); 268 EXPECT_EQ("label", request_proto.key_label()); 269 EXPECT_EQ(KEY_TYPE_ECC, request_proto.key_type()); 270 EXPECT_EQ(KEY_USAGE_SIGN, request_proto.key_usage()); 271 EXPECT_EQ("user", request_proto.username()); 272 // Create reply protobuf. 273 auto response = dbus::Response::CreateEmpty(); 274 dbus::MessageWriter writer(response.get()); 275 CreateCertifiableKeyReply reply_proto; 276 reply_proto.set_status(STATUS_SUCCESS); 277 reply_proto.set_public_key("public_key"); 278 reply_proto.set_certify_info("certify_info"); 279 reply_proto.set_certify_info_signature("signature"); 280 writer.AppendProtoAsArrayOfBytes(reply_proto); 281 response_callback.Run(response.release()); 282 }; 283 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 284 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); 285 286 // Set expectations on the outputs. 287 int callback_count = 0; 288 auto callback = [&callback_count](const CreateCertifiableKeyReply& reply) { 289 callback_count++; 290 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 291 EXPECT_EQ("public_key", reply.public_key()); 292 EXPECT_EQ("certify_info", reply.certify_info()); 293 EXPECT_EQ("signature", reply.certify_info_signature()); 294 }; 295 CreateCertifiableKeyRequest request; 296 request.set_key_label("label"); 297 request.set_key_type(KEY_TYPE_ECC); 298 request.set_key_usage(KEY_USAGE_SIGN); 299 request.set_username("user"); 300 proxy_.CreateCertifiableKey(request, base::Bind(callback)); 301 EXPECT_EQ(1, callback_count); 302} 303 304TEST_F(DBusProxyTest, Decrypt) { 305 auto fake_dbus_call = []( 306 dbus::MethodCall* method_call, 307 const dbus::MockObjectProxy::ResponseCallback& response_callback) { 308 // Verify request protobuf. 309 dbus::MessageReader reader(method_call); 310 DecryptRequest request_proto; 311 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); 312 EXPECT_EQ("label", request_proto.key_label()); 313 EXPECT_EQ("user", request_proto.username()); 314 EXPECT_EQ("data", request_proto.encrypted_data()); 315 // Create reply protobuf. 316 scoped_ptr<dbus::Response> response = dbus::Response::CreateEmpty(); 317 dbus::MessageWriter writer(response.get()); 318 DecryptReply reply_proto; 319 reply_proto.set_status(STATUS_SUCCESS); 320 reply_proto.set_decrypted_data("data"); 321 writer.AppendProtoAsArrayOfBytes(reply_proto); 322 response_callback.Run(response.release()); 323 }; 324 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 325 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); 326 327 // Set expectations on the outputs. 328 int callback_count = 0; 329 auto callback = [&callback_count](const DecryptReply& reply) { 330 callback_count++; 331 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 332 EXPECT_EQ("data", reply.decrypted_data()); 333 }; 334 DecryptRequest request; 335 request.set_key_label("label"); 336 request.set_username("user"); 337 request.set_encrypted_data("data"); 338 proxy_.Decrypt(request, base::Bind(callback)); 339 EXPECT_EQ(1, callback_count); 340} 341 342TEST_F(DBusProxyTest, Sign) { 343 auto fake_dbus_call = []( 344 dbus::MethodCall* method_call, 345 const dbus::MockObjectProxy::ResponseCallback& response_callback) { 346 // Verify request protobuf. 347 dbus::MessageReader reader(method_call); 348 SignRequest request_proto; 349 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); 350 EXPECT_EQ("label", request_proto.key_label()); 351 EXPECT_EQ("user", request_proto.username()); 352 EXPECT_EQ("data", request_proto.data_to_sign()); 353 // Create reply protobuf. 354 auto response = dbus::Response::CreateEmpty(); 355 dbus::MessageWriter writer(response.get()); 356 SignReply reply_proto; 357 reply_proto.set_status(STATUS_SUCCESS); 358 reply_proto.set_signature("signature"); 359 writer.AppendProtoAsArrayOfBytes(reply_proto); 360 response_callback.Run(response.release()); 361 }; 362 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 363 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); 364 365 // Set expectations on the outputs. 366 int callback_count = 0; 367 auto callback = [&callback_count](const SignReply& reply) { 368 callback_count++; 369 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 370 EXPECT_EQ("signature", reply.signature()); 371 }; 372 SignRequest request; 373 request.set_key_label("label"); 374 request.set_username("user"); 375 request.set_data_to_sign("data"); 376 proxy_.Sign(request, base::Bind(callback)); 377 EXPECT_EQ(1, callback_count); 378} 379 380TEST_F(DBusProxyTest, RegisterKeyWithChapsToken) { 381 auto fake_dbus_call = []( 382 dbus::MethodCall* method_call, 383 const dbus::MockObjectProxy::ResponseCallback& response_callback) { 384 // Verify request protobuf. 385 dbus::MessageReader reader(method_call); 386 RegisterKeyWithChapsTokenRequest request_proto; 387 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&request_proto)); 388 EXPECT_EQ("label", request_proto.key_label()); 389 EXPECT_EQ("user", request_proto.username()); 390 // Create reply protobuf. 391 auto response = dbus::Response::CreateEmpty(); 392 dbus::MessageWriter writer(response.get()); 393 RegisterKeyWithChapsTokenReply reply_proto; 394 reply_proto.set_status(STATUS_SUCCESS); 395 writer.AppendProtoAsArrayOfBytes(reply_proto); 396 response_callback.Run(response.release()); 397 }; 398 EXPECT_CALL(*mock_object_proxy_, CallMethodWithErrorCallback(_, _, _, _)) 399 .WillOnce(WithArgs<0, 2>(Invoke(fake_dbus_call))); 400 401 // Set expectations on the outputs. 402 int callback_count = 0; 403 auto callback = 404 [&callback_count](const RegisterKeyWithChapsTokenReply& reply) { 405 callback_count++; 406 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 407 }; 408 RegisterKeyWithChapsTokenRequest request; 409 request.set_key_label("label"); 410 request.set_username("user"); 411 proxy_.RegisterKeyWithChapsToken(request, base::Bind(callback)); 412 EXPECT_EQ(1, callback_count); 413} 414 415} // namespace attestation 416