cryptohome: homedirs_unittest rewrite part 5

KeysetManagementTest class and AddInitialKeyset test.

BUG=chromium:1141301
TEST=unittest

Change-Id: I6409011b53fca1e60ccabc1562203035d031ade0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2507037
Reviewed-by: Greg Kerr <kerrnel@chromium.org>
Reviewed-by: Ryo Hashimoto <hashimoto@chromium.org>
Tested-by: Greg Kerr <kerrnel@chromium.org>
Tested-by: Daniil Lunev <dlunev@chromium.org>
Commit-Queue: Daniil Lunev <dlunev@chromium.org>
diff --git a/cryptohome/BUILD.gn b/cryptohome/BUILD.gn
index 9a56724..28d8d09 100644
--- a/cryptohome/BUILD.gn
+++ b/cryptohome/BUILD.gn
@@ -436,6 +436,7 @@
       "fido/make_credential_response_test.cc",
       "fingerprint_manager_unittest.cc",
       "firmware_management_parameters_unittest.cc",
+      "homedirs_keyset_management_unittest.cc",
       "homedirs_unittest.cc",
       "install_attributes_unittest.cc",
       "le_credential_manager_impl_unittest.cc",
diff --git a/cryptohome/homedirs_keyset_management_unittest.cc b/cryptohome/homedirs_keyset_management_unittest.cc
new file mode 100644
index 0000000..7ceee55
--- /dev/null
+++ b/cryptohome/homedirs_keyset_management_unittest.cc
@@ -0,0 +1,151 @@
+// Copyright 2020 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cryptohome/homedirs.h"
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include <base/files/file_path.h>
+#include <brillo/cryptohome.h>
+#include <brillo/secure_blob.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "cryptohome/credentials.h"
+#include "cryptohome/crypto.h"
+#include "cryptohome/cryptolib.h"
+#include "cryptohome/mock_platform.h"
+#include "cryptohome/mock_tpm.h"
+#include "cryptohome/vault_keyset.h"
+
+using ::testing::_;
+using ::testing::ElementsAre;
+using ::testing::NiceMock;
+using ::testing::Return;
+
+namespace cryptohome {
+
+namespace {
+
+struct UserPassword {
+  const char* name;
+  const char* password;
+};
+
+constexpr char kUser0[] = "First User";
+constexpr char kUserPassword0[] = "user0_pass";
+
+constexpr char kPasswordLabel[] = "password";
+
+}  // namespace
+
+// TODO(dlunev): Remove kKeyFile extern declaration once we have it declared
+// in the proper place.
+extern const char kKeyFile[];
+
+class KeysetManagementTest : public ::testing::Test {
+ public:
+  KeysetManagementTest() : crypto_(&platform_) {}
+  ~KeysetManagementTest() override {}
+
+  // Not copyable or movable
+  KeysetManagementTest(const KeysetManagementTest&) = delete;
+  KeysetManagementTest& operator=(const KeysetManagementTest&) = delete;
+  KeysetManagementTest(KeysetManagementTest&&) = delete;
+  KeysetManagementTest& operator=(KeysetManagementTest&&) = delete;
+
+  void SetUp() override {
+    crypto_.set_tpm(&tpm_);
+    crypto_.set_use_tpm(false);
+    homedirs_.Init(&platform_, &crypto_, nullptr);
+
+    ASSERT_TRUE(homedirs_.GetSystemSalt(&system_salt_));
+    platform_.GetFake()->SetSystemSaltForLibbrillo(system_salt_);
+
+    AddUser(kUser0, kUserPassword0);
+
+    PrepareDirectoryStructure();
+  }
+
+  void TearDown() override {
+    platform_.GetFake()->RemoveSystemSaltForLibbrillo();
+  }
+
+ protected:
+  NiceMock<MockPlatform> platform_;
+  NiceMock<MockTpm> tpm_;
+  Crypto crypto_;
+  HomeDirs homedirs_;
+  brillo::SecureBlob system_salt_;
+
+  struct UserInfo {
+    std::string name;
+    std::string obfuscated;
+    brillo::SecureBlob passkey;
+    Credentials credentials;
+    base::FilePath homedir_path;
+    base::FilePath user_path;
+  };
+
+  // Information about users' homedirs. The order of users is equal to kUsers.
+  std::vector<UserInfo> users_;
+
+  void AddUser(const char* name, const char* password) {
+    std::string obfuscated =
+        brillo::cryptohome::home::SanitizeUserNameWithSalt(name, system_salt_);
+    brillo::SecureBlob passkey;
+    cryptohome::Crypto::PasswordToPasskey(password, system_salt_, &passkey);
+    Credentials credentials(name, passkey);
+    KeyData key_data;
+    key_data.set_label(kPasswordLabel);
+    credentials.set_key_data(key_data);
+
+    UserInfo info = {name,
+                     obfuscated,
+                     passkey,
+                     credentials,
+                     homedirs_.shadow_root().Append(obfuscated),
+                     brillo::cryptohome::home::GetHashedUserPath(obfuscated)};
+    users_.push_back(info);
+  }
+
+  void PrepareDirectoryStructure() {
+    ASSERT_TRUE(platform_.CreateDirectory(homedirs_.shadow_root()));
+    ASSERT_TRUE(platform_.CreateDirectory(
+        brillo::cryptohome::home::GetUserPathPrefix()));
+    // We only need the homedir path, not the vault/mount paths.
+    for (const auto& user : users_) {
+      ASSERT_TRUE(platform_.CreateDirectory(user.homedir_path));
+    }
+  }
+};
+
+// Successfully adds initial keyset
+TEST_F(KeysetManagementTest, AddInitialKeyset) {
+  // No key setup to test addition of the first keyset.
+
+  // TEST
+
+  EXPECT_TRUE(homedirs_.AddInitialKeyset(users_[0].credentials));
+
+  // VERIFY
+
+  std::vector<int> indicies;
+  EXPECT_TRUE(homedirs_.GetVaultKeysets(users_[0].obfuscated, &indicies));
+  EXPECT_THAT(indicies, ElementsAre(0));
+
+  VaultKeyset vk0;
+  vk0.Initialize(&platform_, homedirs_.crypto());
+  EXPECT_TRUE(homedirs_.GetValidKeyset(users_[0].credentials, &vk0,
+                                       /* error */ nullptr));
+  EXPECT_EQ(vk0.legacy_index(), 0);
+  EXPECT_EQ(vk0.label(), users_[0].credentials.key_data().label());
+  // Expect reset seed and chaps_key to be created.
+  EXPECT_TRUE(vk0.serialized().has_wrapped_chaps_key());
+  EXPECT_TRUE(vk0.serialized().has_wrapped_reset_seed());
+}
+
+}  // namespace cryptohome
diff --git a/cryptohome/old_homedirs_unittest.cc b/cryptohome/old_homedirs_unittest.cc
index 08aa4cf..cd88b66 100644
--- a/cryptohome/old_homedirs_unittest.cc
+++ b/cryptohome/old_homedirs_unittest.cc
@@ -403,34 +403,6 @@
                          OldKeysetManagementTest,
                          ::testing::Values(false));
 
