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

Side by Side Diff: sync/util/cryptographer.h

Issue 10827266: [Sync] Add SyncEncryptionHandler (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments. Created 8 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 | Annotate | Revision Log
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 #ifndef SYNC_UTIL_CRYPTOGRAPHER_H_ 5 #ifndef SYNC_UTIL_CRYPTOGRAPHER_H_
6 #define SYNC_UTIL_CRYPTOGRAPHER_H_ 6 #define SYNC_UTIL_CRYPTOGRAPHER_H_
7 7
8 #include <map> 8 #include <map>
9 #include <string> 9 #include <string>
10 10
11 #include "base/gtest_prod_util.h" 11 #include "base/gtest_prod_util.h"
12 #include "base/memory/linked_ptr.h" 12 #include "base/memory/linked_ptr.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/observer_list.h"
15 #include "sync/internal_api/public/base/model_type.h" 14 #include "sync/internal_api/public/base/model_type.h"
16 #include "sync/protocol/encryption.pb.h" 15 #include "sync/protocol/encryption.pb.h"
17 #include "sync/protocol/nigori_specifics.pb.h"
18 #include "sync/util/nigori.h" 16 #include "sync/util/nigori.h"
19 17
18 namespace sync_pb {
19 class NigoriKeyBag;
20 class NigoriSpecifics;
21 }
22
20 namespace syncer { 23 namespace syncer {
21 24
22 class Encryptor; 25 class Encryptor;
23 26
27 namespace syncable {
28 class NigoriHandler;
29 }
30
24 extern const char kNigoriTag[]; 31 extern const char kNigoriTag[];
25 32
26 // The parameters used to initialize a Nigori instance. 33 // The parameters used to initialize a Nigori instance.
27 struct KeyParams { 34 struct KeyParams {
28 std::string hostname; 35 std::string hostname;
29 std::string username; 36 std::string username;
30 std::string password; 37 std::string password;
31 }; 38 };
32 39
33 // This class manages the Nigori objects used to encrypt and decrypt sensitive 40 // This class manages the Nigori objects used to encrypt and decrypt sensitive
34 // sync data (eg. passwords). Each Nigori object knows how to handle data 41 // sync data (eg. passwords). Each Nigori object knows how to handle data
35 // protected with a particular passphrase. 42 // protected with a particular passphrase.
36 // 43 //
37 // Whenever an update to the Nigori sync node is received from the server, 44 // Whenever an update to the Nigori sync node is received from the server,
38 // SetPendingKeys should be called with the encrypted contents of that node. 45 // SetPendingKeys should be called with the encrypted contents of that node.
39 // Most likely, an updated Nigori node means that a new passphrase has been set 46 // Most likely, an updated Nigori node means that a new passphrase has been set
40 // and that future node updates won't be decryptable. To remedy this, the user 47 // and that future node updates won't be decryptable. To remedy this, the user
41 // should be prompted for the new passphrase and DecryptPendingKeys be called. 48 // should be prompted for the new passphrase and DecryptPendingKeys be called.
42 // 49 //
43 // Whenever a update to an encrypted node is received from the server, 50 // Whenever a update to an encrypted node is received from the server,
44 // CanDecrypt should be used to verify whether the Cryptographer can decrypt 51 // CanDecrypt should be used to verify whether the Cryptographer can decrypt
45 // that node. If it cannot, then the application of that update should be 52 // that node. If it cannot, then the application of that update should be
46 // delayed until after it can be decrypted. 53 // delayed until after it can be decrypted.
47 class Cryptographer { 54 class Cryptographer {
48 public: 55 public:
49 // All Observer methods are done synchronously, so they're called
50 // under a transaction (since all Cryptographer operations are done
51 // under a transaction).
52 class Observer {
53 public:
54 // Called when the set of encrypted types or the encrypt
55 // everything flag has been changed. Note that this doesn't
56 // necessarily mean that encryption has completed for the given
57 // types.
58 //
59 // |encrypted_types| will always be a superset of
60 // SensitiveTypes(). If |encrypt_everything| is true,
61 // |encrypted_types| will be the set of all known types.
62 //
63 // Until this function is called, observers can assume that the
64 // set of encrypted types is SensitiveTypes() and that the encrypt
65 // everything flag is false.
66 virtual void OnEncryptedTypesChanged(
67 ModelTypeSet encrypted_types,
68 bool encrypt_everything) = 0;
69
70 protected:
71 virtual ~Observer();
72 };
73
74 // Does not take ownership of |encryptor|. 56 // Does not take ownership of |encryptor|.
75 explicit Cryptographer(Encryptor* encryptor); 57 explicit Cryptographer(Encryptor* encryptor);
76 ~Cryptographer(); 58 ~Cryptographer();
77 59
78 // When update on cryptographer is called this enum tells if the 60 // Set the sync nigori node handler.
79 // cryptographer was succesfully able to update using the nigori node or if 61 // TODO(zea): refactor so that Cryptographer doesn't need any connection
80 // it needs a key to decrypt the nigori node. 62 // to a NigoriHandler.
81 enum UpdateResult { 63 void SetNigoriHandler(syncable::NigoriHandler* delegate);
82 SUCCESS,
83 NEEDS_PASSPHRASE
84 };
85 64
86 // Manage observers. 65 // NigoriHandler delegator methods (passes through to delegate).
87 void AddObserver(Observer* observer); 66 void UpdateFromNigori(const sync_pb::NigoriSpecifics& nigori) ;
tim (not reviewing) 2012/08/14 02:32:20 nit - extra space before ;
Nicolas Zea 2012/08/14 23:24:51 Done.
88 void RemoveObserver(Observer* observer); 67 ModelTypeSet GetEncryptedTypes() const;
68 void UpdateNigoriFromEncryptedTypes(sync_pb::NigoriSpecifics* nigori) const;
89 69
90 // |restored_bootstrap_token| can be provided via this method to bootstrap 70 // |restored_bootstrap_token| can be provided via this method to bootstrap
91 // Cryptographer instance into the ready state (is_ready will be true). 71 // Cryptographer instance into the ready state (is_ready will be true).
92 // It must be a string that was previously built by the 72 // It must be a string that was previously built by the
93 // GetSerializedBootstrapToken function. It is possible that the token is no 73 // GetSerializedBootstrapToken function. It is possible that the token is no
94 // longer valid (due to server key change), in which case the normal 74 // longer valid (due to server key change), in which case the normal
95 // decryption code paths will fail and the user will need to provide a new 75 // decryption code paths will fail and the user will need to provide a new
96 // passphrase. 76 // passphrase.
97 // It is an error to call this if is_ready() == true, though it is fair to 77 // It is an error to call this if is_ready() == true, though it is fair to
98 // never call Bootstrap at all. 78 // never call Bootstrap at all.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 // Creates a new Nigori instance using |params|. If successful, |params| will 115 // Creates a new Nigori instance using |params|. If successful, |params| will
136 // become the default encryption key and be used for all future calls to 116 // become the default encryption key and be used for all future calls to
137 // Encrypt. 117 // Encrypt.
138 bool AddKey(const KeyParams& params); 118 bool AddKey(const KeyParams& params);
139 119
140 // Same as AddKey(..), but builds the new Nigori from a previously persisted 120 // Same as AddKey(..), but builds the new Nigori from a previously persisted
141 // bootstrap token. This can be useful when consuming a bootstrap token 121 // bootstrap token. This can be useful when consuming a bootstrap token
142 // with a cryptographer that has already been initialized. 122 // with a cryptographer that has already been initialized.
143 bool AddKeyFromBootstrapToken(const std::string restored_bootstrap_token); 123 bool AddKeyFromBootstrapToken(const std::string restored_bootstrap_token);
144 124
125 // Decrypts |encrypted| and uses its contents to initialize Nigori instances.
126 // Returns true unless decryption of |encrypted| fails. The caller is
127 // responsible for checking that CanDecrypt(encrypted) == true.
128 // Does not update the default nigori.
129 void InstallKeys(const sync_pb::EncryptedData& encrypted);
130
131
145 // Makes a local copy of |encrypted| to later be decrypted by 132 // Makes a local copy of |encrypted| to later be decrypted by
146 // DecryptPendingKeys. This should only be used if CanDecrypt(encrypted) == 133 // DecryptPendingKeys. This should only be used if CanDecrypt(encrypted) ==
147 // false. 134 // false.
148 void SetPendingKeys(const sync_pb::EncryptedData& encrypted); 135 void SetPendingKeys(const sync_pb::EncryptedData& encrypted);
149 136
150 // Makes |pending_keys_| available to callers that may want to cache its 137 // Makes |pending_keys_| available to callers that may want to cache its
151 // value for later use on the UI thread. It is illegal to call this if the 138 // value for later use on the UI thread. It is illegal to call this if the
152 // cryptographer has no pending keys. Like other calls that access the 139 // cryptographer has no pending keys. Like other calls that access the
153 // cryptographer, this method must be called from within a transaction. 140 // cryptographer, this method must be called from within a transaction.
154 const sync_pb::EncryptedData& GetPendingKeys() const; 141 const sync_pb::EncryptedData& GetPendingKeys() const;
155 142
156 // Attempts to decrypt the set of keys that was copied in the previous call to 143 // Attempts to decrypt the set of keys that was copied in the previous call to
157 // SetPendingKeys using |params|. Returns true if the pending keys were 144 // SetPendingKeys using |params|. Returns true if the pending keys were
158 // successfully decrypted and installed. If successful, the default key 145 // successfully decrypted and installed. If successful, the default key
159 // is updated. 146 // is updated.
160 bool DecryptPendingKeys(const KeyParams& params); 147 bool DecryptPendingKeys(const KeyParams& params);
161 148
149 // Sets the default key to the nigori with name |key_name|. |key_name| must
150 // correspond to a nigori that has already been installed into the keybag.
151 void SetDefaultKey(std::string key_name);
tim (not reviewing) 2012/08/14 02:32:20 const string&
Nicolas Zea 2012/08/14 23:24:51 Done.
152
162 bool is_initialized() const { return !nigoris_.empty() && default_nigori_; } 153 bool is_initialized() const { return !nigoris_.empty() && default_nigori_; }
163 154
164 // Returns whether this Cryptographer is ready to encrypt and decrypt data. 155 // Returns whether this Cryptographer is ready to encrypt and decrypt data.
165 bool is_ready() const { return is_initialized() && 156 bool is_ready() const { return is_initialized() &&
166 has_pending_keys() == false; } 157 has_pending_keys() == false; }
167 158
168 // Returns whether there is a pending set of keys that needs to be decrypted. 159 // Returns whether there is a pending set of keys that needs to be decrypted.
169 bool has_pending_keys() const { return NULL != pending_keys_.get(); } 160 bool has_pending_keys() const { return NULL != pending_keys_.get(); }
170 161
171 // Obtain a token that can be provided on construction to a future 162 // Obtain a token that can be provided on construction to a future
172 // Cryptographer instance to bootstrap itself. Returns false if such a token 163 // Cryptographer instance to bootstrap itself. Returns false if such a token
173 // can't be created (i.e. if this Cryptograhper doesn't have valid keys). 164 // can't be created (i.e. if this Cryptograhper doesn't have valid keys).
174 bool GetBootstrapToken(std::string* token) const; 165 bool GetBootstrapToken(std::string* token) const;
175 166
176 // Obtain the bootstrap token based on the keystore encryption key. 167 // Obtain the bootstrap token based on the keystore encryption key.
177 bool GetKeystoreKeyBootstrapToken(std::string* token) const; 168 bool GetKeystoreKeyBootstrapToken(std::string* token) const;
178 169
179 // Update the cryptographer based on the contents of the nigori specifics.
180 // This updates both the encryption keys and the set of encrypted types.
181 // Returns NEEDS_PASSPHRASE if was unable to decrypt the pending keys,
182 // SUCCESS otherwise.
183 // Note: will not change the default key. If the nigori's keybag
184 // is decryptable, all keys are added to the local keybag and the current
185 // default is preserved. If the nigori's keybag is not decryptable, it is
186 // stored in the |pending_keys_|.
187 UpdateResult Update(const sync_pb::NigoriSpecifics& nigori);
188
189 // Set the keystore-derived nigori from the provided key. 170 // Set the keystore-derived nigori from the provided key.
190 // Returns true if we succesfully create the keystore derived nigori from the 171 // Returns true if we succesfully create the keystore derived nigori from the
191 // provided key, false otherwise. 172 // provided key, false otherwise.
192 bool SetKeystoreKey(const std::string& keystore_key); 173 bool SetKeystoreKey(const std::string& keystore_key);
193 174
194 // Returns true if we currently have a keystore-derived nigori, false 175 // Returns true if we currently have a keystore-derived nigori, false
195 // otherwise. 176 // otherwise.
196 bool HasKeystoreKey() const; 177 bool HasKeystoreKey() const;
197 178
198 // The set of types that are always encrypted. 179 Encryptor* encryptor() const { return encryptor_; }
199 static ModelTypeSet SensitiveTypes();
200
201 // Reset our set of encrypted types based on the contents of the nigori
202 // specifics.
203 void UpdateEncryptedTypesFromNigori(const sync_pb::NigoriSpecifics& nigori);
204
205 // Update the nigori to reflect the current set of encrypted types.
206 void UpdateNigoriFromEncryptedTypes(sync_pb::NigoriSpecifics* nigori) const;
207
208 // Setter/getter for whether all current and future datatypes should
209 // be encrypted. Once set you cannot unset without reading from a
210 // new nigori node. set_encrypt_everything() emits a notification
211 // the first time it's called.
212 void set_encrypt_everything();
213 bool encrypt_everything() const;
214
215 // Return the set of encrypted types.
216 ModelTypeSet GetEncryptedTypes() const;
217
218 // Forwards to MergeEncryptedTypes.
219 void MergeEncryptedTypesForTest(ModelTypeSet encrypted_types);
220 180
221 private: 181 private:
222 FRIEND_TEST_ALL_PREFIXES(SyncCryptographerTest, PackUnpack); 182 FRIEND_TEST_ALL_PREFIXES(SyncCryptographerTest, PackUnpack);
183
223 typedef std::map<std::string, linked_ptr<const Nigori> > NigoriMap; 184 typedef std::map<std::string, linked_ptr<const Nigori> > NigoriMap;
224 185
225 // Merges the given set of encrypted types with the existing set and emits a
226 // notification if necessary.
227 void MergeEncryptedTypes(ModelTypeSet encrypted_types);
228
229 void EmitEncryptedTypesChangedNotification();
230
231 // Decrypts |encrypted| and uses its contents to initialize Nigori instances.
232 // Returns true unless decryption of |encrypted| fails. The caller is
233 // responsible for checking that CanDecrypt(encrypted) == true.
234 // Does not update the default nigori.
235 void InstallKeys(const sync_pb::EncryptedData& encrypted);
236
237 // Helper method to instantiate Nigori instances for each set of key 186 // Helper method to instantiate Nigori instances for each set of key
238 // parameters in |bag|. 187 // parameters in |bag|.
239 // Does not update the default nigori. 188 // Does not update the default nigori.
240 void InstallKeyBag(const sync_pb::NigoriKeyBag& bag); 189 void InstallKeyBag(const sync_pb::NigoriKeyBag& bag);
241 190
242 // Helper method to add a nigori as either the new default nigori or the new 191 // Helper method to add a nigori as either the new default nigori or the new
243 // keystore nigori. 192 // keystore nigori.
244 bool AddKeyImpl(Nigori* nigori, bool is_keystore_key); 193 bool AddKeyImpl(Nigori* nigori, bool is_keystore_key);
245 194
246 // Functions to serialize + encrypt a Nigori object in an opaque format for 195 // Functions to serialize + encrypt a Nigori object in an opaque format for
247 // persistence by sync infrastructure. 196 // persistence by sync infrastructure.
248 bool PackBootstrapToken(const Nigori* nigori, std::string* pack_into) const; 197 bool PackBootstrapToken(const Nigori* nigori, std::string* pack_into) const;
249 Nigori* UnpackBootstrapToken(const std::string& token) const; 198 Nigori* UnpackBootstrapToken(const std::string& token) const;
250 199
251 Encryptor* const encryptor_; 200 Encryptor* const encryptor_;
252 201
253 ObserverList<Observer> observers_;
254
255 NigoriMap nigoris_; // The Nigoris we know about, mapped by key name. 202 NigoriMap nigoris_; // The Nigoris we know about, mapped by key name.
256 NigoriMap::value_type* default_nigori_; // The Nigori used for encryption. 203 NigoriMap::value_type* default_nigori_; // The Nigori used for encryption.
257 NigoriMap::value_type* keystore_nigori_; // Nigori generated from keystore. 204 NigoriMap::value_type* keystore_nigori_; // Nigori generated from keystore.
258 205
259 scoped_ptr<sync_pb::EncryptedData> pending_keys_; 206 scoped_ptr<sync_pb::EncryptedData> pending_keys_;
260 207
261 ModelTypeSet encrypted_types_; 208 // The sync nigori node handler. Necessary until we decouple the encrypted
262 bool encrypt_everything_; 209 // types from the cryptographer.
210 syncable::NigoriHandler* nigori_node_handler_;
263 211
264 DISALLOW_COPY_AND_ASSIGN(Cryptographer); 212 DISALLOW_COPY_AND_ASSIGN(Cryptographer);
265 }; 213 };
266 214
267 } // namespace syncer 215 } // namespace syncer
268 216
269 #endif // SYNC_UTIL_CRYPTOGRAPHER_H_ 217 #endif // SYNC_UTIL_CRYPTOGRAPHER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698