Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: chrome/browser/metrics/variations/variations_seed_store_unittest.cc

Issue 183003008: Enforce variations signature verification. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/metrics/variations/variations_seed_store.h" 5 #include "chrome/browser/metrics/variations/variations_seed_store.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/prefs/testing_pref_service.h" 8 #include "base/prefs/testing_pref_service.h"
9 #include "base/sha1.h" 9 #include "base/sha1.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "chrome/common/pref_names.h" 12 #include "chrome/common/pref_names.h"
13 #include "components/variations/proto/study.pb.h" 13 #include "components/variations/proto/study.pb.h"
14 #include "components/variations/proto/variations_seed.pb.h" 14 #include "components/variations/proto/variations_seed.pb.h"
15 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
16 16
17 namespace chrome_variations { 17 namespace chrome_variations {
18 18
19 namespace { 19 namespace {
20 20
21 class TestVariationsSeedStore : public VariationsSeedStore {
22 public:
23 explicit TestVariationsSeedStore(PrefService* local_state)
24 : VariationsSeedStore(local_state) {}
25 virtual ~TestVariationsSeedStore() {}
26
27 virtual VariationsSeedStore::VerifySignatureResult VerifySeedSignature(
28 const std::string& seed_bytes,
29 const std::string& base64_seed_signature) OVERRIDE {
30 return VariationsSeedStore::VARIATIONS_SEED_SIGNATURE_ENUM_SIZE;
31 }
32
33 private:
34 DISALLOW_COPY_AND_ASSIGN(TestVariationsSeedStore);
35 };
36
37
21 // Populates |seed| with simple test data. The resulting seed will contain one 38 // Populates |seed| with simple test data. The resulting seed will contain one
22 // study called "test", which contains one experiment called "abc" with 39 // study called "test", which contains one experiment called "abc" with
23 // probability weight 100. |seed|'s study field will be cleared before adding 40 // probability weight 100. |seed|'s study field will be cleared before adding
24 // the new study. 41 // the new study.
25 VariationsSeed CreateTestSeed() { 42 VariationsSeed CreateTestSeed() {
26 VariationsSeed seed; 43 VariationsSeed seed;
27 Study* study = seed.add_study(); 44 Study* study = seed.add_study();
28 study->set_name("test"); 45 study->set_name("test");
29 study->set_default_experiment_name("abc"); 46 study->set_default_experiment_name("abc");
30 Study_Experiment* experiment = study->add_experiment(); 47 Study_Experiment* experiment = study->add_experiment();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 TEST(VariationsSeedStoreTest, LoadSeed) { 82 TEST(VariationsSeedStoreTest, LoadSeed) {
66 // Store good seed data to test if loading from prefs works. 83 // Store good seed data to test if loading from prefs works.
67 const VariationsSeed seed = CreateTestSeed(); 84 const VariationsSeed seed = CreateTestSeed();
68 std::string seed_hash; 85 std::string seed_hash;
69 const std::string base64_seed = SerializeSeedBase64(seed, &seed_hash); 86 const std::string base64_seed = SerializeSeedBase64(seed, &seed_hash);
70 87
71 TestingPrefServiceSimple prefs; 88 TestingPrefServiceSimple prefs;
72 VariationsSeedStore::RegisterPrefs(prefs.registry()); 89 VariationsSeedStore::RegisterPrefs(prefs.registry());
73 prefs.SetString(prefs::kVariationsSeed, base64_seed); 90 prefs.SetString(prefs::kVariationsSeed, base64_seed);
74 91
75 VariationsSeedStore seed_store(&prefs); 92 TestVariationsSeedStore seed_store(&prefs);
76 93
77 VariationsSeed loaded_seed; 94 VariationsSeed loaded_seed;
78 // Check that loading a seed without a hash pref set works correctly. 95 // Check that loading a seed without a hash pref set works correctly.
79 EXPECT_TRUE(seed_store.LoadSeed(&loaded_seed)); 96 EXPECT_TRUE(seed_store.LoadSeed(&loaded_seed));
80 97
81 // Check that the loaded data is the same as the original. 98 // Check that the loaded data is the same as the original.
82 EXPECT_EQ(SerializeSeed(seed), SerializeSeed(loaded_seed)); 99 EXPECT_EQ(SerializeSeed(seed), SerializeSeed(loaded_seed));
83 // Make sure the pref hasn't been changed. 100 // Make sure the pref hasn't been changed.
84 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); 101 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed));
85 EXPECT_EQ(base64_seed, prefs.GetString(prefs::kVariationsSeed)); 102 EXPECT_EQ(base64_seed, prefs.GetString(prefs::kVariationsSeed));
86 103
87 // Check that loading a seed with the correct hash works. 104 // Check that loading a seed with the correct hash works.
88 prefs.SetString(prefs::kVariationsSeedHash, seed_hash); 105 prefs.SetString(prefs::kVariationsSeedHash, seed_hash);
89 loaded_seed.Clear(); 106 loaded_seed.Clear();
90 EXPECT_TRUE(seed_store.LoadSeed(&loaded_seed)); 107 EXPECT_TRUE(seed_store.LoadSeed(&loaded_seed));
91 EXPECT_EQ(SerializeSeed(seed), SerializeSeed(loaded_seed)); 108 EXPECT_EQ(SerializeSeed(seed), SerializeSeed(loaded_seed));
92 109
93 // Check that false is returned and the pref is cleared when hash differs.
94 VariationsSeed different_seed = seed;
95 different_seed.mutable_study(0)->set_name("octopus");
96 std::string different_hash;
97 prefs.SetString(prefs::kVariationsSeed,
98 SerializeSeedBase64(different_seed, &different_hash));
99 ASSERT_NE(different_hash, prefs.GetString(prefs::kVariationsSeedHash));
100 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed));
101 EXPECT_FALSE(seed_store.LoadSeed(&loaded_seed));
102 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed));
103 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedDate));
104 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedHash));
105 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedSignature));
106
107 // Check that loading a bad seed returns false and clears the pref. 110 // Check that loading a bad seed returns false and clears the pref.
108 prefs.ClearPref(prefs::kVariationsSeed); 111 prefs.ClearPref(prefs::kVariationsSeed);
109 prefs.SetString(prefs::kVariationsSeed, "this should fail"); 112 prefs.SetString(prefs::kVariationsSeed, "this should fail");
110 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); 113 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed));
111 EXPECT_FALSE(seed_store.LoadSeed(&loaded_seed)); 114 EXPECT_FALSE(seed_store.LoadSeed(&loaded_seed));
112 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); 115 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed));
113 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedDate)); 116 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedDate));
114 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedHash));
115 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedSignature)); 117 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeedSignature));
116 118
117 // Check that having no seed in prefs results in a return value of false. 119 // Check that having no seed in prefs results in a return value of false.
118 prefs.ClearPref(prefs::kVariationsSeed); 120 prefs.ClearPref(prefs::kVariationsSeed);
119 EXPECT_FALSE(seed_store.LoadSeed(&loaded_seed)); 121 EXPECT_FALSE(seed_store.LoadSeed(&loaded_seed));
120 } 122 }
121 123
122 TEST(VariationsSeedStoreTest, StoreSeedData) { 124 TEST(VariationsSeedStoreTest, StoreSeedData) {
123 const base::Time now = base::Time::Now(); 125 const base::Time now = base::Time::Now();
124 const VariationsSeed seed = CreateTestSeed(); 126 const VariationsSeed seed = CreateTestSeed();
125 const std::string serialized_seed = SerializeSeed(seed); 127 const std::string serialized_seed = SerializeSeed(seed);
126 128
127 TestingPrefServiceSimple prefs; 129 TestingPrefServiceSimple prefs;
128 VariationsSeedStore::RegisterPrefs(prefs.registry()); 130 VariationsSeedStore::RegisterPrefs(prefs.registry());
129 131
130 VariationsSeedStore seed_store(&prefs); 132 TestVariationsSeedStore seed_store(&prefs);
131 133
132 EXPECT_TRUE(seed_store.StoreSeedData(serialized_seed, std::string(), now)); 134 EXPECT_TRUE(seed_store.StoreSeedData(serialized_seed, std::string(), now));
133 // Make sure the pref was actually set. 135 // Make sure the pref was actually set.
134 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); 136 EXPECT_FALSE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed));
135 137
136 std::string loaded_serialized_seed = prefs.GetString(prefs::kVariationsSeed); 138 std::string loaded_serialized_seed = prefs.GetString(prefs::kVariationsSeed);
137 std::string decoded_serialized_seed; 139 std::string decoded_serialized_seed;
138 ASSERT_TRUE(base::Base64Decode(loaded_serialized_seed, 140 ASSERT_TRUE(base::Base64Decode(loaded_serialized_seed,
139 &decoded_serialized_seed)); 141 &decoded_serialized_seed));
140 // Make sure the stored seed from pref is the same as the seed we created. 142 // Make sure the stored seed from pref is the same as the seed we created.
141 EXPECT_EQ(serialized_seed, decoded_serialized_seed); 143 EXPECT_EQ(serialized_seed, decoded_serialized_seed);
142 144
143 // Check if trying to store a bad seed leaves the pref unchanged. 145 // Check if trying to store a bad seed leaves the pref unchanged.
144 prefs.ClearPref(prefs::kVariationsSeed); 146 prefs.ClearPref(prefs::kVariationsSeed);
145 EXPECT_FALSE(seed_store.StoreSeedData("should fail", std::string(), now)); 147 EXPECT_FALSE(seed_store.StoreSeedData("should fail", std::string(), now));
146 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed)); 148 EXPECT_TRUE(PrefHasDefaultValue(prefs, prefs::kVariationsSeed));
147 } 149 }
148 150
151 TEST(VariationsSeedStoreTest, VerifySeedSignature) {
152 // The below seed and signature pair were generated using the server's
153 // private key.
154 const std::string base64_seed_data =
155 "CigxZDI5NDY0ZmIzZDc4ZmYxNTU2ZTViNTUxYzY0NDdjYmM3NGU1ZmQwEr0BCh9VTUEtVW5p"
156 "Zm9ybWl0eS1UcmlhbC0xMC1QZXJjZW50GICckqUFOAFCB2RlZmF1bHRKCwoHZGVmYXVsdBAB"
157 "SgwKCGdyb3VwXzAxEAFKDAoIZ3JvdXBfMDIQAUoMCghncm91cF8wMxABSgwKCGdyb3VwXzA0"
158 "EAFKDAoIZ3JvdXBfMDUQAUoMCghncm91cF8wNhABSgwKCGdyb3VwXzA3EAFKDAoIZ3JvdXBf"
159 "MDgQAUoMCghncm91cF8wORAB";
160 const std::string base64_seed_signature =
161 "MEQCIDD1IVxjzWYncun+9IGzqYjZvqxxujQEayJULTlbTGA/AiAr0oVmEgVUQZBYq5VLOSvy"
162 "96JkMYgzTkHPwbv7K/CmgA==";
163
164 std::string seed_data;
165 EXPECT_TRUE(base::Base64Decode(base64_seed_data, &seed_data));
166
167 VariationsSeedStore seed_store(NULL);
168
169 #if defined(OS_IOS) || defined(OS_ANDROID)
170 // Signature verification is not enabled on mobile.
171 if (seed_store.VerifySeedSignature(seed_data, base64_seed_signature) ==
172 VariationsSeedStore::VARIATIONS_SEED_SIGNATURE_ENUM_SIZE) {
173 return;
174 }
175 #endif
176
177 // The above inputs should be valid.
178 EXPECT_EQ(VariationsSeedStore::VARIATIONS_SEED_SIGNATURE_VALID,
179 seed_store.VerifySeedSignature(seed_data, base64_seed_signature));
180
181 // If there's no signature, the corresponding result should be returned.
182 EXPECT_EQ(VariationsSeedStore::VARIATIONS_SEED_SIGNATURE_MISSING,
183 seed_store.VerifySeedSignature(seed_data, std::string()));
184
185 // Using non-base64 encoded value as signature (e.g. seed data) should fail.
186 EXPECT_EQ(VariationsSeedStore::VARIATIONS_SEED_SIGNATURE_DECODE_FAILED,
187 seed_store.VerifySeedSignature(seed_data, seed_data));
188
189 // Using a different signature (e.g. the base64 seed data) should fail.
190 EXPECT_EQ(VariationsSeedStore::VARIATIONS_SEED_SIGNATURE_INVALID_SIGNATURE,
191 seed_store.VerifySeedSignature(seed_data, base64_seed_data));
192
193 // Using a different seed should not match the signature.
194 seed_data[0] = 'x';
195 EXPECT_EQ(VariationsSeedStore::VARIATIONS_SEED_SIGNATURE_INVALID_SEED,
196 seed_store.VerifySeedSignature(seed_data, base64_seed_signature));
197 }
198
149 } // namespace chrome_variations 199 } // namespace chrome_variations
OLDNEW
« no previous file with comments | « chrome/browser/metrics/variations/variations_seed_store.cc ('k') | chrome/browser/metrics/variations/variations_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698