Home | History | Annotate | Download | only in public
      1 // Copyright 2012 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 SYNC_INTERNAL_API_PUBLIC_SYNC_ENCRYPTION_HANDLER_H_
      6 #define SYNC_INTERNAL_API_PUBLIC_SYNC_ENCRYPTION_HANDLER_H_
      7 
      8 #include <string>
      9 
     10 #include "base/time/time.h"
     11 #include "sync/base/sync_export.h"
     12 #include "sync/internal_api/public/base/model_type.h"
     13 
     14 namespace sync_pb {
     15 class EncryptedData;
     16 }
     17 
     18 namespace syncer {
     19 
     20 class Cryptographer;
     21 
     22 // Reasons due to which Cryptographer might require a passphrase.
     23 enum PassphraseRequiredReason {
     24   REASON_PASSPHRASE_NOT_REQUIRED = 0,  // Initial value.
     25   REASON_ENCRYPTION = 1,               // The cryptographer requires a
     26                                        // passphrase for its first attempt at
     27                                        // encryption. Happens only during
     28                                        // migration or upgrade.
     29   REASON_DECRYPTION = 2,               // The cryptographer requires a
     30                                        // passphrase for its first attempt at
     31                                        // decryption.
     32 };
     33 
     34 // The different states for the encryption passphrase. These control if and how
     35 // the user should be prompted for a decryption passphrase.
     36 enum PassphraseType {
     37   IMPLICIT_PASSPHRASE = 0,             // GAIA-based passphrase (deprecated).
     38   KEYSTORE_PASSPHRASE = 1,             // Keystore passphrase.
     39   FROZEN_IMPLICIT_PASSPHRASE = 2,      // Frozen GAIA passphrase.
     40   CUSTOM_PASSPHRASE = 3,               // User-provided passphrase.
     41 };
     42 
     43 // Enum used to distinguish which bootstrap encryption token is being updated.
     44 enum BootstrapTokenType {
     45   PASSPHRASE_BOOTSTRAP_TOKEN,
     46   KEYSTORE_BOOTSTRAP_TOKEN
     47 };
     48 
     49 // Sync's encryption handler. Handles tracking encrypted types, ensuring the
     50 // cryptographer encrypts with the proper key and has the most recent keybag,
     51 // and keeps the nigori node up to date.
     52 // Implementations of this class must be assumed to be non-thread-safe. All
     53 // methods must be invoked on the sync thread.
     54 class SYNC_EXPORT SyncEncryptionHandler {
     55  public:
     56   // All Observer methods are done synchronously from within a transaction and
     57   // on the sync thread.
     58   class SYNC_EXPORT Observer {
     59    public:
     60     Observer();
     61 
     62     // Called when user interaction is required to obtain a valid passphrase.
     63     // - If the passphrase is required for encryption, |reason| will be
     64     //   REASON_ENCRYPTION.
     65     // - If the passphrase is required for the decryption of data that has
     66     //   already been encrypted, |reason| will be REASON_DECRYPTION.
     67     // - If the passphrase is required because decryption failed, and a new
     68     //   passphrase is required, |reason| will be REASON_SET_PASSPHRASE_FAILED.
     69     //
     70     // |pending_keys| is a copy of the cryptographer's pending keys, that may be
     71     // cached by the frontend for subsequent use by the UI.
     72     virtual void OnPassphraseRequired(
     73         PassphraseRequiredReason reason,
     74         const sync_pb::EncryptedData& pending_keys) = 0;
     75     // Called when the passphrase provided by the user has been accepted and is
     76     // now used to encrypt sync data.
     77 
     78     virtual void OnPassphraseAccepted() = 0;
     79     // |bootstrap_token| is an opaque base64 encoded representation of the key
     80     // generated by the current passphrase, and is provided to the observer for
     81     // persistence purposes and use in a future initialization of sync (e.g.
     82     // after restart). The boostrap token will always be derived from the most
     83     // recent GAIA password (for accounts with implicit passphrases), even if
     84     // the data is still encrypted with an older GAIA password. For accounts
     85     // with explicit passphrases, it will be the most recently seen custom
     86     // passphrase.
     87     virtual void OnBootstrapTokenUpdated(
     88         const std::string& bootstrap_token,
     89         BootstrapTokenType type) = 0;
     90 
     91     // Called when the set of encrypted types or the encrypt
     92     // everything flag has been changed.  Note that encryption isn't
     93     // complete until the OnEncryptionComplete() notification has been
     94     // sent (see below).
     95     //
     96     // |encrypted_types| will always be a superset of
     97     // Cryptographer::SensitiveTypes().  If |encrypt_everything| is
     98     // true, |encrypted_types| will be the set of all known types.
     99     //
    100     // Until this function is called, observers can assume that the
    101     // set of encrypted types is Cryptographer::SensitiveTypes() and
    102     // that the encrypt everything flag is false.
    103     virtual void OnEncryptedTypesChanged(
    104         ModelTypeSet encrypted_types,
    105         bool encrypt_everything) = 0;
    106 
    107     // Called after we finish encrypting the current set of encrypted
    108     // types.
    109     virtual void OnEncryptionComplete() = 0;
    110 
    111     // The cryptographer has been updated. Listeners should check that their
    112     // own state matches the cryptographer.
    113     // Used primarily for debugging.
    114     virtual void OnCryptographerStateChanged(Cryptographer* cryptographer) = 0;
    115 
    116     // The passphrase type has changed. |type| is the new type,
    117     // |passphrase_time| is the time the passphrase was set (unset if |type|
    118     // is KEYSTORE_PASSPHRASE or the passphrase was set before we started
    119     // recording the time).
    120     virtual void OnPassphraseTypeChanged(PassphraseType type,
    121                                          base::Time passphrase_time) = 0;
    122 
    123    protected:
    124     virtual ~Observer();
    125   };
    126 
    127   SyncEncryptionHandler();
    128   virtual ~SyncEncryptionHandler();
    129 
    130   // Add/Remove SyncEncryptionHandler::Observers.
    131   virtual void AddObserver(Observer* observer) = 0;
    132   virtual void RemoveObserver(Observer* observer) = 0;
    133 
    134   // Reads the nigori node, updates internal state as needed, and, if an
    135   // empty/stale nigori node is detected, overwrites the existing
    136   // nigori node. Upon completion, if the cryptographer is still ready
    137   // attempts to re-encrypt all sync data.
    138   // Note: This method is expensive (it iterates through all encrypted types),
    139   // so should only be used sparingly (e.g. on startup).
    140   virtual void Init() = 0;
    141 
    142   // Attempts to re-encrypt encrypted data types using the passphrase provided.
    143   // Notifies observers of the result of the operation via OnPassphraseAccepted
    144   // or OnPassphraseRequired, updates the nigori node, and does re-encryption as
    145   // appropriate. If an explicit password has been set previously, we drop
    146   // subsequent requests to set a passphrase. If the cryptographer has pending
    147   // keys, and a new implicit passphrase is provided, we try decrypting the
    148   // pending keys with it, and if that fails, we cache the passphrase for
    149   // re-encryption once the pending keys are decrypted.
    150   virtual void SetEncryptionPassphrase(const std::string& passphrase,
    151                                        bool is_explicit) = 0;
    152 
    153   // Provides a passphrase for decrypting the user's existing sync data.
    154   // Notifies observers of the result of the operation via OnPassphraseAccepted
    155   // or OnPassphraseRequired, updates the nigori node, and does re-encryption as
    156   // appropriate if there is a previously cached encryption passphrase. It is an
    157   // error to call this when we don't have pending keys.
    158   virtual void SetDecryptionPassphrase(const std::string& passphrase) = 0;
    159 
    160   // Enables encryption of all datatypes.
    161   virtual void EnableEncryptEverything() = 0;
    162 
    163   // Whether encryption of all datatypes is enabled. If false, only sensitive
    164   // types are encrypted.
    165   virtual bool EncryptEverythingEnabled() const = 0;
    166 
    167   // Returns the current state of the passphrase needed to decrypt the
    168   // bag of encryption keys in the nigori node.
    169   virtual PassphraseType GetPassphraseType() const = 0;
    170 
    171   // The set of types that are always encrypted.
    172   static ModelTypeSet SensitiveTypes();
    173 };
    174 
    175 }  // namespace syncer
    176 
    177 #endif  // SYNC_INTERNAL_API_PUBLIC_SYNC_ENCRYPTION_HANDLER_H_
    178