Index: sync/internal_api/public/sync_encryption_handler.h |
diff --git a/sync/internal_api/public/sync_encryption_handler.h b/sync/internal_api/public/sync_encryption_handler.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..7c597fc1f95bbd0f14f40149392399c0f3c5eff4 |
--- /dev/null |
+++ b/sync/internal_api/public/sync_encryption_handler.h |
@@ -0,0 +1,175 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef SYNC_INTERNAL_API_PUBLIC_SYNC_ENCRYPTION_HANDLER_H |
+#define SYNC_INTERNAL_API_PUBLIC_SYNC_ENCRYPTION_HANDLER_H |
+ |
+#include <string> |
+ |
+#include "sync/internal_api/public/base/model_type.h" |
+ |
+namespace sync_pb { |
+class EncryptedData; |
+class NigoriSpecifics; |
+} |
+ |
+namespace syncer { |
+ |
+class Cryptographer; |
+ |
+// Reasons due to which Cryptographer might require a passphrase. |
+enum PassphraseRequiredReason { |
+ REASON_PASSPHRASE_NOT_REQUIRED = 0, // Initial value. |
+ REASON_ENCRYPTION = 1, // The cryptographer requires a |
+ // passphrase for its first attempt at |
+ // encryption. Happens only during |
+ // migration or upgrade. |
+ REASON_DECRYPTION = 2, // The cryptographer requires a |
+ // passphrase for its first attempt at |
+ // decryption. |
+}; |
+ |
+// Sync's encryption handler. Handles tracking encrypted types, ensuring the |
+// cryptographer encrypts with the proper key and has the most recent keybag, |
+// and keeps the nigori node up to date. |
+// |
+// TODO(zea): This class should not need to be entirely thread safe. Refactor |
+// how datatypes/sync gets the set of encrypted types and pull that out |
+// into a thread safe class, then make this class explicitly non-thread safe |
+// and ensure its only accessed from the sync thread. As it stands, |
+// GetEncryptedTypes is called from all datatype threads via the cryptographer's |
+// GetEncryptedTypes method. |
+class SyncEncryptionHandler { |
+ public: |
+ // All Observer methods are done synchronously and are assumed to be called |
tim (not reviewing)
2012/08/13 20:01:00
Why is the word 'assumed' here?
'All Observer m
Nicolas Zea
2012/08/13 22:56:38
Done.
|
+ // from within a transaction and on the sync thread. |
+ class Observer { |
+ public: |
+ Observer(); |
+ |
+ // Called when user interaction is required to obtain a valid passphrase. |
+ // - If the passphrase is required for encryption, |reason| will be |
+ // REASON_ENCRYPTION. |
+ // - If the passphrase is required for the decryption of data that has |
+ // already been encrypted, |reason| will be REASON_DECRYPTION. |
+ // - If the passphrase is required because decryption failed, and a new |
+ // passphrase is required, |reason| will be REASON_SET_PASSPHRASE_FAILED. |
+ // |
+ // |pending_keys| is a copy of the cryptographer's pending keys, that may be |
+ // cached by the frontend for subsequent use by the UI. |
+ virtual void OnPassphraseRequired( |
+ PassphraseRequiredReason reason, |
+ const sync_pb::EncryptedData& pending_keys) = 0; |
+ // Called when the passphrase provided by the user has been accepted and is |
+ // now used to encrypt sync data. |
+ |
+ virtual void OnPassphraseAccepted() = 0; |
+ // |bootstrap_token| is an opaque base64 encoded representation of the key |
+ // generated by the current passphrase, and is provided to the observer for |
+ // persistence purposes and use in a future initialization of sync (e.g. |
+ // after restart). The boostrap token will always be derived from the most |
+ // recent GAIA password (for accounts with implicit passphrases), even if |
+ // the data is still encrypted with an older GAIA password. For accounts |
+ // with explicit passphrases, it will be the most recently seen custom |
+ // passphrase. |
+ virtual void OnBootstrapTokenUpdated( |
+ const std::string& bootstrap_token) = 0; |
+ |
+ // Called when the set of encrypted types or the encrypt |
+ // everything flag has been changed. Note that encryption isn't |
+ // complete until the OnEncryptionComplete() notification has been |
+ // sent (see below). |
+ // |
+ // |encrypted_types| will always be a superset of |
+ // Cryptographer::SensitiveTypes(). If |encrypt_everything| is |
+ // true, |encrypted_types| will be the set of all known types. |
+ // |
+ // Until this function is called, observers can assume that the |
+ // set of encrypted types is Cryptographer::SensitiveTypes() and |
+ // that the encrypt everything flag is false. |
+ virtual void OnEncryptedTypesChanged( |
+ ModelTypeSet encrypted_types, |
+ bool encrypt_everything) = 0; |
+ |
+ // Called after we finish encrypting the current set of encrypted |
+ // types. |
+ virtual void OnEncryptionComplete() = 0; |
+ |
+ // The cryptographer has been updated. Listeners should check that their |
+ // own state matches the cryptographer. |
+ // Used primarily for debugging. |
+ virtual void OnCryptographerStateChanged(Cryptographer* cryptographer) = 0; |
+ |
+ protected: |
+ virtual ~Observer(); |
+ }; |
+ |
+ SyncEncryptionHandler(); |
+ virtual ~SyncEncryptionHandler(); |
+ |
+ // Add/Remove SyncEncryptionHandler::Observer's. |
+ // Must be called from sync thread. |
+ virtual void AddObserver(Observer* observer) = 0; |
+ virtual void RemoveObserver(Observer* observer) = 0; |
+ |
+ // Reads the nigori node, updates internal state as needed, and, if a |
+ // stale/incompatible nigori node is detected, overwrites the existing |
+ // nigori node. Upon completion, if the cryptographer is still ready |
+ // attempts to re-encrypt all sync data. |
+ // Note: This method is expensive (it iterates through all encrypted types), |
+ // so should only be used sparingly (e.g. on startup). |
+ virtual void ReloadNigori() = 0; |
+ |
+ // Apply a nigori node update, updating the internal encryption state |
+ // accordingly. |
+ // TODO(zea): remove this in favor of using the ChangeProcessor interface. |
+ virtual void UpdateFromNigori(const sync_pb::NigoriSpecifics& nigori) = 0; |
+ |
+ // Returns the set of currently encrypted types. |
+ // Note: caller must be holding a transaction. See TODO above about |
+ // refactoring how this is called. |
+ virtual ModelTypeSet GetEncryptedTypes() const = 0; |
+ |
+ // Store the current encrypt everything/encrypted types state into |nigori|. |
+ // TODO(zea): remove this in favor of using a ResolveConflict method via |
+ // the ChangeProcessor interface. |
+ virtual void UpdateNigoriFromEncryptedTypes( |
+ sync_pb::NigoriSpecifics* nigori) const = 0; |
+ |
+ // Attempts to re-encrypt encrypted data types using the passphrase provided. |
+ // Notifies observers of the result of the operation via OnPassphraseAccepted |
+ // or OnPassphraseRequired, updates the nigori node, and does re-encryption as |
+ // appropriate. If an explicit password has been set previously, we drop |
+ // subsequent requests to set a passphrase. If the cryptographer has pending |
+ // keys, and a new implicit passphrase is provided, we try decrypting the |
+ // pending keys with it, and if that fails, we cache the passphrase for |
+ // re-encryption once the pending keys are decrypted. |
+ virtual void SetEncryptionPassphrase(const std::string& passphrase, |
+ bool is_explicit) = 0; |
+ |
+ // Provides a passphrase for decrypting the user's existing sync data. |
+ // Notifies observers of the result of the operation via OnPassphraseAccepted |
+ // or OnPassphraseRequired, updates the nigori node, and does re-encryption as |
+ // appropriate if there is a previously cached encryption passphrase. It is an |
+ // error to call this when we don't have pending keys. |
+ virtual void SetDecryptionPassphrase(const std::string& passphrase) = 0; |
+ |
+ // Enables encryption of all datatypes. |
+ virtual void EnableEncryptEverything() = 0; |
+ |
+ // Whether encryption of all datatypes is enabled. If false, only sensitive |
+ // types are encrypted. |
+ virtual bool EncryptEverythingEnabled() const = 0; |
+ |
+ // Whether the account requires a user-provided passphrase to decrypt |
+ // encrypted data. |
+ virtual bool IsUsingExplicitPassphrase() const = 0; |
+ |
+ // The set of types that are always encrypted. |
+ static ModelTypeSet SensitiveTypes(); |
+}; |
+ |
+} // namespace syncer |
+ |
+#endif // SYNC_INTERNAL_API_PUBLIC_SYNC_ENCRYPTION_HANDLER_H |