| 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 |