nacl_validation_query_unittest.cc 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  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. #include "components/nacl/loader/nacl_validation_query.h"
  5. #include <stdint.h>
  6. #include <memory>
  7. #include "components/nacl/loader/nacl_validation_db.h"
  8. #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.
  15. namespace {
  16. const char kKey[] = "bogus key for HMAC...";
  17. const char kKeyAlt[] = "bogus key for HMAC!!!";
  18. const char kVersion[] = "bogus version";
  19. const char kVersionAlt[] = "bogus!version";
  20. const char kShortData[] = "Short data 1234567890";
  21. const char kAltShortData[] = "Short!data 1234567890";
  22. const char kLongData[] = "Long data."
  23. "1234567890123456789012345678901234567890123456789012345678901234567890"
  24. "1234567890123456789012345678901234567890123456789012345678901234567890"
  25. "1234567890123456789012345678901234567890123456789012345678901234567890"
  26. "1234567890123456789012345678901234567890123456789012345678901234567890";
  27. class MockValidationDB : public NaClValidationDB {
  28. public:
  29. MockValidationDB()
  30. : did_query_(false),
  31. did_set_(false),
  32. status_(true) {
  33. }
  34. bool QueryKnownToValidate(const std::string& signature) override {
  35. // The typecast is needed to work around gtest trying to take the address
  36. // of a constant.
  37. EXPECT_EQ((int) NaClValidationQuery::kDigestLength,
  38. (int) signature.length());
  39. EXPECT_FALSE(did_query_);
  40. EXPECT_FALSE(did_set_);
  41. did_query_ = true;
  42. memcpy(query_signature_, signature.data(),
  43. NaClValidationQuery::kDigestLength);
  44. return status_;
  45. }
  46. void SetKnownToValidate(const std::string& signature) override {
  47. // The typecast is needed to work around gtest trying to take the address
  48. // of a constant.
  49. ASSERT_EQ((int) NaClValidationQuery::kDigestLength,
  50. (int) signature.length());
  51. EXPECT_TRUE(did_query_);
  52. EXPECT_FALSE(did_set_);
  53. did_set_ = true;
  54. memcpy(set_signature_, signature.data(),
  55. NaClValidationQuery::kDigestLength);
  56. // Signatures should be the same.
  57. EXPECT_EQ(0, memcmp(query_signature_, set_signature_,
  58. NaClValidationQuery::kDigestLength));
  59. }
  60. bool did_query_;
  61. bool did_set_;
  62. bool status_;
  63. uint8_t query_signature_[NaClValidationQuery::kDigestLength];
  64. uint8_t set_signature_[NaClValidationQuery::kDigestLength];
  65. };
  66. class TestQuery {
  67. public:
  68. TestQuery(const char* key, const char* version) {
  69. db = std::make_unique<MockValidationDB>();
  70. context =
  71. std::make_unique<NaClValidationQueryContext>(db.get(), key, version);
  72. query.reset(context->CreateQuery());
  73. }
  74. std::unique_ptr<MockValidationDB> db;
  75. std::unique_ptr<NaClValidationQueryContext> context;
  76. std::unique_ptr<NaClValidationQuery> query;
  77. };
  78. class NaClValidationQueryTest : public ::testing::Test {
  79. protected:
  80. std::unique_ptr<TestQuery> query1;
  81. std::unique_ptr<TestQuery> query2;
  82. void SetUp() override {
  83. query1 = std::make_unique<TestQuery>(kKey, kVersion);
  84. query2 = std::make_unique<TestQuery>(kKey, kVersion);
  85. }
  86. void AssertQuerySame() {
  87. ASSERT_TRUE(query1->db->did_query_);
  88. ASSERT_TRUE(query2->db->did_query_);
  89. ASSERT_EQ(0, memcmp(query1->db->query_signature_,
  90. query2->db->query_signature_,
  91. NaClValidationQuery::kDigestLength));
  92. }
  93. void AssertQueryDifferent() {
  94. ASSERT_TRUE(query1->db->did_query_);
  95. ASSERT_TRUE(query2->db->did_query_);
  96. ASSERT_NE(0, memcmp(query1->db->query_signature_,
  97. query2->db->query_signature_,
  98. NaClValidationQuery::kDigestLength));
  99. }
  100. };
  101. TEST_F(NaClValidationQueryTest, Sanity) {
  102. query1->query->AddData(kShortData, sizeof(kShortData));
  103. ASSERT_FALSE(query1->db->did_query_);
  104. ASSERT_FALSE(query1->db->did_set_);
  105. ASSERT_EQ(1, query1->query->QueryKnownToValidate());
  106. ASSERT_TRUE(query1->db->did_query_);
  107. ASSERT_FALSE(query1->db->did_set_);
  108. query1->query->SetKnownToValidate();
  109. ASSERT_TRUE(query1->db->did_query_);
  110. ASSERT_TRUE(query1->db->did_set_);
  111. }
  112. TEST_F(NaClValidationQueryTest, ConsistentShort) {
  113. query1->query->AddData(kShortData, sizeof(kShortData));
  114. query1->query->QueryKnownToValidate();
  115. query2->query->AddData(kShortData, sizeof(kShortData));
  116. query2->query->QueryKnownToValidate();
  117. AssertQuerySame();
  118. }
  119. TEST_F(NaClValidationQueryTest, InconsistentShort) {
  120. query1->query->AddData(kShortData, sizeof(kShortData));
  121. query1->query->QueryKnownToValidate();
  122. query2->query->AddData(kAltShortData, sizeof(kAltShortData));
  123. query2->query->QueryKnownToValidate();
  124. AssertQueryDifferent();
  125. }
  126. // Test for a bug caught during development where AddData would accidently
  127. // overwrite previously written data and add uninitialzied memory to the hash.
  128. TEST_F(NaClValidationQueryTest, ConsistentShortBug) {
  129. query1->query->AddData(kShortData, sizeof(kShortData));
  130. query1->query->AddData(kShortData, sizeof(kShortData));
  131. query1->query->QueryKnownToValidate();
  132. query2->query->AddData(kShortData, sizeof(kShortData));
  133. query2->query->AddData(kShortData, sizeof(kShortData));
  134. query2->query->QueryKnownToValidate();
  135. AssertQuerySame();
  136. }
  137. // Test for a bug caught during development where AddData would accidently
  138. // overwrite previously written data and add uninitialzed memory to the hash.
  139. TEST_F(NaClValidationQueryTest, InconsistentShortBug1) {
  140. query1->query->AddData(kShortData, sizeof(kShortData));
  141. query1->query->AddData(kShortData, sizeof(kShortData));
  142. query1->query->QueryKnownToValidate();
  143. query2->query->AddData(kAltShortData, sizeof(kAltShortData));
  144. query2->query->AddData(kShortData, sizeof(kShortData));
  145. query2->query->QueryKnownToValidate();
  146. AssertQueryDifferent();
  147. }
  148. // Make sure we don't ignore the second bit of data.
  149. TEST_F(NaClValidationQueryTest, InconsistentShort2) {
  150. query1->query->AddData(kShortData, sizeof(kShortData));
  151. query1->query->AddData(kShortData, sizeof(kShortData));
  152. query1->query->QueryKnownToValidate();
  153. query2->query->AddData(kShortData, sizeof(kShortData));
  154. query2->query->AddData(kAltShortData, sizeof(kAltShortData));
  155. query2->query->QueryKnownToValidate();
  156. AssertQueryDifferent();
  157. }
  158. TEST_F(NaClValidationQueryTest, InconsistentZeroSizedAdd) {
  159. query1->query->AddData(kShortData, sizeof(kShortData));
  160. query1->query->QueryKnownToValidate();
  161. query2->query->AddData(kShortData, sizeof(kShortData));
  162. query2->query->AddData(kShortData, 0);
  163. query2->query->QueryKnownToValidate();
  164. AssertQueryDifferent();
  165. }
  166. TEST_F(NaClValidationQueryTest, ConsistentZeroSizedAdd) {
  167. query1->query->AddData(kShortData, sizeof(kShortData));
  168. query1->query->AddData("a", 0);
  169. query1->query->QueryKnownToValidate();
  170. query2->query->AddData(kShortData, sizeof(kShortData));
  171. query2->query->AddData("b", 0);
  172. query2->query->QueryKnownToValidate();
  173. AssertQuerySame();
  174. }
  175. TEST_F(NaClValidationQueryTest, ConsistentRepeatedShort) {
  176. for (int i = 0; i < 30; i++) {
  177. query1->query->AddData(kShortData, sizeof(kShortData));
  178. }
  179. query1->query->QueryKnownToValidate();
  180. for (int i = 0; i < 30; i++) {
  181. query2->query->AddData(kShortData, sizeof(kShortData));
  182. }
  183. query2->query->QueryKnownToValidate();
  184. AssertQuerySame();
  185. }
  186. TEST_F(NaClValidationQueryTest, ConsistentLong) {
  187. query1->query->AddData(kLongData, sizeof(kLongData));
  188. query1->query->QueryKnownToValidate();
  189. query2->query->AddData(kLongData, sizeof(kLongData));
  190. query2->query->QueryKnownToValidate();
  191. AssertQuerySame();
  192. }
  193. TEST_F(NaClValidationQueryTest, ConsistentRepeatedLong) {
  194. for (int i = 0; i < 30; i++) {
  195. query1->query->AddData(kLongData, sizeof(kLongData));
  196. }
  197. query1->query->QueryKnownToValidate();
  198. for (int i = 0; i < 30; i++) {
  199. query2->query->AddData(kLongData, sizeof(kLongData));
  200. }
  201. query2->query->QueryKnownToValidate();
  202. AssertQuerySame();
  203. }
  204. TEST_F(NaClValidationQueryTest, PerturbKey) {
  205. query2 = std::make_unique<TestQuery>(kKeyAlt, kVersion);
  206. query1->query->AddData(kShortData, sizeof(kShortData));
  207. query1->query->QueryKnownToValidate();
  208. query2->query->AddData(kShortData, sizeof(kShortData));
  209. query2->query->QueryKnownToValidate();
  210. AssertQueryDifferent();
  211. }
  212. TEST_F(NaClValidationQueryTest, PerturbVersion) {
  213. query2 = std::make_unique<TestQuery>(kKey, kVersionAlt);
  214. query1->query->AddData(kShortData, sizeof(kShortData));
  215. query1->query->QueryKnownToValidate();
  216. query2->query->AddData(kShortData, sizeof(kShortData));
  217. query2->query->QueryKnownToValidate();
  218. AssertQueryDifferent();
  219. }
  220. }