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

Side by Side Diff: components/sync/base/cryptographer.cc

Issue 2130453004: [Sync] Move //sync to //components/sync. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 4 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
« no previous file with comments | « components/sync/base/cryptographer.h ('k') | components/sync/base/cryptographer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "sync/util/cryptographer.h" 5 #include "components/sync/base/cryptographer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8
8 #include <algorithm> 9 #include <algorithm>
9 #include <utility> 10 #include <utility>
10 11
11 #include "base/base64.h" 12 #include "base/base64.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "sync/protocol/nigori_specifics.pb.h" 14 #include "components/sync/base/encryptor.h"
14 #include "sync/util/encryptor.h" 15 #include "components/sync/protocol/nigori_specifics.pb.h"
15 16
16 namespace syncer { 17 namespace syncer {
17 18
18 const char kNigoriTag[] = "google_chrome_nigori"; 19 const char kNigoriTag[] = "google_chrome_nigori";
19 20
20 // We name a particular Nigori instance (ie. a triplet consisting of a hostname, 21 // We name a particular Nigori instance (ie. a triplet consisting of a hostname,
21 // a username, and a password) by calling Permute on this string. Since the 22 // a username, and a password) by calling Permute on this string. Since the
22 // output of Permute is always the same for a given triplet, clients will always 23 // output of Permute is always the same for a given triplet, clients will always
23 // assign the same name to a particular triplet. 24 // assign the same name to a particular triplet.
24 const char kNigoriKeyName[] = "nigori-key"; 25 const char kNigoriKeyName[] = "nigori-key";
25 26
26 Cryptographer::Cryptographer(Encryptor* encryptor) 27 Cryptographer::Cryptographer(Encryptor* encryptor) : encryptor_(encryptor) {
27 : encryptor_(encryptor) {
28 DCHECK(encryptor); 28 DCHECK(encryptor);
29 } 29 }
30 30
31 Cryptographer::Cryptographer(const Cryptographer& other) 31 Cryptographer::Cryptographer(const Cryptographer& other)
32 : encryptor_(other.encryptor_), 32 : encryptor_(other.encryptor_),
33 default_nigori_name_(other.default_nigori_name_) { 33 default_nigori_name_(other.default_nigori_name_) {
34 for (NigoriMap::const_iterator it = other.nigoris_.begin(); 34 for (NigoriMap::const_iterator it = other.nigoris_.begin();
35 it != other.nigoris_.end(); 35 it != other.nigoris_.end(); ++it) {
36 ++it) {
37 std::string user_key, encryption_key, mac_key; 36 std::string user_key, encryption_key, mac_key;
38 it->second->ExportKeys(&user_key, &encryption_key, &mac_key); 37 it->second->ExportKeys(&user_key, &encryption_key, &mac_key);
39 linked_ptr<Nigori> nigori_copy(new Nigori()); 38 linked_ptr<Nigori> nigori_copy(new Nigori());
40 nigori_copy->InitByImport(user_key, encryption_key, mac_key); 39 nigori_copy->InitByImport(user_key, encryption_key, mac_key);
41 nigoris_.insert(std::make_pair(it->first, nigori_copy)); 40 nigoris_.insert(std::make_pair(it->first, nigori_copy));
42 } 41 }
43 42
44 if (other.pending_keys_) { 43 if (other.pending_keys_) {
45 pending_keys_.reset(new sync_pb::EncryptedData(*(other.pending_keys_))); 44 pending_keys_.reset(new sync_pb::EncryptedData(*(other.pending_keys_)));
46 } 45 }
47 } 46 }
48 47
49 Cryptographer::~Cryptographer() {} 48 Cryptographer::~Cryptographer() {}
50 49
51
52 void Cryptographer::Bootstrap(const std::string& restored_bootstrap_token) { 50 void Cryptographer::Bootstrap(const std::string& restored_bootstrap_token) {
53 if (is_initialized()) { 51 if (is_initialized()) {
54 NOTREACHED(); 52 NOTREACHED();
55 return; 53 return;
56 } 54 }
57 55
58 std::string serialized_nigori_key = 56 std::string serialized_nigori_key =
59 UnpackBootstrapToken(restored_bootstrap_token); 57 UnpackBootstrapToken(restored_bootstrap_token);
60 if (serialized_nigori_key.empty()) 58 if (serialized_nigori_key.empty())
61 return; 59 return;
62 ImportNigoriKey(serialized_nigori_key); 60 ImportNigoriKey(serialized_nigori_key);
63 } 61 }
64 62
65 bool Cryptographer::CanDecrypt(const sync_pb::EncryptedData& data) const { 63 bool Cryptographer::CanDecrypt(const sync_pb::EncryptedData& data) const {
66 return nigoris_.end() != nigoris_.find(data.key_name()); 64 return nigoris_.end() != nigoris_.find(data.key_name());
67 } 65 }
68 66
69 bool Cryptographer::CanDecryptUsingDefaultKey( 67 bool Cryptographer::CanDecryptUsingDefaultKey(
70 const sync_pb::EncryptedData& data) const { 68 const sync_pb::EncryptedData& data) const {
71 return !default_nigori_name_.empty() && 69 return !default_nigori_name_.empty() &&
72 data.key_name() == default_nigori_name_; 70 data.key_name() == default_nigori_name_;
73 } 71 }
74 72
75 bool Cryptographer::Encrypt( 73 bool Cryptographer::Encrypt(const ::google::protobuf::MessageLite& message,
76 const ::google::protobuf::MessageLite& message, 74 sync_pb::EncryptedData* encrypted) const {
77 sync_pb::EncryptedData* encrypted) const {
78 DCHECK(encrypted); 75 DCHECK(encrypted);
79 if (default_nigori_name_.empty()) { 76 if (default_nigori_name_.empty()) {
80 LOG(ERROR) << "Cryptographer not ready, failed to encrypt."; 77 LOG(ERROR) << "Cryptographer not ready, failed to encrypt.";
81 return false; 78 return false;
82 } 79 }
83 80
84 std::string serialized; 81 std::string serialized;
85 if (!message.SerializeToString(&serialized)) { 82 if (!message.SerializeToString(&serialized)) {
86 LOG(ERROR) << "Message is invalid/missing a required field."; 83 LOG(ERROR) << "Message is invalid/missing a required field.";
87 return false; 84 return false;
88 } 85 }
89 86
90 return EncryptString(serialized, encrypted); 87 return EncryptString(serialized, encrypted);
91 } 88 }
92 89
93 bool Cryptographer::EncryptString( 90 bool Cryptographer::EncryptString(const std::string& serialized,
94 const std::string& serialized, 91 sync_pb::EncryptedData* encrypted) const {
95 sync_pb::EncryptedData* encrypted) const {
96 if (CanDecryptUsingDefaultKey(*encrypted)) { 92 if (CanDecryptUsingDefaultKey(*encrypted)) {
97 const std::string& original_serialized = DecryptToString(*encrypted); 93 const std::string& original_serialized = DecryptToString(*encrypted);
98 if (original_serialized == serialized) { 94 if (original_serialized == serialized) {
99 DVLOG(2) << "Re-encryption unnecessary, encrypted data already matches."; 95 DVLOG(2) << "Re-encryption unnecessary, encrypted data already matches.";
100 return true; 96 return true;
101 } 97 }
102 } 98 }
103 99
104 NigoriMap::const_iterator default_nigori = 100 NigoriMap::const_iterator default_nigori =
105 nigoris_.find(default_nigori_name_); 101 nigoris_.find(default_nigori_name_);
106 if (default_nigori == nigoris_.end()) { 102 if (default_nigori == nigoris_.end()) {
107 LOG(ERROR) << "Corrupt default key."; 103 LOG(ERROR) << "Corrupt default key.";
108 return false; 104 return false;
109 } 105 }
110 106
111 encrypted->set_key_name(default_nigori_name_); 107 encrypted->set_key_name(default_nigori_name_);
112 if (!default_nigori->second->Encrypt(serialized, 108 if (!default_nigori->second->Encrypt(serialized, encrypted->mutable_blob())) {
113 encrypted->mutable_blob())) {
114 LOG(ERROR) << "Failed to encrypt data."; 109 LOG(ERROR) << "Failed to encrypt data.";
115 return false; 110 return false;
116 } 111 }
117 return true; 112 return true;
118 } 113 }
119 114
120 bool Cryptographer::Decrypt(const sync_pb::EncryptedData& encrypted, 115 bool Cryptographer::Decrypt(const sync_pb::EncryptedData& encrypted,
121 ::google::protobuf::MessageLite* message) const { 116 ::google::protobuf::MessageLite* message) const {
122 DCHECK(message); 117 DCHECK(message);
123 std::string plaintext = DecryptToString(encrypted); 118 std::string plaintext = DecryptToString(encrypted);
(...skipping 22 matching lines...) Expand all
146 DCHECK(encrypted); 141 DCHECK(encrypted);
147 DCHECK(!nigoris_.empty()); 142 DCHECK(!nigoris_.empty());
148 143
149 // Create a bag of all the Nigori parameters we know about. 144 // Create a bag of all the Nigori parameters we know about.
150 sync_pb::NigoriKeyBag bag; 145 sync_pb::NigoriKeyBag bag;
151 for (NigoriMap::const_iterator it = nigoris_.begin(); it != nigoris_.end(); 146 for (NigoriMap::const_iterator it = nigoris_.begin(); it != nigoris_.end();
152 ++it) { 147 ++it) {
153 const Nigori& nigori = *it->second; 148 const Nigori& nigori = *it->second;
154 sync_pb::NigoriKey* key = bag.add_key(); 149 sync_pb::NigoriKey* key = bag.add_key();
155 key->set_name(it->first); 150 key->set_name(it->first);
156 nigori.ExportKeys(key->mutable_user_key(), 151 nigori.ExportKeys(key->mutable_user_key(), key->mutable_encryption_key(),
157 key->mutable_encryption_key(),
158 key->mutable_mac_key()); 152 key->mutable_mac_key());
159 } 153 }
160 154
161 // Encrypt the bag with the default Nigori. 155 // Encrypt the bag with the default Nigori.
162 return Encrypt(bag, encrypted); 156 return Encrypt(bag, encrypted);
163 } 157 }
164 158
165 bool Cryptographer::AddKey(const KeyParams& params) { 159 bool Cryptographer::AddKey(const KeyParams& params) {
166 // Create the new Nigori and make it the default encryptor. 160 // Create the new Nigori and make it the default encryptor.
167 std::unique_ptr<Nigori> nigori(new Nigori); 161 std::unique_ptr<Nigori> nigori(new Nigori);
168 if (!nigori->InitByDerivation(params.hostname, 162 if (!nigori->InitByDerivation(params.hostname, params.username,
169 params.username,
170 params.password)) { 163 params.password)) {
171 NOTREACHED(); // Invalid username or password. 164 NOTREACHED(); // Invalid username or password.
172 return false; 165 return false;
173 } 166 }
174 return AddKeyImpl(std::move(nigori), true); 167 return AddKeyImpl(std::move(nigori), true);
175 } 168 }
176 169
177 bool Cryptographer::AddNonDefaultKey(const KeyParams& params) { 170 bool Cryptographer::AddNonDefaultKey(const KeyParams& params) {
178 DCHECK(is_initialized()); 171 DCHECK(is_initialized());
179 // Create the new Nigori and add it to the keybag. 172 // Create the new Nigori and add it to the keybag.
180 std::unique_ptr<Nigori> nigori(new Nigori); 173 std::unique_ptr<Nigori> nigori(new Nigori);
181 if (!nigori->InitByDerivation(params.hostname, 174 if (!nigori->InitByDerivation(params.hostname, params.username,
182 params.username,
183 params.password)) { 175 params.password)) {
184 NOTREACHED(); // Invalid username or password. 176 NOTREACHED(); // Invalid username or password.
185 return false; 177 return false;
186 } 178 }
187 return AddKeyImpl(std::move(nigori), false); 179 return AddKeyImpl(std::move(nigori), false);
188 } 180 }
189 181
190 bool Cryptographer::AddKeyFromBootstrapToken( 182 bool Cryptographer::AddKeyFromBootstrapToken(
191 const std::string& restored_bootstrap_token) { 183 const std::string& restored_bootstrap_token) {
192 // Create the new Nigori and make it the default encryptor. 184 // Create the new Nigori and make it the default encryptor.
193 std::string serialized_nigori_key = UnpackBootstrapToken( 185 std::string serialized_nigori_key =
194 restored_bootstrap_token); 186 UnpackBootstrapToken(restored_bootstrap_token);
195 return ImportNigoriKey(serialized_nigori_key); 187 return ImportNigoriKey(serialized_nigori_key);
196 } 188 }
197 189
198 bool Cryptographer::AddKeyImpl(std::unique_ptr<Nigori> initialized_nigori, 190 bool Cryptographer::AddKeyImpl(std::unique_ptr<Nigori> initialized_nigori,
199 bool set_as_default) { 191 bool set_as_default) {
200 std::string name; 192 std::string name;
201 if (!initialized_nigori->Permute(Nigori::Password, kNigoriKeyName, &name)) { 193 if (!initialized_nigori->Permute(Nigori::Password, kNigoriKeyName, &name)) {
202 NOTREACHED(); 194 NOTREACHED();
203 return false; 195 return false;
204 } 196 }
205 197
206 nigoris_[name] = make_linked_ptr(initialized_nigori.release()); 198 nigoris_[name] = make_linked_ptr(initialized_nigori.release());
207 199
208 // Check if the key we just added can decrypt the pending keys and add them 200 // Check if the key we just added can decrypt the pending keys and add them
209 // too if so. 201 // too if so.
210 if (pending_keys_.get() && CanDecrypt(*pending_keys_)) { 202 if (pending_keys_.get() && CanDecrypt(*pending_keys_)) {
211 sync_pb::NigoriKeyBag pending_bag; 203 sync_pb::NigoriKeyBag pending_bag;
212 Decrypt(*pending_keys_, &pending_bag); 204 Decrypt(*pending_keys_, &pending_bag);
213 InstallKeyBag(pending_bag); 205 InstallKeyBag(pending_bag);
214 SetDefaultKey(pending_keys_->key_name()); 206 SetDefaultKey(pending_keys_->key_name());
215 pending_keys_.reset(); 207 pending_keys_.reset();
216 } 208 }
217 209
218 // The just-added key takes priority over the pending keys as default. 210 // The just-added key takes priority over the pending keys as default.
219 if (set_as_default) SetDefaultKey(name); 211 if (set_as_default)
212 SetDefaultKey(name);
220 return true; 213 return true;
221 } 214 }
222 215
223 void Cryptographer::InstallKeys(const sync_pb::EncryptedData& encrypted) { 216 void Cryptographer::InstallKeys(const sync_pb::EncryptedData& encrypted) {
224 DCHECK(CanDecrypt(encrypted)); 217 DCHECK(CanDecrypt(encrypted));
225 218
226 sync_pb::NigoriKeyBag bag; 219 sync_pb::NigoriKeyBag bag;
227 if (!Decrypt(encrypted, &bag)) 220 if (!Decrypt(encrypted, &bag))
228 return; 221 return;
229 InstallKeyBag(bag); 222 InstallKeyBag(bag);
(...skipping 10 matching lines...) Expand all
240 pending_keys_.reset(new sync_pb::EncryptedData(encrypted)); 233 pending_keys_.reset(new sync_pb::EncryptedData(encrypted));
241 } 234 }
242 235
243 const sync_pb::EncryptedData& Cryptographer::GetPendingKeys() const { 236 const sync_pb::EncryptedData& Cryptographer::GetPendingKeys() const {
244 DCHECK(has_pending_keys()); 237 DCHECK(has_pending_keys());
245 return *(pending_keys_.get()); 238 return *(pending_keys_.get());
246 } 239 }
247 240
248 bool Cryptographer::DecryptPendingKeys(const KeyParams& params) { 241 bool Cryptographer::DecryptPendingKeys(const KeyParams& params) {
249 Nigori nigori; 242 Nigori nigori;
250 if (!nigori.InitByDerivation(params.hostname, 243 if (!nigori.InitByDerivation(params.hostname, params.username,
251 params.username,
252 params.password)) { 244 params.password)) {
253 NOTREACHED(); 245 NOTREACHED();
254 return false; 246 return false;
255 } 247 }
256 248
257 std::string plaintext; 249 std::string plaintext;
258 if (!nigori.Decrypt(pending_keys_->blob(), &plaintext)) 250 if (!nigori.Decrypt(pending_keys_->blob(), &plaintext))
259 return false; 251 return false;
260 252
261 sync_pb::NigoriKeyBag bag; 253 sync_pb::NigoriKeyBag bag;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 return unencrypted_token; 297 return unencrypted_token;
306 } 298 }
307 299
308 void Cryptographer::InstallKeyBag(const sync_pb::NigoriKeyBag& bag) { 300 void Cryptographer::InstallKeyBag(const sync_pb::NigoriKeyBag& bag) {
309 int key_size = bag.key_size(); 301 int key_size = bag.key_size();
310 for (int i = 0; i < key_size; ++i) { 302 for (int i = 0; i < key_size; ++i) {
311 const sync_pb::NigoriKey key = bag.key(i); 303 const sync_pb::NigoriKey key = bag.key(i);
312 // Only use this key if we don't already know about it. 304 // Only use this key if we don't already know about it.
313 if (nigoris_.end() == nigoris_.find(key.name())) { 305 if (nigoris_.end() == nigoris_.find(key.name())) {
314 std::unique_ptr<Nigori> new_nigori(new Nigori); 306 std::unique_ptr<Nigori> new_nigori(new Nigori);
315 if (!new_nigori->InitByImport(key.user_key(), 307 if (!new_nigori->InitByImport(key.user_key(), key.encryption_key(),
316 key.encryption_key(),
317 key.mac_key())) { 308 key.mac_key())) {
318 NOTREACHED(); 309 NOTREACHED();
319 continue; 310 continue;
320 } 311 }
321 nigoris_[key.name()] = make_linked_ptr(new_nigori.release()); 312 nigoris_[key.name()] = make_linked_ptr(new_nigori.release());
322 } 313 }
323 } 314 }
324 } 315 }
325 316
326 bool Cryptographer::KeybagIsStale( 317 bool Cryptographer::KeybagIsStale(
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 NOTREACHED(); 367 NOTREACHED();
377 return false; 368 return false;
378 } 369 }
379 370
380 if (!AddKeyImpl(std::move(nigori), true)) 371 if (!AddKeyImpl(std::move(nigori), true))
381 return false; 372 return false;
382 return true; 373 return true;
383 } 374 }
384 375
385 } // namespace syncer 376 } // namespace syncer
OLDNEW
« no previous file with comments | « components/sync/base/cryptographer.h ('k') | components/sync/base/cryptographer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698