Home | History | Annotate | Download | only in cryptohome
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chromeos/cryptohome/homedir_methods.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/bind_helpers.h"
      9 #include "base/compiler_specific.h"
     10 #include "base/memory/scoped_ptr.h"
     11 #include "chromeos/dbus/cryptohome/rpc.pb.h"
     12 #include "chromeos/dbus/cryptohome_client.h"
     13 #include "chromeos/dbus/dbus_method_call_status.h"
     14 #include "chromeos/dbus/dbus_thread_manager.h"
     15 #include "chromeos/dbus/mock_cryptohome_client.h"
     16 #include "testing/gmock/include/gmock/gmock.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 
     19 using testing::_;
     20 using testing::Invoke;
     21 using testing::WithArg;
     22 
     23 namespace cryptohome {
     24 
     25 namespace {
     26 
     27 MATCHER_P(EqualsProto, expected_proto, "") {
     28   std::string expected_value;
     29   expected_proto.SerializeToString(&expected_value);
     30   std::string actual_value;
     31   arg.SerializeToString(&actual_value);
     32   return actual_value == expected_value;
     33 }
     34 
     35 }  // namespace
     36 
     37 const char kUserID[] = "user (at) example.com";
     38 const char kKeyLabel[] = "key_label";
     39 
     40 const int64 kKeyRevision = 123;
     41 const char kProviderData1Name[] = "data_1";
     42 const int64 kProviderData1Number = 12345;
     43 const char kProviderData2Name[] = "data_2";
     44 const char kProviderData2Bytes[] = "data_2 bytes";
     45 
     46 class HomedirMethodsTest : public testing::Test {
     47  public:
     48   HomedirMethodsTest();
     49   virtual ~HomedirMethodsTest();
     50 
     51   // testing::Test:
     52   virtual void SetUp() OVERRIDE;
     53   virtual void TearDown() OVERRIDE;
     54 
     55   void RunProtobufMethodCallback(
     56       const chromeos::CryptohomeClient::ProtobufMethodCallback& callback);
     57 
     58   void StoreGetKeyDataExResult(
     59       bool success,
     60       MountError return_code,
     61       const std::vector<KeyDefinition>& key_definitions);
     62 
     63  protected:
     64   chromeos::MockCryptohomeClient* cryptohome_client_;
     65 
     66   // The reply that |cryptohome_client_| will make.
     67   cryptohome::BaseReply cryptohome_reply_;
     68 
     69   // The results of the most recent |HomedirMethods| method call.
     70   bool success_;
     71   MountError return_code_;
     72   std::vector<KeyDefinition> key_definitions_;
     73 
     74  private:
     75   DISALLOW_COPY_AND_ASSIGN(HomedirMethodsTest);
     76 };
     77 
     78 HomedirMethodsTest::HomedirMethodsTest() : cryptohome_client_(NULL),
     79                                            success_(false),
     80                                            return_code_(MOUNT_ERROR_FATAL) {
     81 }
     82 
     83 HomedirMethodsTest::~HomedirMethodsTest() {
     84 }
     85 
     86 void HomedirMethodsTest::SetUp() {
     87   scoped_ptr<chromeos::MockCryptohomeClient> cryptohome_client(
     88       new chromeos::MockCryptohomeClient);
     89   cryptohome_client_ = cryptohome_client.get();
     90   chromeos::DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient(
     91       cryptohome_client.PassAs<chromeos::CryptohomeClient>());
     92   HomedirMethods::Initialize();
     93 }
     94 
     95 void HomedirMethodsTest::TearDown() {
     96   HomedirMethods::Shutdown();
     97   chromeos::DBusThreadManager::Shutdown();
     98 }
     99 
    100 void HomedirMethodsTest::RunProtobufMethodCallback(
    101     const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) {
    102   callback.Run(chromeos::DBUS_METHOD_CALL_SUCCESS,
    103                true,
    104                cryptohome_reply_);
    105 }
    106 
    107 void HomedirMethodsTest::StoreGetKeyDataExResult(
    108     bool success,
    109     MountError return_code,
    110     const std::vector<KeyDefinition>& key_definitions) {
    111   success_ = success;
    112   return_code_ = return_code;
    113   key_definitions_ = key_definitions;
    114 }
    115 
    116 // Verifies that the result of a GetKeyDataEx() call is correctly parsed.
    117 TEST_F(HomedirMethodsTest, GetKeyDataEx) {
    118   AccountIdentifier expected_id;
    119   expected_id.set_email(kUserID);
    120   const cryptohome::AuthorizationRequest expected_auth;
    121   cryptohome::GetKeyDataRequest expected_request;
    122       expected_request.mutable_key()->mutable_data()->set_label(kKeyLabel);
    123 
    124   EXPECT_CALL(*cryptohome_client_,
    125               GetKeyDataEx(EqualsProto(expected_id),
    126                            EqualsProto(expected_auth),
    127                            EqualsProto(expected_request),
    128                            _))
    129       .Times(1)
    130       .WillOnce(WithArg<3>(Invoke(
    131           this,
    132           &HomedirMethodsTest::RunProtobufMethodCallback)));
    133 
    134   // Set up the reply that |cryptohome_client_| will make.
    135   cryptohome::GetKeyDataReply* reply =
    136       cryptohome_reply_.MutableExtension(cryptohome::GetKeyDataReply::reply);
    137   KeyData* key_data = reply->add_key_data();
    138   key_data->set_type(KeyData::KEY_TYPE_PASSWORD);
    139   key_data->set_label(kKeyLabel);
    140   key_data->mutable_privileges()->set_update(false);
    141   key_data->set_revision(kKeyRevision);
    142   key_data->add_authorization_data()->set_type(
    143       KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256);
    144   KeyProviderData* data = key_data->mutable_provider_data();
    145   KeyProviderData::Entry* entry = data->add_entry();
    146   entry->set_name(kProviderData1Name);
    147   entry->set_number(kProviderData1Number);
    148   entry = data->add_entry();
    149   entry->set_name(kProviderData2Name);
    150   entry->set_bytes(kProviderData2Bytes);
    151 
    152   // Call GetKeyDataEx().
    153   HomedirMethods::GetInstance()->GetKeyDataEx(
    154     Identification(kUserID),
    155     kKeyLabel,
    156     base::Bind(&HomedirMethodsTest::StoreGetKeyDataExResult,
    157                base::Unretained(this)));
    158 
    159   // Verify that the call was successful and the result was correctly parsed.
    160   EXPECT_TRUE(success_);
    161   EXPECT_EQ(MOUNT_ERROR_NONE, return_code_);
    162   ASSERT_EQ(1u, key_definitions_.size());
    163   const KeyDefinition& key_definition = key_definitions_.front();
    164   EXPECT_EQ(KeyDefinition::TYPE_PASSWORD, key_definition.type);
    165   EXPECT_EQ(PRIV_MOUNT | PRIV_ADD | PRIV_REMOVE,
    166             key_definition.privileges);
    167   EXPECT_EQ(kKeyRevision, key_definition.revision);
    168   ASSERT_EQ(1u, key_definition.authorization_data.size());
    169   EXPECT_EQ(KeyDefinition::AuthorizationData::TYPE_HMACSHA256,
    170             key_definition.authorization_data.front().type);
    171   ASSERT_EQ(2u, key_definition.provider_data.size());
    172   const KeyDefinition::ProviderData* provider_data =
    173       &key_definition.provider_data[0];
    174   EXPECT_EQ(kProviderData1Name, provider_data->name);
    175   ASSERT_TRUE(provider_data->number);
    176   EXPECT_EQ(kProviderData1Number, *provider_data->number.get());
    177   EXPECT_FALSE(provider_data->bytes);
    178   provider_data = &key_definition.provider_data[1];
    179   EXPECT_EQ(kProviderData2Name, provider_data->name);
    180   EXPECT_FALSE(provider_data->number);
    181   ASSERT_TRUE(provider_data->bytes);
    182   EXPECT_EQ(kProviderData2Bytes, *provider_data->bytes.get());
    183 }
    184 
    185 }  // namespace cryptohome
    186