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 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 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
));
74 uint8 query_signature_
[NaClValidationQuery::kDigestLength
];
75 uint8 set_signature_
[NaClValidationQuery::kDigestLength
];
80 TestQuery(const char* key
, const char* version
) {
81 db
.reset(new MockValidationDB());
82 context
.reset(new NaClValidationQueryContext(db
.get(), key
, version
));
83 query
.reset(context
->CreateQuery());
86 scoped_ptr
<MockValidationDB
> db
;
87 scoped_ptr
<NaClValidationQueryContext
> context
;
88 scoped_ptr
<NaClValidationQuery
> query
;
91 class NaClValidationQueryTest
: public ::testing::Test
{
93 scoped_ptr
<TestQuery
> query1
;
94 scoped_ptr
<TestQuery
> query2
;
96 void SetUp() override
{
97 query1
.reset(new TestQuery(kKey
, kVersion
));
98 query2
.reset(new TestQuery(kKey
, kVersion
));
101 void AssertQuerySame() {
102 ASSERT_TRUE(query1
->db
->did_query_
);
103 ASSERT_TRUE(query2
->db
->did_query_
);
104 ASSERT_EQ(0, memcmp(query1
->db
->query_signature_
,
105 query2
->db
->query_signature_
,
106 NaClValidationQuery::kDigestLength
));
109 void AssertQueryDifferent() {
110 ASSERT_TRUE(query1
->db
->did_query_
);
111 ASSERT_TRUE(query2
->db
->did_query_
);
112 ASSERT_NE(0, memcmp(query1
->db
->query_signature_
,
113 query2
->db
->query_signature_
,
114 NaClValidationQuery::kDigestLength
));
118 TEST_F(NaClValidationQueryTest
, Sanity
) {
119 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
120 ASSERT_FALSE(query1
->db
->did_query_
);
121 ASSERT_FALSE(query1
->db
->did_set_
);
122 ASSERT_EQ(1, query1
->query
->QueryKnownToValidate());
123 ASSERT_TRUE(query1
->db
->did_query_
);
124 ASSERT_FALSE(query1
->db
->did_set_
);
125 query1
->query
->SetKnownToValidate();
126 ASSERT_TRUE(query1
->db
->did_query_
);
127 ASSERT_TRUE(query1
->db
->did_set_
);
130 TEST_F(NaClValidationQueryTest
, ConsistentShort
) {
131 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
132 query1
->query
->QueryKnownToValidate();
134 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
135 query2
->query
->QueryKnownToValidate();
140 TEST_F(NaClValidationQueryTest
, InconsistentShort
) {
141 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
142 query1
->query
->QueryKnownToValidate();
144 query2
->query
->AddData(kAltShortData
, sizeof(kAltShortData
));
145 query2
->query
->QueryKnownToValidate();
147 AssertQueryDifferent();
150 // Test for a bug caught during development where AddData would accidently
151 // overwrite previously written data and add uninitialzied memory to the hash.
152 TEST_F(NaClValidationQueryTest
, ConsistentShortBug
) {
153 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
154 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
155 query1
->query
->QueryKnownToValidate();
157 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
158 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
159 query2
->query
->QueryKnownToValidate();
164 // Test for a bug caught during development where AddData would accidently
165 // overwrite previously written data and add uninitialzed memory to the hash.
166 TEST_F(NaClValidationQueryTest
, InconsistentShortBug1
) {
167 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
168 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
169 query1
->query
->QueryKnownToValidate();
171 query2
->query
->AddData(kAltShortData
, sizeof(kAltShortData
));
172 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
173 query2
->query
->QueryKnownToValidate();
175 AssertQueryDifferent();
178 // Make sure we don't ignore the second bit of data.
179 TEST_F(NaClValidationQueryTest
, InconsistentShort2
) {
180 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
181 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
182 query1
->query
->QueryKnownToValidate();
184 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
185 query2
->query
->AddData(kAltShortData
, sizeof(kAltShortData
));
186 query2
->query
->QueryKnownToValidate();
188 AssertQueryDifferent();
191 TEST_F(NaClValidationQueryTest
, InconsistentZeroSizedAdd
) {
192 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
193 query1
->query
->QueryKnownToValidate();
195 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
196 query2
->query
->AddData(kShortData
, 0);
197 query2
->query
->QueryKnownToValidate();
199 AssertQueryDifferent();
202 TEST_F(NaClValidationQueryTest
, ConsistentZeroSizedAdd
) {
203 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
204 query1
->query
->AddData("a", 0);
205 query1
->query
->QueryKnownToValidate();
207 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
208 query2
->query
->AddData("b", 0);
209 query2
->query
->QueryKnownToValidate();
214 TEST_F(NaClValidationQueryTest
, ConsistentRepeatedShort
) {
215 for (int i
= 0; i
< 30; i
++) {
216 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
218 query1
->query
->QueryKnownToValidate();
220 for (int i
= 0; i
< 30; i
++) {
221 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
223 query2
->query
->QueryKnownToValidate();
228 TEST_F(NaClValidationQueryTest
, ConsistentLong
) {
229 query1
->query
->AddData(kLongData
, sizeof(kLongData
));
230 query1
->query
->QueryKnownToValidate();
232 query2
->query
->AddData(kLongData
, sizeof(kLongData
));
233 query2
->query
->QueryKnownToValidate();
238 TEST_F(NaClValidationQueryTest
, ConsistentRepeatedLong
) {
239 for (int i
= 0; i
< 30; i
++) {
240 query1
->query
->AddData(kLongData
, sizeof(kLongData
));
242 query1
->query
->QueryKnownToValidate();
244 for (int i
= 0; i
< 30; i
++) {
245 query2
->query
->AddData(kLongData
, sizeof(kLongData
));
247 query2
->query
->QueryKnownToValidate();
252 TEST_F(NaClValidationQueryTest
, PerturbKey
) {
253 query2
.reset(new TestQuery(kKeyAlt
, kVersion
));
255 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
256 query1
->query
->QueryKnownToValidate();
258 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
259 query2
->query
->QueryKnownToValidate();
261 AssertQueryDifferent();
264 TEST_F(NaClValidationQueryTest
, PerturbVersion
) {
265 query2
.reset(new TestQuery(kKey
, kVersionAlt
));
267 query1
->query
->AddData(kShortData
, sizeof(kShortData
));
268 query1
->query
->QueryKnownToValidate();
270 query2
->query
->AddData(kShortData
, sizeof(kShortData
));
271 query2
->query
->QueryKnownToValidate();
273 AssertQueryDifferent();