1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/crx_file/crx_verifier.h"
6 #include "base/base_paths.h"
7 #include "base/files/file_path.h"
8 #include "base/path_service.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "testing/gtest/include/gtest/gtest.h"
14 base::FilePath TestFile(const std::string& file) {
16 base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &path);
17 return path.AppendASCII("components")
20 .AppendASCII("crx_file")
24 constexpr char kOjjHash[] = "ojjgnpkioondelmggbekfhllhdaimnho";
25 constexpr char kOjjKey[] =
26 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA230uN7vYDEhdDlb4/"
27 "+pg2pfL8p0FFzCF/O146NB3D5dPKuLbnNphn0OUzOrDzR/Z1XLVDlDyiA6xnb+qeRp7H8n7Wk/"
28 "/gvVDNArZyForlVqWdaHLhl4dyZoNJwPKsggf30p/"
29 "MxCbNfy2rzFujzn2nguOrJKzWvNt0BFqssrBpzOQl69blBezE2ZYGOnYW8mPgQV29ekIgOfJk2"
30 "GgXoJBQQRRsjoPmUY7GDuEKudEB/"
32 "mCsHBHFWbqtGhSN4YCAw3DYQzwdTcIVaIA8f2Uo4AZ4INKkrEPRL8o9mZDYtO2YHIQg8pMSRMa"
33 "6AawBNYi9tZScnmgl5L1qE6z5oIwIDAQAB";
35 constexpr char kJlnHash[] = "jlnmailbicnpnbggmhfebbomaddckncf";
36 constexpr char kJlnKey[] =
37 "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtYd4M8wBjlPsc/wxS1/uXKMD6GtI7/"
40 "FO6Yi3XcJGtMvuojiB1j4bdiYBfvRgfTD4b7krWtWM2udKPBtHI9ikAT5aom5Bda8rCPNyaqXC"
41 "6Ax+KTgQpeeJglYu7TTd/"
42 "AePyvlRHtCKNkcvRQLY0b6hccALqoTzyTueDX12c8Htg76syEPbz7hSIPPfq6KEGvuVSxWAejy"
43 "/y6EhwAdXRLpegul9KmL94OY1G6dpycUKwyKeXOcB6Qj5iKNcOqJAaSLxoOZby4G3cI1BcQpp/"
44 "3vYccJ4qouDMfaanLe8CvFlLp4VOn833aJ8PYpLQIDAQAB";
50 using CrxVerifierTest = testing::Test;
52 TEST_F(CrxVerifierTest, ValidFullCrx3) {
53 const std::vector<std::vector<uint8_t>> keys;
54 const std::vector<uint8_t> hash;
55 std::string public_key = "UNSET";
56 std::string crx_id = "UNSET";
58 EXPECT_EQ(VerifierResult::OK_FULL,
59 Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX3,
60 keys, hash, &public_key, &crx_id,
61 /*compressed_verified_contents=*/nullptr));
62 EXPECT_EQ(std::string(kOjjHash), crx_id);
63 EXPECT_EQ(std::string(kOjjKey), public_key);
67 EXPECT_EQ(VerifierResult::OK_FULL,
68 Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX3,
69 keys, hash, &public_key, &crx_id,
70 /*compressed_verified_contents=*/nullptr));
71 EXPECT_EQ(std::string(kOjjHash), crx_id);
72 EXPECT_EQ(std::string(kOjjKey), public_key);
75 TEST_F(CrxVerifierTest, Crx3RejectsCrx2) {
76 const std::vector<std::vector<uint8_t>> keys;
77 const std::vector<uint8_t> hash;
78 std::string public_key = "UNSET";
79 std::string crx_id = "UNSET";
82 VerifierResult::ERROR_HEADER_INVALID,
83 Verify(TestFile("valid.crx2"), VerifierFormat::CRX3, keys, hash,
84 &public_key, &crx_id, /*compressed_verified_contents=*/nullptr));
85 EXPECT_EQ("UNSET", crx_id);
86 EXPECT_EQ("UNSET", public_key);
89 TEST_F(CrxVerifierTest, VerifiesFileHash) {
90 const std::vector<std::vector<uint8_t>> keys;
91 std::vector<uint8_t> hash;
92 EXPECT_TRUE(base::HexStringToBytes(
93 "d033c510f9e4ee081ccb60ea2bf530dc2e5cb0e71085b55503c8b13b74515fe4",
95 std::string public_key = "UNSET";
96 std::string crx_id = "UNSET";
98 EXPECT_EQ(VerifierResult::OK_FULL,
99 Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX3,
100 keys, hash, &public_key, &crx_id,
101 /*compressed_verified_contents=*/nullptr));
102 EXPECT_EQ(std::string(kOjjHash), crx_id);
103 EXPECT_EQ(std::string(kOjjKey), public_key);
106 EXPECT_TRUE(base::HexStringToBytes(std::string(32, '0'), &hash));
107 public_key = "UNSET";
109 EXPECT_EQ(VerifierResult::ERROR_EXPECTED_HASH_INVALID,
110 Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX3,
111 keys, hash, &public_key, &crx_id,
112 /*compressed_verified_contents=*/nullptr));
113 EXPECT_EQ("UNSET", crx_id);
114 EXPECT_EQ("UNSET", public_key);
117 EXPECT_TRUE(base::HexStringToBytes(std::string(64, '0'), &hash));
118 public_key = "UNSET";
120 EXPECT_EQ(VerifierResult::ERROR_FILE_HASH_FAILED,
121 Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX3,
122 keys, hash, &public_key, &crx_id,
123 /*compressed_verified_contents=*/nullptr));
124 EXPECT_EQ("UNSET", crx_id);
125 EXPECT_EQ("UNSET", public_key);
128 TEST_F(CrxVerifierTest, ChecksRequiredKeyHashes) {
129 const std::vector<uint8_t> hash;
131 std::vector<uint8_t> good_key;
132 EXPECT_TRUE(base::HexStringToBytes(
133 "e996dfa8eed34bc6614a57bb7308cd7e519bcc690841e1969f7cb173ef16800a",
135 const std::vector<std::vector<uint8_t>> good_keys = {good_key};
136 std::string public_key = "UNSET";
137 std::string crx_id = "UNSET";
138 EXPECT_EQ(VerifierResult::OK_FULL,
139 Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX3,
140 good_keys, hash, &public_key, &crx_id,
141 /*compressed_verified_contents=*/nullptr));
142 EXPECT_EQ(std::string(kOjjHash), crx_id);
143 EXPECT_EQ(std::string(kOjjKey), public_key);
145 std::vector<uint8_t> bad_key;
146 EXPECT_TRUE(base::HexStringToBytes(std::string(64, '0'), &bad_key));
147 const std::vector<std::vector<uint8_t>> bad_keys = {bad_key};
148 public_key = "UNSET";
150 EXPECT_EQ(VerifierResult::ERROR_REQUIRED_PROOF_MISSING,
151 Verify(TestFile("valid_no_publisher.crx3"), VerifierFormat::CRX3,
152 bad_keys, hash, &public_key, &crx_id,
153 /*compressed_verified_contents=*/nullptr));
154 EXPECT_EQ("UNSET", crx_id);
155 EXPECT_EQ("UNSET", public_key);
158 TEST_F(CrxVerifierTest, ChecksPinnedKey) {
159 const std::vector<uint8_t> hash;
160 const std::vector<std::vector<uint8_t>> keys;
161 std::string public_key = "UNSET";
162 std::string crx_id = "UNSET";
164 VerifierResult::OK_FULL,
165 Verify(TestFile("valid_publisher.crx3"),
166 VerifierFormat::CRX3_WITH_PUBLISHER_PROOF, keys, hash, &public_key,
167 &crx_id, /*compressed_verified_contents=*/nullptr));
168 EXPECT_EQ(std::string(kOjjHash), crx_id);
169 EXPECT_EQ(std::string(kOjjKey), public_key);
171 public_key = "UNSET";
174 VerifierResult::ERROR_REQUIRED_PROOF_MISSING,
175 Verify(TestFile("valid_test_publisher.crx3"),
176 VerifierFormat::CRX3_WITH_PUBLISHER_PROOF, keys, hash, &public_key,
177 &crx_id, /*compressed_verified_contents=*/nullptr));
178 EXPECT_EQ("UNSET", crx_id);
179 EXPECT_EQ("UNSET", public_key);
181 public_key = "UNSET";
184 VerifierResult::ERROR_REQUIRED_PROOF_MISSING,
185 Verify(TestFile("valid_no_publisher.crx3"),
186 VerifierFormat::CRX3_WITH_PUBLISHER_PROOF, keys, hash, &public_key,
187 &crx_id, /*compressed_verified_contents=*/nullptr));
188 EXPECT_EQ("UNSET", crx_id);
189 EXPECT_EQ("UNSET", public_key);
192 TEST_F(CrxVerifierTest, ChecksPinnedKeyAcceptsTest) {
193 const std::vector<uint8_t> hash;
194 const std::vector<std::vector<uint8_t>> keys;
195 std::string public_key = "UNSET";
196 std::string crx_id = "UNSET";
198 VerifierResult::OK_FULL,
199 Verify(TestFile("valid_publisher.crx3"),
200 VerifierFormat::CRX3_WITH_TEST_PUBLISHER_PROOF, keys, hash,
201 &public_key, &crx_id, /*compressed_verified_contents=*/nullptr));
202 EXPECT_EQ(std::string(kOjjHash), crx_id);
203 EXPECT_EQ(std::string(kOjjKey), public_key);
205 public_key = "UNSET";
208 VerifierResult::OK_FULL,
209 Verify(TestFile("valid_test_publisher.crx3"),
210 VerifierFormat::CRX3_WITH_TEST_PUBLISHER_PROOF, keys, hash,
211 &public_key, &crx_id, /*compressed_verified_contents=*/nullptr));
212 EXPECT_EQ(std::string(kJlnHash), crx_id);
213 EXPECT_EQ(std::string(kJlnKey), public_key);
215 public_key = "UNSET";
218 VerifierResult::ERROR_REQUIRED_PROOF_MISSING,
219 Verify(TestFile("valid_no_publisher.crx3"),
220 VerifierFormat::CRX3_WITH_TEST_PUBLISHER_PROOF, keys, hash,
221 &public_key, &crx_id, /*compressed_verified_contents=*/nullptr));
222 EXPECT_EQ("UNSET", crx_id);
223 EXPECT_EQ("UNSET", public_key);
226 TEST_F(CrxVerifierTest, NullptrSafe) {
227 const std::vector<uint8_t> hash;
228 const std::vector<std::vector<uint8_t>> keys;
229 EXPECT_EQ(VerifierResult::OK_FULL,
230 Verify(TestFile("valid_publisher.crx3"),
231 VerifierFormat::CRX3_WITH_PUBLISHER_PROOF, keys, hash,
232 nullptr, nullptr, /*compressed_verified_contents=*/nullptr));
235 TEST_F(CrxVerifierTest, RequiresDeveloperKey) {
236 const std::vector<uint8_t> hash;
237 const std::vector<std::vector<uint8_t>> keys;
238 std::string public_key = "UNSET";
239 std::string crx_id = "UNSET";
241 VerifierResult::ERROR_REQUIRED_PROOF_MISSING,
242 Verify(TestFile("unsigned.crx3"), VerifierFormat::CRX3, keys, hash,
243 &public_key, &crx_id, /*compressed_verified_contents=*/nullptr));
244 EXPECT_EQ("UNSET", crx_id);
245 EXPECT_EQ("UNSET", public_key);
248 // Verifies that `compressed_verified_contents` is not set when verified
249 // contents are not present in the header of the CRX.
250 TEST_F(CrxVerifierTest, ChecksCompressedVerifiedContentsEmpty) {
251 const std::vector<uint8_t> hash;
252 const std::vector<std::vector<uint8_t>> keys;
253 std::string public_key = "UNSET";
254 std::string crx_id = "UNSET";
255 std::vector<uint8_t> compressed_verified_contents;
256 EXPECT_EQ(VerifierResult::OK_FULL,
257 Verify(TestFile("valid_test_publisher.crx3"),
258 VerifierFormat::CRX3_WITH_TEST_PUBLISHER_PROOF, keys, hash,
259 &public_key, &crx_id, &compressed_verified_contents));
260 EXPECT_EQ(std::string(kJlnHash), crx_id);
261 EXPECT_EQ(std::string(kJlnKey), public_key);
262 EXPECT_TRUE(compressed_verified_contents.empty());
265 } // namespace crx_file