chromium/components/device_signals/core/system_signals/win/win_platform_delegate_unittest.cc

// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/device_signals/core/system_signals/win/win_platform_delegate.h"

#include <array>

#include "base/base64.h"
#include "base/base_paths.h"
#include "base/environment.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/uuid.h"
#include "components/device_signals/test/win/scoped_executable_files.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace device_signals {

namespace {

// Using regular strings instead of file path literals as they will be used
// to construct all sorts of file paths, and also non-file-paths.
constexpr char kEnvironmentVariableName[] = "TestEnvironmentVariablePath";
constexpr char kTestFileName[] = "test_file";

constexpr char kExpectedSignedBase64PublicKey[] =
    "Rsw3wqh8gUxnMU8j2jGvvBMZqpe6OhIxn/WeEVg+pYQ=";
constexpr char kExpectedMultiSignedPrimaryBase64PublicKey[] =
    "ir/0opX6HPqsQlv4dFWqSx+nilORf7Q9474b2lGYZ94=";
constexpr char kExpectedMultiSignedSecondaryBase64PublicKey[] =
    "tzTDLyjSfGIMobYniu5f0JwZ5uSo0nmBV7T566A3vcQ=";

constexpr base::FilePath::CharType kInexistantFileName[] =
    FILE_PATH_LITERAL("does_not_exit");

}  // namespace

class WinPlatformDelegateTest : public testing::Test {
 protected:
  WinPlatformDelegateTest() : env_(base::Environment::Create()) {
    EXPECT_TRUE(scoped_dir_.CreateUniqueTempDir());
    absolute_file_path_ = scoped_dir_.GetPath().Append(
        base::FilePath::FromUTF8Unsafe(kTestFileName));
    EXPECT_TRUE(
        base::WriteFile(absolute_file_path_,
                        base::Uuid::GenerateRandomV4().AsLowercaseString()));

    env_->SetVar(kEnvironmentVariableName,
                 scoped_dir_.GetPath().AsUTF8Unsafe());
  }

  ~WinPlatformDelegateTest() override {
    env_->UnSetVar(kEnvironmentVariableName);
  }

  base::ScopedTempDir scoped_dir_;
  base::FilePath absolute_file_path_;
  std::unique_ptr<base::Environment> env_;
  test::ScopedExecutableFiles scoped_executable_files_;
  WinPlatformDelegate platform_delegate_;
};

TEST_F(WinPlatformDelegateTest, ResolveFilePath_Success) {
  std::string directory_name = scoped_dir_.GetPath().BaseName().AsUTF8Unsafe();

  std::array<std::string, 2> test_cases = {
      base::StrCat({"%", kEnvironmentVariableName, "%\\", kTestFileName}),
      base::StrCat({"%", kEnvironmentVariableName, "%\\..\\", directory_name,
                    "\\", kTestFileName})};

  for (const auto& test_case : test_cases) {
    base::FilePath resolved_fp;
    const base::FilePath test_case_fp =
        base::FilePath::FromUTF8Unsafe(test_case);
    EXPECT_TRUE(platform_delegate_.ResolveFilePath(test_case_fp, &resolved_fp));
    EXPECT_TRUE(base::ContentsEqual(absolute_file_path_, resolved_fp));
  }
}

TEST_F(WinPlatformDelegateTest, ResolveFilePath_Fail) {
  base::FilePath resolved_fp;
  EXPECT_FALSE(platform_delegate_.ResolveFilePath(
      scoped_dir_.GetPath().Append(kInexistantFileName), &resolved_fp));
  EXPECT_EQ(resolved_fp, base::FilePath());
}

TEST_F(WinPlatformDelegateTest, GetSigningCertificatesPublicKeys_InvalidPath) {
  auto public_keys =
      platform_delegate_.GetSigningCertificatesPublicKeys(base::FilePath());
  ASSERT_TRUE(public_keys);
  EXPECT_EQ(public_keys->hashes.size(), 0U);
  EXPECT_FALSE(public_keys->is_os_verified);
  EXPECT_FALSE(public_keys->subject_name);
}