-TEST_P(OldKeysetManagementTest, AddInitialKeyset) {
-  KeysetSetUp();
-
-  Credentials credentials(test_helper_.users[0].username,
-                          brillo::SecureBlob("passkey"));
-  KeyData key_data;
-  key_data.set_label("current label");
-  credentials.set_key_data(key_data);
-  SerializedVaultKeyset serialized;
-
-  // Caller of the mock factory will assume ownership.
-  auto vk = new MockVaultKeyset();
-  EXPECT_CALL(vault_keyset_factory_, New(_, _)).WillOnce(Return(vk));
-  homedirs_.set_vault_keyset_factory(&vault_keyset_factory_);
-
-  EXPECT_CALL(*vk, serialized()).WillRepeatedly(ReturnRef(serialized));
-  EXPECT_CALL(*vk, mutable_serialized()).WillRepeatedly(Return(&serialized));
-
-  EXPECT_CALL(*vk, CreateRandom()).Times(1);
-  EXPECT_CALL(*vk, set_legacy_index(0)).Times(1);
-
-  EXPECT_CALL(*vk, Encrypt(_, _)).WillRepeatedly(Return(true));
-  EXPECT_CALL(*vk, Save(_)).WillRepeatedly(Return(true));
-
-  EXPECT_TRUE(homedirs_.AddInitialKeyset(credentials));
-  EXPECT_EQ(key_data.label(), serialized.key_data().label());
-}
-
 TEST_P(OldKeysetManagementTest, AddKeysetSuccess) {
   KeysetSetUp();