cryptohome: Add label property to VaultKeyset class.

The VaultKeyset class, once loaded, always has the index set. Thus it is
possible now to derive the keyset label solely from the information
stored within the class. The change replaces the external derivation
function with a getter, which either users the label passed upon keyset
creation, or defaulted index-based value.

BUG=chromium:1124561
TEST=FEATURES="test noclean" USE="cryptohome_userdataauth_interface" emerge-hatch chromeos-base/cryptohome
TEST=tast run ${DUT_IP} hwsec.*

Change-Id: Icbcd332846d575b6b975ff7190a9ea647273e66d
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2465550
Commit-Queue: Daniil Lunev <dlunev@chromium.org>
Tested-by: Daniil Lunev <dlunev@chromium.org>
Reviewed-by: Leo Lai <cylai@google.com>
diff --git a/cryptohome/homedirs.cc b/cryptohome/homedirs.cc
index 5e888bb..b52ce16 100644
--- a/cryptohome/homedirs.cc
+++ b/cryptohome/homedirs.cc
@@ -57,23 +57,6 @@
 // Name of the mount directory.
 const char kMountDir[] = "mount";
 
-namespace {
-
-// Returns label of the given serialized vault keyset. The label is normally
-// specified in the keyset itself, but for a legacy keyset it has to be
-// automatically generated.
-std::string GetSerializedKeysetLabel(const SerializedVaultKeyset& serialized,
-                                     int key_index) {
-  if (!serialized.has_key_data()) {
-    // Fallback for legacy keys, for which the label has to be inferred from the
-    // index number.
-    return base::StringPrintf("%s%d", kKeyLegacyPrefix, key_index);
-  }
-  return serialized.key_data().label();
-}
-
-}  // namespace
-
 HomeDirs::HomeDirs()
     : default_platform_(new Platform()),
       platform_(default_platform_.get()),
@@ -179,8 +162,7 @@
     // Skip decrypt attempts if the label doesn't match.
     // Treat an empty creds label as a wildcard.
     if (!creds.key_data().label().empty() &&
-        creds.key_data().label() !=
-            GetSerializedKeysetLabel(vk->serialized(), index))
+        creds.key_data().label() != vk->label())
       continue;
     // Skip LE Credentials if not explicitly identified by a label, since we
     // don't want unnecessary wrong attempts.
@@ -296,7 +278,7 @@
     if (!LoadVaultKeysetForUser(obfuscated_username, index, vk.get())) {
       continue;
     }
-    if (GetSerializedKeysetLabel(vk->serialized(), index) == key_label) {
+    if (vk->label() == key_label) {
       return vk.release();
     }
   }
@@ -367,7 +349,7 @@
     if (!LoadVaultKeysetForUser(obfuscated_username, index, vk.get())) {
       continue;
     }
-    labels->push_back(GetSerializedKeysetLabel(vk->serialized(), index));
+    labels->push_back(vk->label());
   }
 
   return (labels->size() > 0);
diff --git a/cryptohome/homedirs_unittest.cc b/cryptohome/homedirs_unittest.cc
index c092493..352c768 100644
--- a/cryptohome/homedirs_unittest.cc
+++ b/cryptohome/homedirs_unittest.cc
@@ -735,6 +735,7 @@
           .WillRepeatedly(Return(true));
       EXPECT_CALL(*active_vks_[i], set_legacy_index(_))
           .Times(testing::AnyNumber());
+      EXPECT_CALL(*active_vks_[i], label()).WillRepeatedly(Return("legacy-0"));
     }
     active_vk_ = active_vks_[0];
 
@@ -824,6 +825,7 @@
       .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
   EXPECT_CALL(*active_vk_, Encrypt(newkey, _)).WillOnce(Return(true));
   EXPECT_CALL(*active_vks_[1], set_legacy_index(_));