TEST_F(WinPlatformDelegateTest, GetSigningCertificatesPublicKeys_Signed) {
  base::FilePath signed_exe_path = scoped_executable_files_.GetSignedExePath();
  ASSERT_TRUE(base::PathExists(signed_exe_path));

  auto public_keys =
      platform_delegate_.GetSigningCertificatesPublicKeys(signed_exe_path);
  ASSERT_TRUE(public_keys);
  EXPECT_EQ(public_keys->hashes.size(), 1U);
  // The binary is properly signed, but with a self-signed cert that the OS
  // does not trust.
  EXPECT_FALSE(public_keys->is_os_verified);
  EXPECT_TRUE(public_keys->subject_name);
  EXPECT_EQ(public_keys->subject_name.value(), "Joe's-Software-Emporium");

  const std::string base64_encoded_public_key =
      base::Base64Encode(public_keys.value().hashes[0]);
  EXPECT_EQ(base64_encoded_public_key, kExpectedSignedBase64PublicKey);
}

TEST_F(WinPlatformDelegateTest, GetSigningCertificatesPublicKeys_MultiSigned) {
  base::FilePath multi_signed_exe_path =
      scoped_executable_files_.GetMultiSignedExePath();
  ASSERT_TRUE(base::PathExists(multi_signed_exe_path));

  auto public_keys = platform_delegate_.GetSigningCertificatesPublicKeys(
      multi_signed_exe_path);
  ASSERT_TRUE(public_keys);
  EXPECT_EQ(public_keys->hashes.size(), 2U);
  // The binary is properly signed, but with a self-signed cert that the OS
  // does not trust.
  EXPECT_FALSE(public_keys->is_os_verified);
  EXPECT_TRUE(public_keys->subject_name);
  EXPECT_EQ(public_keys->subject_name.value(), "SebL's-Software-Emporium");

  std::string base64_encoded_public_key =
      base::Base64Encode(public_keys.value().hashes[0]);
  EXPECT_EQ(base64_encoded_public_key,
            kExpectedMultiSignedPrimaryBase64PublicKey);
  base64_encoded_public_key = base::Base64Encode(public_keys.value().hashes[1]);
  EXPECT_EQ(base64_encoded_public_key,
            kExpectedMultiSignedSecondaryBase64PublicKey);
}

TEST_F(WinPlatformDelegateTest, GetSigningCertificatePublicKeysHash_Empty) {
  base::FilePath empty_exe_path = scoped_executable_files_.GetEmptyExePath();
  ASSERT_TRUE(base::PathExists(empty_exe_path));

  auto public_keys =
      platform_delegate_.GetSigningCertificatesPublicKeys(empty_exe_path);
  ASSERT_TRUE(public_keys);
  EXPECT_EQ(public_keys->hashes.size(), 0U);
  EXPECT_FALSE(public_keys->is_os_verified);
  EXPECT_FALSE(public_keys->subject_name);
}

TEST_F(WinPlatformDelegateTest, GetProductMetadata_Success) {
  base::FilePath metadata_exe_path =
      scoped_executable_files_.GetMetadataExePath();
  ASSERT_TRUE(base::PathExists(metadata_exe_path));

  auto metadata = platform_delegate_.GetProductMetadata(metadata_exe_path);

  ASSERT_TRUE(metadata);
  EXPECT_EQ(metadata->name, scoped_executable_files_.GetMetadataProductName());
  EXPECT_EQ(metadata->version,
            scoped_executable_files_.GetMetadataProductVersion());
}

TEST_F(WinPlatformDelegateTest, GetProductMetadata_Empty) {
  base::FilePath empty_exe_path = scoped_executable_files_.GetEmptyExePath();
  ASSERT_TRUE(base::PathExists(empty_exe_path));

  EXPECT_FALSE(platform_delegate_.GetProductMetadata(empty_exe_path));
}

}  // namespace device_signals