Chromium Code Reviews| 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 |