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