+  EXPECT_CALL(*active_vks_[1], label()).WillOnce(Return(key_data.label()));
   EXPECT_CALL(*active_vks_[1], legacy_index()).WillOnce(Return(0));
   EXPECT_CALL(*active_vks_[1], source_file()).WillOnce(ReturnRef(vk_path));
   EXPECT_CALL(*active_vk_, Save(vk_path)).WillOnce(Return(true));
@@ -856,6 +858,7 @@
       platform_,
       OpenFile(Property(&FilePath::value, EndsWith("master.1")), StrEq("wx")))
       .WillOnce(Return(reinterpret_cast<FILE*>(0xbeefbeef)));
+  EXPECT_CALL(*active_vks_[1], label()).WillOnce(Return(key_data.label()));
 
   EXPECT_EQ(
       CRYPTOHOME_ERROR_KEY_LABEL_EXISTS,
@@ -1165,6 +1168,7 @@
 
   // Expect the 0 slot since it'll match all the fake keys.
   EXPECT_CALL(*active_vks_[0], set_legacy_index(0));
+  EXPECT_CALL(*active_vks_[0], label()).WillRepeatedly(Return("remove me"));
   // Return a different slot to make sure the code is using the right object.
   EXPECT_CALL(*active_vks_[0], legacy_index()).WillOnce(Return(1));
   // The VaultKeyset which will be removed will get index 2.
@@ -1195,6 +1199,7 @@
 
   serialized_.mutable_key_data()->set_label("a labeled key");
   std::vector<std::string> labels;
+  EXPECT_CALL(*active_vks_[0], label()).WillRepeatedly(Return("a labeled key"));
   EXPECT_TRUE(homedirs_.GetVaultKeysetLabels(
       credentials_->GetObfuscatedUsername(system_salt_), &labels));
   ASSERT_NE(0, labels.size());
diff --git a/cryptohome/mock_vault_keyset.h b/cryptohome/mock_vault_keyset.h
index e77e4d5..60f2a82 100644
--- a/cryptohome/mock_vault_keyset.h
+++ b/cryptohome/mock_vault_keyset.h
@@ -51,6 +51,7 @@
               Encrypt,
               (const brillo::SecureBlob&, const std::string&),
               (override));
+  MOCK_METHOD(std::string, label, (), (const, override));
   MOCK_METHOD(const SerializedVaultKeyset&, serialized, (), (const, override));
   MOCK_METHOD(SerializedVaultKeyset*, mutable_serialized, (), (override));
   MOCK_METHOD(const base::FilePath&, source_file, (), (const, override));
diff --git a/cryptohome/vault_keyset.cc b/cryptohome/vault_keyset.cc
index 80d26b5..d6cc523 100644
--- a/cryptohome/vault_keyset.cc
+++ b/cryptohome/vault_keyset.cc
@@ -19,6 +19,7 @@
 
 namespace {
 const mode_t kVaultFilePermissions = 0600;
+const char kKeyLegacyPrefix[] = "legacy-";
 }
 
 namespace cryptohome {
@@ -336,6 +337,15 @@
   return ok;
 }
 
+std::string VaultKeyset::label() const {
+  if (serialized_.has_key_data()) {
+    return serialized_.key_data().label();
+  }
+  // Fallback for legacy keys, for which the label has to be inferred from the
+  // index number.
+  return base::StringPrintf("%s%d", kKeyLegacyPrefix, legacy_index_);
+}
+
 bool VaultKeyset::IsLECredential() const {
   return serialized_.key_data().policy().low_entropy_credential();
 }
diff --git a/cryptohome/vault_keyset.h b/cryptohome/vault_keyset.h
index e46d530..623f9ba 100644
--- a/cryptohome/vault_keyset.h
+++ b/cryptohome/vault_keyset.h
@@ -61,6 +61,7 @@
   virtual bool Save(const base::FilePath& filename);
   virtual bool Encrypt(const brillo::SecureBlob& key,
                        const std::string& obfuscated_username);
+  virtual std::string label() const;
   virtual const SerializedVaultKeyset& serialized() const {
     return serialized_;
   }