| // Copyright 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 COMPONENTS_SYNC_ENGINE_SYNC_ENCRYPTION_HANDLER_H_ | 
 | #define COMPONENTS_SYNC_ENGINE_SYNC_ENCRYPTION_HANDLER_H_ | 
 |  | 
 | #include <string> | 
 |  | 
 | #include "base/time/time.h" | 
 | #include "components/sync/base/model_type.h" | 
 | #include "components/sync/protocol/sync.pb.h" | 
 |  | 
 | namespace syncer { | 
 |  | 
 | class Cryptographer; | 
 | enum class PassphraseType; | 
 |  | 
 | // 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. | 
 | }; | 
 |  | 
 | // Enum used to distinguish which bootstrap encryption token is being updated. | 
 | enum BootstrapTokenType { | 
 |   PASSPHRASE_BOOTSTRAP_TOKEN, | 
 |   KEYSTORE_BOOTSTRAP_TOKEN | 
 | }; | 
 |  | 
 | // 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. | 
 | // Implementations of this class must be assumed to be non-thread-safe. All | 
 | // methods must be invoked on the sync thread. | 
 | class SyncEncryptionHandler { | 
 |  public: | 
 |   class NigoriState; | 
 |  | 
 |   // All Observer methods are done synchronously 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, | 
 |                                          BootstrapTokenType type) = 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; | 
 |  | 
 |     // The passphrase type has changed. |type| is the new type, | 
 |     // |passphrase_time| is the time the passphrase was set (unset if |type| | 
 |     // is KEYSTORE_PASSPHRASE or the passphrase was set before we started | 
 |     // recording the time). | 
 |     virtual void OnPassphraseTypeChanged(PassphraseType type, | 
 |                                          base::Time passphrase_time) = 0; | 
 |  | 
 |     // The user has set a passphrase using this device. | 
 |     // | 
 |     // |nigori_state| can be used to restore nigori state across | 
 |     // SyncEncryptionHandlerImpl lifetimes. See also SyncEncryptionHandlerImpl's | 
 |     // RestoredNigori method. | 
 |     virtual void OnLocalSetPassphraseEncryption( | 
 |         const NigoriState& nigori_state) = 0; | 
 |  | 
 |    protected: | 
 |     virtual ~Observer(); | 
 |   }; | 
 |  | 
 |   class NigoriState { | 
 |    public: | 
 |     NigoriState() {} | 
 |     sync_pb::NigoriSpecifics nigori_specifics; | 
 |   }; | 
 |  | 
 |   SyncEncryptionHandler(); | 
 |   virtual ~SyncEncryptionHandler(); | 
 |  | 
 |   // Add/Remove SyncEncryptionHandler::Observers. | 
 |   virtual void AddObserver(Observer* observer) = 0; | 
 |   virtual void RemoveObserver(Observer* observer) = 0; | 
 |  | 
 |   // Reads the nigori node, updates internal state as needed, and, if an | 
 |   // empty/stale 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 Init() = 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 IsEncryptEverythingEnabled() const = 0; | 
 |  | 
 |   // The set of types that are always encrypted. | 
 |   static ModelTypeSet SensitiveTypes(); | 
 | }; | 
 |  | 
 | }  // namespace syncer | 
 |  | 
 | #endif  // COMPONENTS_SYNC_ENGINE_SYNC_ENCRYPTION_HANDLER_H_ |