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 "base/pickle.h" 6 #include "components/nacl/browser/nacl_validation_cache.h" 7 #include "testing/gtest/include/gtest/gtest.h" 8 9 namespace nacl { 10 11 const char key1[65] = 12 "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"; 13 const char key2[65] = 14 "a 64-byte string of various junk................................"; 15 const char sig1[33] = "0123456789ABCDEF0123456789ABCDEF"; 16 const char sig2[33] = "a 32-byte string of various junk"; 17 18 class NaClValidationCacheTest : public ::testing::Test { 19 protected: 20 NaClValidationCache cache1; 21 NaClValidationCache cache2; 22 23 virtual void SetUp() { 24 // The compiler chokes if std::string(key1) is passed directly as an arg. 25 std::string key(key1); 26 cache1.SetValidationCacheKey(key); 27 cache2.SetValidationCacheKey(key); 28 } 29 30 bool IsIdentical(const NaClValidationCache& a, 31 const NaClValidationCache& b) const { 32 if (a.GetValidationCacheKey() != b.GetValidationCacheKey()) 33 return false; 34 if (a.size() != b.size()) 35 return false; 36 return a.GetContents() == b.GetContents(); 37 } 38 }; 39 40 TEST_F(NaClValidationCacheTest, Sanity) { 41 ASSERT_EQ(0, (int) cache1.size()); 42 ASSERT_FALSE(cache1.QueryKnownToValidate(sig1, true)); 43 ASSERT_FALSE(cache1.QueryKnownToValidate(sig2, true)); 44 } 45 46 TEST_F(NaClValidationCacheTest, Sig1) { 47 cache1.SetKnownToValidate(sig1); 48 ASSERT_EQ(1, (int) cache1.size()); 49 ASSERT_TRUE(cache1.QueryKnownToValidate(sig1, true)); 50 ASSERT_FALSE(cache1.QueryKnownToValidate(sig2, true)); 51 } 52 53 TEST_F(NaClValidationCacheTest, Sig2) { 54 cache1.SetKnownToValidate(sig2); 55 ASSERT_EQ(1, (int) cache1.size()); 56 ASSERT_FALSE(cache1.QueryKnownToValidate(sig1, true)); 57 ASSERT_TRUE(cache1.QueryKnownToValidate(sig2, true)); 58 } 59 60 TEST_F(NaClValidationCacheTest, SigBoth) { 61 cache1.SetKnownToValidate(sig1); 62 cache1.SetKnownToValidate(sig2); 63 ASSERT_EQ(2, (int) cache1.size()); 64 ASSERT_TRUE(cache1.QueryKnownToValidate(sig1, true)); 65 ASSERT_TRUE(cache1.QueryKnownToValidate(sig2, true)); 66 } 67 68 TEST_F(NaClValidationCacheTest, DoubleSet) { 69 cache1.SetKnownToValidate(sig1); 70 cache1.SetKnownToValidate(sig1); 71 ASSERT_EQ(1, (int) cache1.size()); 72 ASSERT_TRUE(cache1.QueryKnownToValidate(sig1, true)); 73 } 74 75 TEST_F(NaClValidationCacheTest, EmptyIdentical) { 76 ASSERT_TRUE(IsIdentical(cache1, cache2)); 77 } 78 79 TEST_F(NaClValidationCacheTest, DifferentKeysNotIdentical) { 80 std::string key(key2); 81 cache2.SetValidationCacheKey(key); 82 ASSERT_FALSE(IsIdentical(cache1, cache2)); 83 } 84 85 86 TEST_F(NaClValidationCacheTest, DifferentSizesNotIdentical) { 87 cache1.SetKnownToValidate(sig1); 88 89 ASSERT_FALSE(IsIdentical(cache1, cache2)); 90 } 91 92 TEST_F(NaClValidationCacheTest, SameSigsIdentical) { 93 cache1.SetKnownToValidate(sig1); 94 95 cache2.SetKnownToValidate(sig1); 96 97 ASSERT_TRUE(IsIdentical(cache1, cache2)); 98 } 99 100 TEST_F(NaClValidationCacheTest, DifferentSigsNotIdentical) { 101 cache1.SetKnownToValidate(sig1); 102 103 cache2.SetKnownToValidate(sig2); 104 105 ASSERT_FALSE(IsIdentical(cache1, cache2)); 106 } 107 108 TEST_F(NaClValidationCacheTest, InOrderIdentical) { 109 cache1.SetKnownToValidate(sig1); 110 cache1.SetKnownToValidate(sig2); 111 112 cache2.SetKnownToValidate(sig1); 113 cache2.SetKnownToValidate(sig2); 114 115 ASSERT_TRUE(IsIdentical(cache1, cache2)); 116 } 117 118 TEST_F(NaClValidationCacheTest, QueryReorders) { 119 cache1.SetKnownToValidate(sig1); 120 cache1.SetKnownToValidate(sig2); 121 122 cache2.SetKnownToValidate(sig2); 123 cache2.SetKnownToValidate(sig1); 124 125 ASSERT_FALSE(IsIdentical(cache1, cache2)); 126 cache2.QueryKnownToValidate(sig2, true); 127 ASSERT_TRUE(IsIdentical(cache1, cache2)); 128 } 129 130 TEST_F(NaClValidationCacheTest, ForceNoReorder) { 131 cache1.SetKnownToValidate(sig1); 132 cache1.SetKnownToValidate(sig2); 133 134 cache2.SetKnownToValidate(sig2); 135 cache2.SetKnownToValidate(sig1); 136 137 cache2.QueryKnownToValidate(sig2, false); 138 ASSERT_FALSE(IsIdentical(cache1, cache2)); 139 } 140 141 TEST_F(NaClValidationCacheTest, SerializeDeserialize) { 142 std::string key(key2); 143 cache1.SetValidationCacheKey(key); 144 cache1.SetKnownToValidate(sig1); 145 cache1.SetKnownToValidate(sig2); 146 147 Pickle pickle; 148 cache1.Serialize(&pickle); 149 ASSERT_TRUE(cache2.Deserialize(&pickle)); 150 ASSERT_EQ(2, (int) cache2.size()); 151 ASSERT_TRUE(IsIdentical(cache1, cache2)); 152 } 153 154 TEST_F(NaClValidationCacheTest, SerializeDeserializeTruncated) { 155 std::string key(key2); 156 cache1.SetValidationCacheKey(key); 157 cache1.SetKnownToValidate(sig1); 158 cache1.SetKnownToValidate(sig2); 159 160 Pickle pickle; 161 cache1.Serialize(&pickle); 162 Pickle truncated(static_cast<const char*>(pickle.data()), pickle.size()-20); 163 ASSERT_FALSE(cache2.Deserialize(&truncated)); 164 ASSERT_EQ(0, (int) cache2.size()); 165 } 166 167 TEST_F(NaClValidationCacheTest, DeserializeBadKey) { 168 std::string key(sig1); // Too short, will cause the deserialization to error. 169 cache1.SetValidationCacheKey(key); 170 cache1.SetKnownToValidate(sig1); 171 cache1.SetKnownToValidate(sig2); 172 173 Pickle pickle; 174 cache1.Serialize(&pickle); 175 ASSERT_FALSE(cache2.Deserialize(&pickle)); 176 ASSERT_EQ(0, (int) cache2.size()); 177 } 178 179 TEST_F(NaClValidationCacheTest, DeserializeNothing) { 180 cache1.SetKnownToValidate(sig1); 181 Pickle pickle("", 0); 182 ASSERT_FALSE(cache1.Deserialize(&pickle)); 183 ASSERT_EQ(0, (int) cache1.size()); 184 } 185 186 TEST_F(NaClValidationCacheTest, DeserializeJunk) { 187 cache1.SetKnownToValidate(sig1); 188 Pickle pickle(key1, strlen(key1)); 189 ASSERT_FALSE(cache1.Deserialize(&pickle)); 190 ASSERT_EQ(0, (int) cache1.size()); 191 } 192 193 } 194