- add sources.
[platform/framework/web/crosswalk.git] / src / components / nacl / loader / nacl_validation_query_unittest.cc
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 "components/nacl/loader/nacl_validation_db.h"
6 #include "components/nacl/loader/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 }