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 9namespace nacl { 10 11const char key1[65] = 12 "0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"; 13const char key2[65] = 14 "a 64-byte string of various junk................................"; 15const char sig1[33] = "0123456789ABCDEF0123456789ABCDEF"; 16const char sig2[33] = "a 32-byte string of various junk"; 17 18class 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 40TEST_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 46TEST_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 53TEST_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 60TEST_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 68TEST_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 75TEST_F(NaClValidationCacheTest, EmptyIdentical) { 76 ASSERT_TRUE(IsIdentical(cache1, cache2)); 77} 78 79TEST_F(NaClValidationCacheTest, DifferentKeysNotIdentical) { 80 std::string key(key2); 81 cache2.SetValidationCacheKey(key); 82 ASSERT_FALSE(IsIdentical(cache1, cache2)); 83} 84 85 86TEST_F(NaClValidationCacheTest, DifferentSizesNotIdentical) { 87 cache1.SetKnownToValidate(sig1); 88 89 ASSERT_FALSE(IsIdentical(cache1, cache2)); 90} 91 92TEST_F(NaClValidationCacheTest, SameSigsIdentical) { 93 cache1.SetKnownToValidate(sig1); 94 95 cache2.SetKnownToValidate(sig1); 96 97 ASSERT_TRUE(IsIdentical(cache1, cache2)); 98} 99 100TEST_F(NaClValidationCacheTest, DifferentSigsNotIdentical) { 101 cache1.SetKnownToValidate(sig1); 102 103 cache2.SetKnownToValidate(sig2); 104 105 ASSERT_FALSE(IsIdentical(cache1, cache2)); 106} 107 108TEST_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 118TEST_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 130TEST_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 141TEST_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 154TEST_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 167TEST_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 179TEST_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 186TEST_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