1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 53345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/base64.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/util/cryptographer.h" 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/password_manager/encryptor.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser_sync { 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kNigoriTag[] = "google_chrome_nigori"; 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// We name a particular Nigori instance (ie. a triplet consisting of a hostname, 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// a username, and a password) by calling Permute on this string. Since the 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// output of Permute is always the same for a given triplet, clients will always 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// assign the same name to a particular triplet. 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kNigoriKeyName[] = "nigori-key"; 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCryptographer::Cryptographer() : default_nigori_(NULL) { 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickCryptographer::~Cryptographer() {} 23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid Cryptographer::Bootstrap(const std::string& restored_bootstrap_token) { 253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (is_ready()) { 263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<Nigori> nigori(UnpackBootstrapToken(restored_bootstrap_token)); 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (nigori.get()) 323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick AddKeyImpl(nigori.release()); 333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Cryptographer::CanDecrypt(const sync_pb::EncryptedData& data) const { 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return nigoris_.end() != nigoris_.find(data.key_name()); 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool Cryptographer::CanDecryptUsingDefaultKey( 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const sync_pb::EncryptedData& data) const { 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return default_nigori_ && (data.key_name() == default_nigori_->first); 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Cryptographer::Encrypt(const ::google::protobuf::MessageLite& message, 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_pb::EncryptedData* encrypted) const { 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(encrypted); 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(default_nigori_); 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string serialized; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!message.SerializeToString(&serialized)) { 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); // |message| is invalid/missing a required field. 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch encrypted->set_key_name(default_nigori_->first); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!default_nigori_->second->Encrypt(serialized, 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch encrypted->mutable_blob())) { 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); // Encrypt should not fail. 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Cryptographer::Decrypt(const sync_pb::EncryptedData& encrypted, 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ::google::protobuf::MessageLite* message) const { 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(message); 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen std::string plaintext = DecryptToString(encrypted); 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return message->ParseFromString(plaintext); 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::string Cryptographer::DecryptToString( 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen const sync_pb::EncryptedData& encrypted) const { 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NigoriMap::const_iterator it = nigoris_.find(encrypted.key_name()); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nigoris_.end() == it) { 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED() << "Cannot decrypt message"; 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return std::string(""); // Caller should have called CanDecrypt(encrypt). 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string plaintext; 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!it->second->Decrypt(encrypted.blob(), &plaintext)) { 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return std::string(""); 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return plaintext; 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Cryptographer::GetKeys(sync_pb::EncryptedData* encrypted) const { 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(encrypted); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!nigoris_.empty()); 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create a bag of all the Nigori parameters we know about. 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_pb::NigoriKeyBag bag; 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (NigoriMap::const_iterator it = nigoris_.begin(); it != nigoris_.end(); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++it) { 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const Nigori& nigori = *it->second; 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_pb::NigoriKey* key = bag.add_key(); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch key->set_name(it->first); 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick nigori.ExportKeys(key->mutable_user_key(), 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key->mutable_encryption_key(), 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key->mutable_mac_key()); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Encrypt the bag with the default Nigori. 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return Encrypt(bag, encrypted); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Cryptographer::AddKey(const KeyParams& params) { 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(NULL == pending_keys_.get()); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Create the new Nigori and make it the default encryptor. 1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<Nigori> nigori(new Nigori); 1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!nigori->InitByDerivation(params.hostname, 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick params.username, 1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick params.password)) { 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); // Invalid username or password. 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return AddKeyImpl(nigori.release()); 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Cryptographer::AddKeyImpl(Nigori* initialized_nigori) { 1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<Nigori> nigori(initialized_nigori); 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string name; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!nigori->Permute(Nigori::Password, kNigoriKeyName, &name)) { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nigoris_[name] = make_linked_ptr(nigori.release()); 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default_nigori_ = &*nigoris_.find(name); 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Cryptographer::SetKeys(const sync_pb::EncryptedData& encrypted) { 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(CanDecrypt(encrypted)); 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_pb::NigoriKeyBag bag; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!Decrypt(encrypted, &bag)) { 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InstallKeys(encrypted.key_name(), bag); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Cryptographer::SetPendingKeys(const sync_pb::EncryptedData& encrypted) { 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!CanDecrypt(encrypted)); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_keys_.reset(new sync_pb::EncryptedData(encrypted)); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool Cryptographer::DecryptPendingKeys(const KeyParams& params) { 1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Nigori nigori; 1513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!nigori.InitByDerivation(params.hostname, 1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick params.username, 1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick params.password)) { 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string plaintext; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!nigori.Decrypt(pending_keys_->blob(), &plaintext)) 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch sync_pb::NigoriKeyBag bag; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!bag.ParseFromString(plaintext)) { 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InstallKeys(pending_keys_->key_name(), bag); 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pending_keys_.reset(); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Cryptographer::GetBootstrapToken(std::string* token) const { 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(token); 1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!is_ready()) 1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return PackBootstrapToken(default_nigori_->second.get(), token); 1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool Cryptographer::PackBootstrapToken(const Nigori* nigori, 1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string* pack_into) const { 1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(pack_into); 1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(nigori); 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sync_pb::NigoriKey key; 1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!nigori->ExportKeys(key.mutable_user_key(), 1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key.mutable_encryption_key(), 1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key.mutable_mac_key())) { 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string unencrypted_token; 1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!key.SerializeToString(&unencrypted_token)) { 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string encrypted_token; 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!Encryptor::EncryptString(unencrypted_token, &encrypted_token)) { 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!base::Base64Encode(encrypted_token, pack_into)) { 2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return false; 2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return true; 2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickNigori* Cryptographer::UnpackBootstrapToken(const std::string& token) const { 2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (token.empty()) 2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string encrypted_data; 217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (!base::Base64Decode(token, &encrypted_data)) { 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DLOG(WARNING) << "Could not decode token."; 2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string unencrypted_token; 2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!Encryptor::DecryptString(encrypted_data, &unencrypted_token)) { 2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DLOG(WARNING) << "Decryption of bootstrap token failed."; 2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick sync_pb::NigoriKey key; 2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!key.ParseFromString(unencrypted_token)) { 2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DLOG(WARNING) << "Parsing of bootstrap token failed."; 2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<Nigori> nigori(new Nigori); 2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!nigori->InitByImport(key.user_key(), key.encryption_key(), 2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key.mac_key())) { 2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NOTREACHED(); 2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return NULL; 2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return nigori.release(); 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid Cryptographer::InstallKeys(const std::string& default_key_name, 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const sync_pb::NigoriKeyBag& bag) { 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int key_size = bag.key_size(); 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (int i = 0; i < key_size; ++i) { 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const sync_pb::NigoriKey key = bag.key(i); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Only use this key if we don't already know about it. 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (nigoris_.end() == nigoris_.find(key.name())) { 2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick scoped_ptr<Nigori> new_nigori(new Nigori); 2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!new_nigori->InitByImport(key.user_key(), 2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key.encryption_key(), 2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick key.mac_key())) { 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch continue; 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nigoris_[key.name()] = make_linked_ptr(new_nigori.release()); 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(nigoris_.end() != nigoris_.find(default_key_name)); 262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default_nigori_ = &*nigoris_.find(default_key_name); 263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace browser_sync 266