Home | History | Annotate | Download | only in server
      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_ =
     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 
     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(
     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 
    114 TEST_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 
    135 TEST_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 
    171 TEST_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 
    198 TEST_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 
    231 TEST_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 
    265 TEST_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 
    300 TEST_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 
    328 TEST_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 
    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 }  // namespace attestation
    382