OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "chrome/nacl/nacl_validation_db.h" | |
6 #include "chrome/nacl/nacl_validation_query.h" | |
7 #include "testing/gtest/include/gtest/gtest.h" | |
8 | |
9 // This test makes sure that validation signature generation is performed | |
10 // correctly. In effect, this means that we are checking all of the data | |
11 // (and no other data) we are passing the signature generator affects the final | |
12 // signature. To avoid tying the tests to a particular implementation, each | |
13 // test generates two signatures and compares them rather than trying to compare | |
14 // against a specified signature. | |
15 | |
16 namespace { | |
17 | |
18 const char kKey[] = "bogus key for HMAC..."; | |
19 const char kKeyAlt[] = "bogus key for HMAC!!!"; | |
20 | |
21 const char kVersion[] = "bogus version"; | |
22 const char kVersionAlt[] = "bogus!version"; | |
23 | |
24 | |
25 const char kShortData[] = "Short data 1234567890"; | |
26 const char kAltShortData[] = "Short!data 1234567890"; | |
27 | |
28 const char kLongData[] = "Long data." | |
29 "1234567890123456789012345678901234567890123456789012345678901234567890" | |
30 "1234567890123456789012345678901234567890123456789012345678901234567890" | |
31 "1234567890123456789012345678901234567890123456789012345678901234567890" | |
32 "1234567890123456789012345678901234567890123456789012345678901234567890"; | |
33 | |
34 class MockValidationDB : public NaClValidationDB { | |
35 public: | |
36 MockValidationDB() | |
37 : did_query_(false), | |
38 did_set_(false), | |
39 status_(true) { | |
40 } | |
41 | |
42 virtual bool QueryKnownToValidate(const std::string& signature) OVERRIDE { | |
43 // The typecast is needed to work around gtest trying to take the address | |
44 // of a constant. | |
45 EXPECT_EQ((int) NaClValidationQuery::kDigestLength, | |
46 (int) signature.length()); | |
47 EXPECT_FALSE(did_query_); | |
48 EXPECT_FALSE(did_set_); | |
49 did_query_ = true; | |
50 memcpy(query_signature_, signature.data(), | |
51 NaClValidationQuery::kDigestLength); | |
52 return status_; | |
53 } | |
54 | |
55 virtual void SetKnownToValidate(const std::string& signature) OVERRIDE { | |
56 // The typecast is needed to work around gtest trying to take the address | |
57 // of a constant. | |
58 ASSERT_EQ((int) NaClValidationQuery::kDigestLength, | |
59 (int) signature.length()); | |
60 EXPECT_TRUE(did_query_); | |
61 EXPECT_FALSE(did_set_); | |
62 did_set_ = true; | |
63 memcpy(set_signature_, signature.data(), | |
64 NaClValidationQuery::kDigestLength); | |
65 // Signatures should be the same. | |
66 EXPECT_EQ(0, memcmp(query_signature_, set_signature_, | |
67 NaClValidationQuery::kDigestLength)); | |
68 } | |
69 | |
70 virtual bool ResolveFileToken(struct NaClFileToken* file_token, int32* fd, | |
71 std::string* path) OVERRIDE { | |
72 *fd = -1; | |
73 *path = ""; | |
74 return false; | |
75 } | |
76 | |
77 bool did_query_; | |
78 bool did_set_; | |
79 bool status_; | |
80 | |
81 uint8 query_signature_[NaClValidationQuery::kDigestLength]; | |
82 uint8 set_signature_[NaClValidationQuery::kDigestLength]; | |
83 }; | |
84 | |
85 class TestQuery { | |
86 public: | |
87 TestQuery(const char* key, const char* version) { | |
88 db.reset(new MockValidationDB()); | |
89 context.reset(new NaClValidationQueryContext(db.get(), key, version)); | |
90 query.reset(context->CreateQuery()); | |
91 } | |
92 | |
93 scoped_ptr<MockValidationDB> db; | |
94 scoped_ptr<NaClValidationQueryContext> context; | |
95 scoped_ptr<NaClValidationQuery> query; | |
96 }; | |
97 | |
98 class NaClValidationQueryTest : public ::testing::Test { | |
99 protected: | |
100 scoped_ptr<TestQuery> query1; | |
101 scoped_ptr<TestQuery> query2; | |
102 | |
103 virtual void SetUp() { | |
104 query1.reset(new TestQuery(kKey, kVersion)); | |
105 query2.reset(new TestQuery(kKey, kVersion)); | |
106 } | |
107 | |
108 void AssertQuerySame() { | |
109 ASSERT_TRUE(query1->db->did_query_); | |
110 ASSERT_TRUE(query2->db->did_query_); | |
111 ASSERT_EQ(0, memcmp(query1->db->query_signature_, | |
112 query2->db->query_signature_, | |
113 NaClValidationQuery::kDigestLength)); | |
114 } | |
115 | |
116 void AssertQueryDifferent() { | |
117 ASSERT_TRUE(query1->db->did_query_); | |
118 ASSERT_TRUE(query2->db->did_query_); | |
119 ASSERT_NE(0, memcmp(query1->db->query_signature_, | |
120 query2->db->query_signature_, | |
121 NaClValidationQuery::kDigestLength)); | |
122 } | |
123 }; | |
124 | |
125 TEST_F(NaClValidationQueryTest, Sanity) { | |
126 query1->query->AddData(kShortData, sizeof(kShortData)); | |
127 ASSERT_FALSE(query1->db->did_query_); | |
128 ASSERT_FALSE(query1->db->did_set_); | |
129 ASSERT_EQ(1, query1->query->QueryKnownToValidate()); | |
130 ASSERT_TRUE(query1->db->did_query_); | |
131 ASSERT_FALSE(query1->db->did_set_); | |
132 query1->query->SetKnownToValidate(); | |
133 ASSERT_TRUE(query1->db->did_query_); | |
134 ASSERT_TRUE(query1->db->did_set_); | |
135 } | |
136 | |
137 TEST_F(NaClValidationQueryTest, ConsistentShort) { | |
138 query1->query->AddData(kShortData, sizeof(kShortData)); | |
139 query1->query->QueryKnownToValidate(); | |
140 | |
141 query2->query->AddData(kShortData, sizeof(kShortData)); | |
142 query2->query->QueryKnownToValidate(); | |
143 | |
144 AssertQuerySame(); | |
145 } | |
146 | |
147 TEST_F(NaClValidationQueryTest, InconsistentShort) { | |
148 query1->query->AddData(kShortData, sizeof(kShortData)); | |
149 query1->query->QueryKnownToValidate(); | |
150 | |
151 query2->query->AddData(kAltShortData, sizeof(kAltShortData)); | |
152 query2->query->QueryKnownToValidate(); | |
153 | |
154 AssertQueryDifferent(); | |
155 } | |
156 | |
157 // Test for a bug caught during development where AddData would accidently | |
158 // overwrite previously written data and add uninitialzied memory to the hash. | |
159 TEST_F(NaClValidationQueryTest, ConsistentShortBug) { | |
160 query1->query->AddData(kShortData, sizeof(kShortData)); | |
161 query1->query->AddData(kShortData, sizeof(kShortData)); | |
162 query1->query->QueryKnownToValidate(); | |
163 | |
164 query2->query->AddData(kShortData, sizeof(kShortData)); | |
165 query2->query->AddData(kShortData, sizeof(kShortData)); | |
166 query2->query->QueryKnownToValidate(); | |
167 | |
168 AssertQuerySame(); | |
169 } | |
170 | |
171 // Test for a bug caught during development where AddData would accidently | |
172 // overwrite previously written data and add uninitialzed memory to the hash. | |
173 TEST_F(NaClValidationQueryTest, InconsistentShortBug1) { | |
174 query1->query->AddData(kShortData, sizeof(kShortData)); | |
175 query1->query->AddData(kShortData, sizeof(kShortData)); | |
176 query1->query->QueryKnownToValidate(); | |
177 | |
178 query2->query->AddData(kAltShortData, sizeof(kAltShortData)); | |
179 query2->query->AddData(kShortData, sizeof(kShortData)); | |
180 query2->query->QueryKnownToValidate(); | |
181 | |
182 AssertQueryDifferent(); | |
183 } | |
184 | |
185 // Make sure we don't ignore the second bit of data. | |
186 TEST_F(NaClValidationQueryTest, InconsistentShort2) { | |
187 query1->query->AddData(kShortData, sizeof(kShortData)); | |
188 query1->query->AddData(kShortData, sizeof(kShortData)); | |
189 query1->query->QueryKnownToValidate(); | |
190 | |
191 query2->query->AddData(kShortData, sizeof(kShortData)); | |
192 query2->query->AddData(kAltShortData, sizeof(kAltShortData)); | |
193 query2->query->QueryKnownToValidate(); | |
194 | |
195 AssertQueryDifferent(); | |
196 } | |
197 | |
198 TEST_F(NaClValidationQueryTest, InconsistentZeroSizedAdd) { | |
199 query1->query->AddData(kShortData, sizeof(kShortData)); | |
200 query1->query->QueryKnownToValidate(); | |
201 | |
202 query2->query->AddData(kShortData, sizeof(kShortData)); | |
203 query2->query->AddData(kShortData, 0); | |
204 query2->query->QueryKnownToValidate(); | |
205 | |
206 AssertQueryDifferent(); | |
207 } | |
208 | |
209 TEST_F(NaClValidationQueryTest, ConsistentZeroSizedAdd) { | |
210 query1->query->AddData(kShortData, sizeof(kShortData)); | |
211 query1->query->AddData("a", 0); | |
212 query1->query->QueryKnownToValidate(); | |
213 | |
214 query2->query->AddData(kShortData, sizeof(kShortData)); | |
215 query2->query->AddData("b", 0); | |
216 query2->query->QueryKnownToValidate(); | |
217 | |
218 AssertQuerySame(); | |
219 } | |
220 | |
221 TEST_F(NaClValidationQueryTest, ConsistentRepeatedShort) { | |
222 for (int i = 0; i < 30; i++) { | |
223 query1->query->AddData(kShortData, sizeof(kShortData)); | |
224 } | |
225 query1->query->QueryKnownToValidate(); | |
226 | |
227 for (int i = 0; i < 30; i++) { | |
228 query2->query->AddData(kShortData, sizeof(kShortData)); | |
229 } | |
230 query2->query->QueryKnownToValidate(); | |
231 | |
232 AssertQuerySame(); | |
233 } | |
234 | |
235 TEST_F(NaClValidationQueryTest, ConsistentLong) { | |
236 query1->query->AddData(kLongData, sizeof(kLongData)); | |
237 query1->query->QueryKnownToValidate(); | |
238 | |
239 query2->query->AddData(kLongData, sizeof(kLongData)); | |
240 query2->query->QueryKnownToValidate(); | |
241 | |
242 AssertQuerySame(); | |
243 } | |
244 | |
245 TEST_F(NaClValidationQueryTest, ConsistentRepeatedLong) { | |
246 for (int i = 0; i < 30; i++) { | |
247 query1->query->AddData(kLongData, sizeof(kLongData)); | |
248 } | |
249 query1->query->QueryKnownToValidate(); | |
250 | |
251 for (int i = 0; i < 30; i++) { | |
252 query2->query->AddData(kLongData, sizeof(kLongData)); | |
253 } | |
254 query2->query->QueryKnownToValidate(); | |
255 | |
256 AssertQuerySame(); | |
257 } | |
258 | |
259 TEST_F(NaClValidationQueryTest, PerturbKey) { | |
260 query2.reset(new TestQuery(kKeyAlt, kVersion)); | |
261 | |
262 query1->query->AddData(kShortData, sizeof(kShortData)); | |
263 query1->query->QueryKnownToValidate(); | |
264 | |
265 query2->query->AddData(kShortData, sizeof(kShortData)); | |
266 query2->query->QueryKnownToValidate(); | |
267 | |
268 AssertQueryDifferent(); | |
269 } | |
270 | |
271 TEST_F(NaClValidationQueryTest, PerturbVersion) { | |
272 query2.reset(new TestQuery(kKey, kVersionAlt)); | |
273 | |
274 query1->query->AddData(kShortData, sizeof(kShortData)); | |
275 query1->query->QueryKnownToValidate(); | |
276 | |
277 query2->query->AddData(kShortData, sizeof(kShortData)); | |
278 query2->query->QueryKnownToValidate(); | |
279 | |
280 AssertQueryDifferent(); | |
281 } | |
282 | |
283 } | |
OLD | NEW |