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
SetUp()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
IsIdentical(const NaClValidationCache & a,const NaClValidationCache & b) const30 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
TEST_F(NaClValidationCacheTest,Sanity)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
TEST_F(NaClValidationCacheTest,Sig1)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
TEST_F(NaClValidationCacheTest,Sig2)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
TEST_F(NaClValidationCacheTest,SigBoth)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
TEST_F(NaClValidationCacheTest,DoubleSet)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
TEST_F(NaClValidationCacheTest,EmptyIdentical)75 TEST_F(NaClValidationCacheTest, EmptyIdentical) {
76 ASSERT_TRUE(IsIdentical(cache1, cache2));
77 }
78
TEST_F(NaClValidationCacheTest,DifferentKeysNotIdentical)79 TEST_F(NaClValidationCacheTest, DifferentKeysNotIdentical) {
80 std::string key(key2);
81 cache2.SetValidationCacheKey(key);
82 ASSERT_FALSE(IsIdentical(cache1, cache2));
83 }
84
85
TEST_F(NaClValidationCacheTest,DifferentSizesNotIdentical)86 TEST_F(NaClValidationCacheTest, DifferentSizesNotIdentical) {
87 cache1.SetKnownToValidate(sig1);
88
89 ASSERT_FALSE(IsIdentical(cache1, cache2));
90 }
91
TEST_F(NaClValidationCacheTest,SameSigsIdentical)92 TEST_F(NaClValidationCacheTest, SameSigsIdentical) {
93 cache1.SetKnownToValidate(sig1);
94
95 cache2.SetKnownToValidate(sig1);
96
97 ASSERT_TRUE(IsIdentical(cache1, cache2));
98 }
99
TEST_F(NaClValidationCacheTest,DifferentSigsNotIdentical)100 TEST_F(NaClValidationCacheTest, DifferentSigsNotIdentical) {
101 cache1.SetKnownToValidate(sig1);
102
103 cache2.SetKnownToValidate(sig2);
104
105 ASSERT_FALSE(IsIdentical(cache1, cache2));
106 }
107
TEST_F(NaClValidationCacheTest,InOrderIdentical)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
TEST_F(NaClValidationCacheTest,QueryReorders)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
TEST_F(NaClValidationCacheTest,ForceNoReorder)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
TEST_F(NaClValidationCacheTest,SerializeDeserialize)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
TEST_F(NaClValidationCacheTest,SerializeDeserializeTruncated)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
TEST_F(NaClValidationCacheTest,DeserializeBadKey)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
TEST_F(NaClValidationCacheTest,DeserializeNothing)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
TEST_F(NaClValidationCacheTest,DeserializeJunk)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