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.
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"
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.
18 const char kKey
[] = "bogus key for HMAC...";
19 const char kKeyAlt
[] = "bogus key for HMAC!!!";
21 const char kVersion
[] = "bogus version";
22 const char kVersionAlt
[] = "bogus!version";
25 const char kShortData
[] = "Short data 1234567890";
26 const char kAltShortData
[] = "Short!data 1234567890";
28 const char kLongData
[] = "Long data."
29 "1234567890123456789012345678901234567890123456789012345678901234567890"
30 "1234567890123456789012345678901234567890123456789012345678901234567890"
31 "1234567890123456789012345678901234567890123456789012345678901234567890"
32 "1234567890123456789012345678901234567890123456789012345678901234567890";
34 class MockValidationDB
: public NaClValidationDB
{
42 virtual bool QueryKnownToValidate(const std::string
& signature
) OVERRIDE
{
43 // The typecast is needed to work around gtest trying to take the address
45 EXPECT_EQ((int) NaClValidationQuery::kDigestLength
,
46 (int) signature
.length());
47 EXPECT_FALSE(did_query_
);
48 EXPECT_FALSE(did_set_
);
50 memcpy(query_signature_
, signature
.data(),
51 NaClValidationQuery::kDigestLength
);
55 virtual void SetKnownToValidate(const std::string
& signature
) OVERRIDE
{
56 // The typecast is needed to work around gtest trying to take the address
58 ASSERT_EQ((int) NaClValidationQuery::kDigestLength
,
59 (int) signature
.length());
60 EXPECT_TRUE(did_query_
);
61 EXPECT_FALSE(did_set_
);
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
));
70 virtual bool ResolveFileToken(struct NaClFileToken
* file_token
, int32
* fd
,
71 std::string
* path
) OVERRIDE
{
81 uint8 query_signature_
[NaClValidationQuery::kDigestLength
];
82 uint8 set_signature_
[NaClValidationQuery::kDigestLength
];
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());
93 scoped_ptr
<MockValidationDB
> db
;
94 scoped_ptr
<NaClValidationQueryContext
> context
;
95 scoped_ptr
<NaClValidationQuery
> query
;
98 class NaClValidationQueryTest
: public ::testing::Test
{
100 scoped_ptr
<TestQuery
> query1
;
101 scoped_ptr
<TestQuery
> query2
;
103 virtual void SetUp() {
104 query1
.reset(new TestQuery(kKey
, kVersion
));
105 query2
.reset(new TestQuery(kKey
, kVersion
));
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
));
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
));
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_
);
137 TEST_F(NaClValidationQueryTest
, ConsistentShort
) {
138 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
139 query1
->query
->QueryKnownToValidate();
141 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
142 query2
->query
->QueryKnownToValidate();
147 TEST_F(NaClValidationQueryTest
, InconsistentShort
) {
148 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
149 query1
->query
->QueryKnownToValidate();
151 query2
->query
->AddData(kAltShortData
, sizeof(kAltShortData
));
152 query2
->query
->QueryKnownToValidate();
154 AssertQueryDifferent();
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();
164 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
165 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
166 query2
->query
->QueryKnownToValidate();
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();
178 query2
->query
->AddData(kAltShortData
, sizeof(kAltShortData
));
179 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
180 query2
->query
->QueryKnownToValidate();
182 AssertQueryDifferent();
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();
191 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
192 query2
->query
->AddData(kAltShortData
, sizeof(kAltShortData
));
193 query2
->query
->QueryKnownToValidate();
195 AssertQueryDifferent();
198 TEST_F(NaClValidationQueryTest
, InconsistentZeroSizedAdd
) {
199 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
200 query1
->query
->QueryKnownToValidate();
202 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
203 query2
->query
->AddData(kShortData
, 0);
204 query2
->query
->QueryKnownToValidate();
206 AssertQueryDifferent();
209 TEST_F(NaClValidationQueryTest
, ConsistentZeroSizedAdd
) {
210 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
211 query1
->query
->AddData("a", 0);
212 query1
->query
->QueryKnownToValidate();
214 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
215 query2
->query
->AddData("b", 0);
216 query2
->query
->QueryKnownToValidate();
221 TEST_F(NaClValidationQueryTest
, ConsistentRepeatedShort
) {
222 for (int i
= 0; i
< 30; i
++) {
223 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
225 query1
->query
->QueryKnownToValidate();
227 for (int i
= 0; i
< 30; i
++) {
228 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
230 query2
->query
->QueryKnownToValidate();
235 TEST_F(NaClValidationQueryTest
, ConsistentLong
) {
236 query1
->query
->AddData(kLongData
, sizeof(kLongData
));
237 query1
->query
->QueryKnownToValidate();
239 query2
->query
->AddData(kLongData
, sizeof(kLongData
));
240 query2
->query
->QueryKnownToValidate();
245 TEST_F(NaClValidationQueryTest
, ConsistentRepeatedLong
) {
246 for (int i
= 0; i
< 30; i
++) {
247 query1
->query
->AddData(kLongData
, sizeof(kLongData
));
249 query1
->query
->QueryKnownToValidate();
251 for (int i
= 0; i
< 30; i
++) {
252 query2
->query
->AddData(kLongData
, sizeof(kLongData
));
254 query2
->query
->QueryKnownToValidate();
259 TEST_F(NaClValidationQueryTest
, PerturbKey
) {
260 query2
.reset(new TestQuery(kKeyAlt
, kVersion
));
262 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
263 query1
->query
->QueryKnownToValidate();
265 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
266 query2
->query
->QueryKnownToValidate();
268 AssertQueryDifferent();
271 TEST_F(NaClValidationQueryTest
, PerturbVersion
) {
272 query2
.reset(new TestQuery(kKey
, kVersionAlt
));
274 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
275 query1
->query
->QueryKnownToValidate();
277 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
278 query2
->query
->QueryKnownToValidate();
280 AssertQueryDifferent();