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 30 using testing::_; 31 using testing::Invoke; 32 using testing::NiceMock; 33 using testing::Return; 34 using testing::StrictMock; 35 using testing::WithArgs; 36 37 namespace attestation { 38 39 class 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_ = new NiceMock<dbus::MockExportedObject>( 47 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(brillo::dbus_utils::AsyncEventSequencer:: 52 GetDefaultCompletionAction()); 53 } 54 55 std::unique_ptr<dbus::Response> CallMethod(dbus::MethodCall* method_call) { 56 return brillo::dbus_utils::testing::CallMethod( 57 dbus_service_->dbus_object_, method_call); 58 } 59 60 std::unique_ptr<dbus::MethodCall> CreateMethodCall( 61 const std::string& method_name) { 62 std::unique_ptr<dbus::MethodCall> call(new dbus::MethodCall( 63 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 75 TEST_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(Invoke([]( 85 const CreateGoogleAttestedKeyRequest& request, 86 const AttestationInterface:: 87 CreateGoogleAttestedKeyCallback& 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 = CreateMethodCall( 102 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 114 TEST_F(DBusServiceTest, CopyableCallback) { 115 EXPECT_CALL(mock_service_, CreateGoogleAttestedKey(_, _)) 116 .WillOnce(WithArgs<1>(Invoke([](const AttestationInterface:: 117 CreateGoogleAttestedKeyCallback& callback) { 118 // Copy the callback, then call the original. 119 CreateGoogleAttestedKeyReply reply; 120 base::Closure copy = base::Bind(callback, reply); 121 callback.Run(reply); 122 }))); 123 std::unique_ptr<dbus::MethodCall> call = CreateMethodCall( 124 kCreateGoogleAttestedKey); 125 CreateGoogleAttestedKeyRequest request; 126 dbus::MessageWriter writer(call.get()); 127 writer.AppendProtoAsArrayOfBytes(request); 128 auto response = CallMethod(call.get()); 129 dbus::MessageReader reader(response.get()); 130 CreateGoogleAttestedKeyReply reply; 131 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 132 } 133 134 TEST_F(DBusServiceTest, GetKeyInfo) { 135 GetKeyInfoRequest request; 136 request.set_key_label("label"); 137 request.set_username("username"); 138 EXPECT_CALL(mock_service_, GetKeyInfo(_, _)) 139 .WillOnce(Invoke([]( 140 const GetKeyInfoRequest& request, 141 const AttestationInterface::GetKeyInfoCallback& callback) { 142 EXPECT_EQ("label", request.key_label()); 143 EXPECT_EQ("username", request.username()); 144 GetKeyInfoReply reply; 145 reply.set_status(STATUS_SUCCESS); 146 reply.set_key_type(KEY_TYPE_ECC); 147 reply.set_key_usage(KEY_USAGE_SIGN); 148 reply.set_public_key("public_key"); 149 reply.set_certify_info("certify"); 150 reply.set_certify_info_signature("signature"); 151 reply.set_certificate("certificate"); 152 callback.Run(reply); 153 })); 154 std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kGetKeyInfo); 155 dbus::MessageWriter writer(call.get()); 156 writer.AppendProtoAsArrayOfBytes(request); 157 auto response = CallMethod(call.get()); 158 dbus::MessageReader reader(response.get()); 159 GetKeyInfoReply reply; 160 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 161 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 162 EXPECT_EQ(KEY_TYPE_ECC, reply.key_type()); 163 EXPECT_EQ(KEY_USAGE_SIGN, reply.key_usage()); 164 EXPECT_EQ("public_key", reply.public_key()); 165 EXPECT_EQ("certify", reply.certify_info()); 166 EXPECT_EQ("signature", reply.certify_info_signature()); 167 EXPECT_EQ("certificate", reply.certificate()); 168 } 169 170 TEST_F(DBusServiceTest, GetEndorsementInfo) { 171 GetEndorsementInfoRequest request; 172 request.set_key_type(KEY_TYPE_ECC); 173 EXPECT_CALL(mock_service_, GetEndorsementInfo(_, _)) 174 .WillOnce(Invoke([]( 175 const GetEndorsementInfoRequest& request, 176 const AttestationInterface::GetEndorsementInfoCallback& callback) { 177 EXPECT_EQ(KEY_TYPE_ECC, request.key_type()); 178 GetEndorsementInfoReply reply; 179 reply.set_status(STATUS_SUCCESS); 180 reply.set_ek_public_key("public_key"); 181 reply.set_ek_certificate("certificate"); 182 callback.Run(reply); 183 })); 184 std::unique_ptr<dbus::MethodCall> call = 185 CreateMethodCall(kGetEndorsementInfo); 186 dbus::MessageWriter writer(call.get()); 187 writer.AppendProtoAsArrayOfBytes(request); 188 auto response = CallMethod(call.get()); 189 dbus::MessageReader reader(response.get()); 190 GetEndorsementInfoReply reply; 191 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 192 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 193 EXPECT_EQ("public_key", reply.ek_public_key()); 194 EXPECT_EQ("certificate", reply.ek_certificate()); 195 } 196 197 TEST_F(DBusServiceTest, GetAttestationKeyInfo) { 198 GetAttestationKeyInfoRequest request; 199 request.set_key_type(KEY_TYPE_ECC); 200 EXPECT_CALL(mock_service_, GetAttestationKeyInfo(_, _)) 201 .WillOnce(Invoke([]( 202 const GetAttestationKeyInfoRequest& request, 203 const AttestationInterface::GetAttestationKeyInfoCallback& callback) { 204 EXPECT_EQ(KEY_TYPE_ECC, request.key_type()); 205 GetAttestationKeyInfoReply reply; 206 reply.set_status(STATUS_SUCCESS); 207 reply.set_public_key("public_key"); 208 reply.set_public_key_tpm_format("public_key_tpm_format"); 209 reply.set_certificate("certificate"); 210 reply.mutable_pcr0_quote()->set_quote("pcr0"); 211 reply.mutable_pcr1_quote()->set_quote("pcr1"); 212 callback.Run(reply); 213 })); 214 std::unique_ptr<dbus::MethodCall> call = 215 CreateMethodCall(kGetAttestationKeyInfo); 216 dbus::MessageWriter writer(call.get()); 217 writer.AppendProtoAsArrayOfBytes(request); 218 auto response = CallMethod(call.get()); 219 dbus::MessageReader reader(response.get()); 220 GetAttestationKeyInfoReply reply; 221 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 222 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 223 EXPECT_EQ("public_key", reply.public_key()); 224 EXPECT_EQ("public_key_tpm_format", reply.public_key_tpm_format()); 225 EXPECT_EQ("certificate", reply.certificate()); 226 EXPECT_EQ("pcr0", reply.pcr0_quote().quote()); 227 EXPECT_EQ("pcr1", reply.pcr1_quote().quote()); 228 } 229 230 TEST_F(DBusServiceTest, ActivateAttestationKey) { 231 ActivateAttestationKeyRequest request; 232 request.set_key_type(KEY_TYPE_ECC); 233 request.mutable_encrypted_certificate()->set_asym_ca_contents("encrypted1"); 234 request.mutable_encrypted_certificate()->set_sym_ca_attestation("encrypted2"); 235 request.set_save_certificate(true); 236 EXPECT_CALL(mock_service_, ActivateAttestationKey(_, _)) 237 .WillOnce(Invoke([]( 238 const ActivateAttestationKeyRequest& request, 239 const AttestationInterface::ActivateAttestationKeyCallback& 240 callback) { 241 EXPECT_EQ(KEY_TYPE_ECC, request.key_type()); 242 EXPECT_EQ("encrypted1", 243 request.encrypted_certificate().asym_ca_contents()); 244 EXPECT_EQ("encrypted2", 245 request.encrypted_certificate().sym_ca_attestation()); 246 EXPECT_TRUE(request.save_certificate()); 247 ActivateAttestationKeyReply reply; 248 reply.set_status(STATUS_SUCCESS); 249 reply.set_certificate("certificate"); 250 callback.Run(reply); 251 })); 252 std::unique_ptr<dbus::MethodCall> call = 253 CreateMethodCall(kActivateAttestationKey); 254 dbus::MessageWriter writer(call.get()); 255 writer.AppendProtoAsArrayOfBytes(request); 256 auto response = CallMethod(call.get()); 257 dbus::MessageReader reader(response.get()); 258 ActivateAttestationKeyReply reply; 259 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 260 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 261 EXPECT_EQ("certificate", reply.certificate()); 262 } 263 264 TEST_F(DBusServiceTest, CreateCertifiableKey) { 265 CreateCertifiableKeyRequest request; 266 request.set_key_label("label"); 267 request.set_key_type(KEY_TYPE_ECC); 268 request.set_key_usage(KEY_USAGE_SIGN); 269 request.set_username("user"); 270 EXPECT_CALL(mock_service_, CreateCertifiableKey(_, _)) 271 .WillOnce(Invoke([]( 272 const CreateCertifiableKeyRequest& request, 273 const AttestationInterface::CreateCertifiableKeyCallback& callback) { 274 EXPECT_EQ("label", request.key_label()); 275 EXPECT_EQ(KEY_TYPE_ECC, request.key_type()); 276 EXPECT_EQ(KEY_USAGE_SIGN, request.key_usage()); 277 EXPECT_EQ("user", request.username()); 278 CreateCertifiableKeyReply reply; 279 reply.set_status(STATUS_SUCCESS); 280 reply.set_public_key("public_key"); 281 reply.set_certify_info("certify_info"); 282 reply.set_certify_info_signature("signature"); 283 callback.Run(reply); 284 })); 285 std::unique_ptr<dbus::MethodCall> call = 286 CreateMethodCall(kCreateCertifiableKey); 287 dbus::MessageWriter writer(call.get()); 288 writer.AppendProtoAsArrayOfBytes(request); 289 auto response = CallMethod(call.get()); 290 dbus::MessageReader reader(response.get()); 291 CreateCertifiableKeyReply reply; 292 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 293 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 294 EXPECT_EQ("public_key", reply.public_key()); 295 EXPECT_EQ("certify_info", reply.certify_info()); 296 EXPECT_EQ("signature", reply.certify_info_signature()); 297 } 298 299 TEST_F(DBusServiceTest, Decrypt) { 300 DecryptRequest request; 301 request.set_key_label("label"); 302 request.set_username("user"); 303 request.set_encrypted_data("data"); 304 EXPECT_CALL(mock_service_, Decrypt(_, _)) 305 .WillOnce(Invoke([]( 306 const DecryptRequest& request, 307 const AttestationInterface::DecryptCallback& callback) { 308 EXPECT_EQ("label", request.key_label()); 309 EXPECT_EQ("user", request.username()); 310 EXPECT_EQ("data", request.encrypted_data()); 311 DecryptReply reply; 312 reply.set_status(STATUS_SUCCESS); 313 reply.set_decrypted_data("data"); 314 callback.Run(reply); 315 })); 316 std::unique_ptr<dbus::MethodCall> call = CreateMethodCall(kDecrypt); 317 dbus::MessageWriter writer(call.get()); 318 writer.AppendProtoAsArrayOfBytes(request); 319 auto response = CallMethod(call.get()); 320 dbus::MessageReader reader(response.get()); 321 DecryptReply reply; 322 EXPECT_TRUE(reader.PopArrayOfBytesAsProto(&reply)); 323 EXPECT_EQ(STATUS_SUCCESS, reply.status()); 324 EXPECT_EQ("data", reply.decrypted_data()); 325 } 326 327 TEST_F(DBusServiceTest, Sign) { 328 SignRequest request; 329 request.set_key_label("label"); 330 request.set_username("user"); 331 request.set_data_to_sign("data"); 332 EXPECT_CALL(mock_service_, Sign(_, _)) 333 .WillOnce(Invoke([]( 334 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 355 TEST_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 382 } // namespace attestation 383