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.
9 #include "base/base_paths.h"
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/logging.h"
15 #include "base/path_service.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_piece.h"
18 #include "base/strings/string_util.h"
19 #include "chrome/app/signature_validator_win.h"
20 #include "crypto/sha2.h"
21 #include "crypto/wincrypt_shim.h"
22 #include "net/cert/test_root_certs.h"
23 #include "testing/gtest/include/gtest/gtest.h"
27 const char kGoogleCertIssuer
[] = "Google Inc";
28 const int CERT_BUFFER_SIZE
= 1024;
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\\");
35 class SignatureValidatorTest
: public testing::Test
{
37 SignatureValidatorTest() {}
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());
49 SetExpectedHash(GetTestCertsDirectory().Append(L
"ValidCert.cer"));
52 void TearDown() override
{
54 EXPECT_TRUE(test_roots_
->IsEmpty());
57 base::FilePath
GetTestCertsDirectory() {
58 base::FilePath src_root
;
59 PathService::Get(base::DIR_SOURCE_ROOT
, &src_root
);
60 return src_root
.Append(kCertificateRelativePath
);
63 base::FilePath
GetTestDLLsDirectory() {
64 base::FilePath src_root
;
65 PathService::Get(base::DIR_SOURCE_ROOT
, &src_root
);
66 return src_root
.Append(kDLLRelativePath
);
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
);
73 PCCERT_CONTEXT cert
= CertCreateCertificateContext(X509_ASN_ENCODING
,
74 reinterpret_cast<byte
*>(&cert_buffer
),
77 CRYPT_BIT_BLOB blob
= cert
->pCertInfo
->SubjectPublicKeyInfo
.PublicKey
;
78 size_t public_key_length
= blob
.cbData
;
79 uint8
* public_key
= blob
.pbData
;
81 uint8 hash
[crypto::kSHA256Length
] = {0};
83 base::StringPiece
key_bytes(reinterpret_cast<char*>(public_key
),
85 crypto::SHA256HashString(key_bytes
, hash
, crypto::kSHA256Length
);
87 std::string public_key_hash
=
88 base::ToLowerASCII(base::HexEncode(hash
, arraysize(hash
)));
89 expected_hashes_
.push_back(public_key_hash
);
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
,
100 net::TestRootCerts
* test_roots_
;
101 std::vector
<std::string
> expected_hashes_
;
106 TEST_F(SignatureValidatorTest
, ValidSigTest
) {
107 RunTest(L
"valid_sig.dll", true, true);
110 TEST_F(SignatureValidatorTest
, SelfSignedTest
) {
111 RunTest(L
"self_signed.dll", false, false);
114 TEST_F(SignatureValidatorTest
, NotSignedTest
) {
115 RunTest(L
"not_signed.dll", false, false);
118 TEST_F(SignatureValidatorTest
, NotGoogleTest
) {
119 RunTest(L
"not_google.dll", true, false);
122 TEST_F(SignatureValidatorTest
, CertPinningTest
) {
123 RunTest(L
"different_hash.dll", true, false);
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);