• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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 <windows.h>
6 #include <atlstr.h>
7 #include <wincrypt.h>
8 #include <wintrust.h>
9 
10 #include "base/base_paths.h"
11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/logging.h"
16 #include "base/path_service.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_piece.h"
19 #include "base/strings/string_util.h"
20 #include "chrome/app/signature_validator_win.h"
21 #include "crypto/sha2.h"
22 #include "net/cert/test_root_certs.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 
25 namespace {
26 
27 const char kGoogleCertIssuer[] = "Google Inc";
28 const int CERT_BUFFER_SIZE = 1024;
29 
30 const base::FilePath::CharType kCertificateRelativePath[] =
31     FILE_PATH_LITERAL("chrome\\app\\test_data\\certificates\\");
32 const base::FilePath::CharType kDLLRelativePath[] =
33     FILE_PATH_LITERAL("chrome\\app\\test_data\\dlls\\");
34 
35 class SignatureValidatorTest : public testing::Test {
36  protected:
SignatureValidatorTest()37   SignatureValidatorTest() {}
38 
SetUp()39   void SetUp() OVERRIDE {
40     test_roots_ = net::TestRootCerts::GetInstance();
41     base::FilePath cert_path =
42         GetTestCertsDirectory().Append(L"AuthorityCert.cer");
43     base::FilePath other_cert_path =
44         GetTestCertsDirectory().Append(L"OtherAuthorityCert.cer");
45     test_roots_->AddFromFile(cert_path);
46     test_roots_->AddFromFile(other_cert_path);
47     EXPECT_FALSE(test_roots_->IsEmpty());
48 
49     SetExpectedHash(GetTestCertsDirectory().Append(L"ValidCert.cer"));
50   }
51 
TearDown()52   void TearDown() OVERRIDE {
53     test_roots_->Clear();
54     EXPECT_TRUE(test_roots_->IsEmpty());
55   }
56 
GetTestCertsDirectory()57   base::FilePath GetTestCertsDirectory() {
58     base::FilePath src_root;
59     PathService::Get(base::DIR_SOURCE_ROOT, &src_root);
60     return src_root.Append(kCertificateRelativePath);
61   }
62 
GetTestDLLsDirectory()63   base::FilePath GetTestDLLsDirectory() {
64     base::FilePath src_root;
65     PathService::Get(base::DIR_SOURCE_ROOT, &src_root);
66     return src_root.Append(kDLLRelativePath);
67   }
68 
SetExpectedHash(const base::FilePath & cert_path)69   void SetExpectedHash(const base::FilePath& cert_path) {
70     char cert_buffer[CERT_BUFFER_SIZE];
71     base::ReadFile(cert_path, cert_buffer, CERT_BUFFER_SIZE);
72 
73     PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING,
74         reinterpret_cast<byte*>(&cert_buffer),
75         CERT_BUFFER_SIZE);
76 
77     CRYPT_BIT_BLOB blob = cert->pCertInfo->SubjectPublicKeyInfo.PublicKey;
78     size_t public_key_length = blob.cbData;
79     uint8* public_key = blob.pbData;
80 
81     uint8 hash[crypto::kSHA256Length] = {0};
82 
83     base::StringPiece key_bytes(reinterpret_cast<char*>(public_key),
84                                 public_key_length);
85     crypto::SHA256HashString(key_bytes, hash, crypto::kSHA256Length);
86 
87     std::string public_key_hash =
88         base::StringToLowerASCII(base::HexEncode(hash, arraysize(hash)));
89     expected_hashes_.push_back(public_key_hash);
90   }
91 
RunTest(const wchar_t * dll_filename,bool isValid,bool isGoogle)92   void RunTest(const wchar_t* dll_filename, bool isValid, bool isGoogle) {
93     base::FilePath full_dll_path = GetTestDLLsDirectory().Append(dll_filename);
94     ASSERT_EQ(isValid, VerifyAuthenticodeSignature(full_dll_path));
95     ASSERT_EQ(isGoogle, VerifySignerIsGoogle(full_dll_path, kGoogleCertIssuer,
96                                              expected_hashes_));
97   }
98 
99  private:
100   net::TestRootCerts* test_roots_;
101   std::vector<std::string> expected_hashes_;
102 };
103 
104 }  // namespace
105 
TEST_F(SignatureValidatorTest,ValidSigTest)106 TEST_F(SignatureValidatorTest, ValidSigTest) {
107   RunTest(L"valid_sig.dll", true, true);
108 }
109 
TEST_F(SignatureValidatorTest,SelfSignedTest)110 TEST_F(SignatureValidatorTest, SelfSignedTest) {
111   RunTest(L"self_signed.dll", false, false);
112 }
113 
TEST_F(SignatureValidatorTest,NotSignedTest)114 TEST_F(SignatureValidatorTest, NotSignedTest) {
115   RunTest(L"not_signed.dll", false, false);
116 }
117 
TEST_F(SignatureValidatorTest,NotGoogleTest)118 TEST_F(SignatureValidatorTest, NotGoogleTest) {
119   RunTest(L"not_google.dll", true, false);
120 }
121 
TEST_F(SignatureValidatorTest,CertPinningTest)122 TEST_F(SignatureValidatorTest, CertPinningTest) {
123   RunTest(L"different_hash.dll", true, false);
124 }
125 
TEST_F(SignatureValidatorTest,ExpiredCertTest)126 TEST_F(SignatureValidatorTest, ExpiredCertTest) {
127   //TODO(caitkp): Figure out how to sign a dll with an expired cert.
128   RunTest(L"expired.dll", false, false);
129 }
130 
131 
132