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

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

Issue 8468023: Move encryption related files from util folder to encryption folder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: For review. Created 9 years, 1 month 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
(Empty)
1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_SYNC_UTIL_CRYPTOGRAPHER_H_
6 #define CHROME_BROWSER_SYNC_UTIL_CRYPTOGRAPHER_H_
7 #pragma once
8
9 #include <map>
10 #include <string>
11
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/linked_ptr.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/observer_list.h"
16 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h"
17 #include "chrome/browser/sync/syncable/model_type.h"
18 #include "chrome/browser/sync/util/nigori.h"
19
20 namespace browser_sync {
21
22 extern const char kNigoriTag[];
23
24 // The parameters used to initialize a Nigori instance.
25 struct KeyParams {
26 std::string hostname;
27 std::string username;
28 std::string password;
29 };
30
31 // This class manages the Nigori objects used to encrypt and decrypt sensitive
32 // sync data (eg. passwords). Each Nigori object knows how to handle data
33 // protected with a particular passphrase.
34 //
35 // Whenever an update to the Nigori sync node is received from the server,
36 // SetPendingKeys should be called with the encrypted contents of that node.
37 // Most likely, an updated Nigori node means that a new passphrase has been set
38 // and that future node updates won't be decryptable. To remedy this, the user
39 // should be prompted for the new passphrase and DecryptPendingKeys be called.
40 //
41 // Whenever a update to an encrypted node is received from the server,
42 // CanDecrypt should be used to verify whether the Cryptographer can decrypt
43 // that node. If it cannot, then the application of that update should be
44 // delayed until after it can be decrypted.
45 class Cryptographer {
46 public:
47 // All Observer methods are done synchronously, so they're called
48 // under a transaction (since all Cryptographer operations are done
49 // under a transaction).
50 class Observer {
51 public:
52 // Called when the set of encrypted types or the encrypt
53 // everything flag has been changed. Note that this doesn't
54 // necessarily mean that encryption has completed for the given
55 // types.
56 //
57 // |encrypted_types| will always be a superset of
58 // SensitiveTypes(). If |encrypt_everything| is true,
59 // |encrypted_types| will be the set of all known types.
60 //
61 // Until this function is called, observers can assume that the
62 // set of encrypted types is SensitiveTypes() and that the encrypt
63 // everything flag is false.
64 virtual void OnEncryptedTypesChanged(
65 const syncable::ModelTypeSet& encrypted_types,
66 bool encrypt_everything) = 0;
67
68 protected:
69 virtual ~Observer();
70 };
71
72 Cryptographer();
73 ~Cryptographer();
74
75 // When update on cryptographer is called this enum tells if the
76 // cryptographer was succesfully able to update using the nigori node or if
77 // it needs a key to decrypt the nigori node.
78 enum UpdateResult {
79 SUCCESS,
80 NEEDS_PASSPHRASE
81 };
82
83 // Manage observers.
84 void AddObserver(Observer* observer);
85 void RemoveObserver(Observer* observer);
86
87 // |restored_bootstrap_token| can be provided via this method to bootstrap
88 // Cryptographer instance into the ready state (is_ready will be true).
89 // It must be a string that was previously built by the
90 // GetSerializedBootstrapToken function. It is possible that the token is no
91 // longer valid (due to server key change), in which case the normal
92 // decryption code paths will fail and the user will need to provide a new
93 // passphrase.
94 // It is an error to call this if is_ready() == true, though it is fair to
95 // never call Bootstrap at all.
96 void Bootstrap(const std::string& restored_bootstrap_token);
97
98 // Returns whether we can decrypt |encrypted| using the keys we currently know
99 // about.
100 bool CanDecrypt(const sync_pb::EncryptedData& encrypted) const;
101
102 // Returns whether |encrypted| can be decrypted using the default encryption
103 // key.
104 bool CanDecryptUsingDefaultKey(const sync_pb::EncryptedData& encrypted) const;
105
106 // Encrypts |message| into |encrypted|. Returns true unless encryption fails.
107 // Note that encryption will fail if |message| isn't valid (eg. a required
108 // field isn't set).
109 bool Encrypt(const ::google::protobuf::MessageLite& message,
110 sync_pb::EncryptedData* encrypted) const;
111
112 // Decrypts |encrypted| into |message|. Returns true unless decryption fails,
113 // or |message| fails to parse the decrypted data.
114 bool Decrypt(const sync_pb::EncryptedData& encrypted,
115 ::google::protobuf::MessageLite* message) const;
116
117 // Decrypts |encrypted| and returns plaintext decrypted data. If decryption
118 // fails, returns empty string.
119 std::string DecryptToString(const sync_pb::EncryptedData& encrypted) const;
120
121 // Encrypts the set of currently known keys into |encrypted|. Returns true if
122 // successful.
123 bool GetKeys(sync_pb::EncryptedData* encrypted) const;
124
125 // Creates a new Nigori instance using |params|. If successful, |params| will
126 // become the default encryption key and be used for all future calls to
127 // Encrypt.
128 bool AddKey(const KeyParams& params);
129
130 // Decrypts |encrypted| and uses its contents to initialize Nigori instances.
131 // Returns true unless decryption of |encrypted| fails. The caller is
132 // responsible for checking that CanDecrypt(encrypted) == true.
133 bool SetKeys(const sync_pb::EncryptedData& encrypted);
134
135 // Makes a local copy of |encrypted| to later be decrypted by
136 // DecryptPendingKeys. This should only be used if CanDecrypt(encrypted) ==
137 // false.
138 void SetPendingKeys(const sync_pb::EncryptedData& encrypted);
139
140 // Attempts to decrypt the set of keys that was copied in the previous call to
141 // SetPendingKeys using |params|. Returns true if the pending keys were
142 // successfully decrypted and installed.
143 bool DecryptPendingKeys(const KeyParams& params);
144
145 bool is_initialized() const { return !nigoris_.empty() && default_nigori_; }
146
147 // Returns whether this Cryptographer is ready to encrypt and decrypt data.
148 bool is_ready() const { return is_initialized() &&
149 has_pending_keys() == false; }
150
151 // Returns whether there is a pending set of keys that needs to be decrypted.
152 bool has_pending_keys() const { return NULL != pending_keys_.get(); }
153
154 // Obtain a token that can be provided on construction to a future
155 // Cryptographer instance to bootstrap itself. Returns false if such a token
156 // can't be created (i.e. if this Cryptograhper doesn't have valid keys).
157 bool GetBootstrapToken(std::string* token) const;
158
159 // Update the cryptographer based on the contents of the nigori specifics.
160 // This updates both the encryption keys and the set of encrypted types.
161 // Returns NEEDS_PASSPHRASE if was unable to decrypt the pending keys,
162 // SUCCESS otherwise.
163 UpdateResult Update(const sync_pb::NigoriSpecifics& nigori);
164
165 // The set of types that are always encrypted.
166 static syncable::ModelTypeSet SensitiveTypes();
167
168 // Reset our set of encrypted types based on the contents of the nigori
169 // specifics.
170 void UpdateEncryptedTypesFromNigori(const sync_pb::NigoriSpecifics& nigori);
171
172 // Update the nigori to reflect the current set of encrypted types.
173 void UpdateNigoriFromEncryptedTypes(sync_pb::NigoriSpecifics* nigori) const;
174
175 // Setter/getter for whether all current and future datatypes should
176 // be encrypted. Once set you cannot unset without reading from a
177 // new nigori node. set_encrypt_everything() emits a notification
178 // the first time it's called.
179 void set_encrypt_everything();
180 bool encrypt_everything() const;
181
182 // Return the set of encrypted types.
183 syncable::ModelTypeSet GetEncryptedTypes() const;
184
185 // Forwards to SetEncryptedTypes.
186 void SetEncryptedTypesForTest(
187 const syncable::ModelTypeSet& encrypted_types);
188
189 private:
190 FRIEND_TEST_ALL_PREFIXES(CryptographerTest, PackUnpack);
191 typedef std::map<std::string, linked_ptr<const Nigori> > NigoriMap;
192
193 // Changes the set of encrypted types and emits a notification if
194 // necessary.
195 void SetEncryptedTypes(const syncable::ModelTypeSet& encrypted_types);
196
197 void EmitEncryptedTypesChangedNotification();
198
199 // Helper method to instantiate Nigori instances for each set of key
200 // parameters in |bag| and setting the default encryption key to
201 // |default_key_name|.
202 void InstallKeys(const std::string& default_key_name,
203 const sync_pb::NigoriKeyBag& bag);
204
205 bool AddKeyImpl(Nigori* nigori);
206
207 // Functions to serialize + encrypt a Nigori object in an opaque format for
208 // persistence by sync infrastructure.
209 bool PackBootstrapToken(const Nigori* nigori, std::string* pack_into) const;
210 Nigori* UnpackBootstrapToken(const std::string& token) const;
211
212 ObserverList<Observer> observers_;
213
214 NigoriMap nigoris_; // The Nigoris we know about, mapped by key name.
215 NigoriMap::value_type* default_nigori_; // The Nigori used for encryption.
216
217 scoped_ptr<sync_pb::EncryptedData> pending_keys_;
218
219 syncable::ModelTypeSet encrypted_types_;
220 bool encrypt_everything_;
221
222 DISALLOW_COPY_AND_ASSIGN(Cryptographer);
223 };
224
225 } // namespace browser_sync
226
227 #endif // CHROME_BROWSER_SYNC_UTIL_CRYPTOGRAPHER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698