Home | History | Annotate | Download | only in internal_api
      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_SYNC_ENCRYPTION_HANDLER_IMPL_H_
      6 #define SYNC_INTERNAL_API_SYNC_ENCRYPTION_HANDLER_IMPL_H_
      7 
      8 #include <string>
      9 
     10 #include "base/compiler_specific.h"
     11 #include "base/gtest_prod_util.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/memory/weak_ptr.h"
     14 #include "base/observer_list.h"
     15 #include "base/threading/thread_checker.h"
     16 #include "base/time/time.h"
     17 #include "sync/base/sync_export.h"
     18 #include "sync/internal_api/public/sync_encryption_handler.h"
     19 #include "sync/syncable/nigori_handler.h"
     20 #include "sync/util/cryptographer.h"
     21 
     22 namespace syncer {
     23 
     24 class Encryptor;
     25 struct UserShare;
     26 class WriteNode;
     27 class WriteTransaction;
     28 
     29 // Sync encryption handler implementation.
     30 //
     31 // This class acts as the respository of all sync encryption state, and handles
     32 // encryption related changes/queries coming from both the chrome side and
     33 // the sync side (via NigoriHandler). It is capable of modifying all sync data
     34 // (re-encryption), updating the encrypted types, changing the encryption keys,
     35 // and creating/receiving nigori node updates.
     36 //
     37 // The class should live as long as the directory itself in order to ensure
     38 // any data read/written is properly decrypted/encrypted.
     39 //
     40 // Note: See sync_encryption_handler.h for a description of the chrome visible
     41 // methods and what they do, and nigori_handler.h for a description of the
     42 // sync methods.
     43 // All methods are non-thread-safe and should only be called from the sync
     44 // thread unless explicitly noted otherwise.
     45 class SYNC_EXPORT_PRIVATE SyncEncryptionHandlerImpl
     46     : public SyncEncryptionHandler,
     47       public syncable::NigoriHandler {
     48  public:
     49   SyncEncryptionHandlerImpl(
     50       UserShare* user_share,
     51       Encryptor* encryptor,
     52       const std::string& restored_key_for_bootstrapping,
     53       const std::string& restored_keystore_key_for_bootstrapping);
     54   virtual ~SyncEncryptionHandlerImpl();
     55 
     56   // SyncEncryptionHandler implementation.
     57   virtual void AddObserver(Observer* observer) OVERRIDE;
     58   virtual void RemoveObserver(Observer* observer) OVERRIDE;
     59   virtual void Init() OVERRIDE;
     60   virtual void SetEncryptionPassphrase(const std::string& passphrase,
     61                                        bool is_explicit) OVERRIDE;
     62   virtual void SetDecryptionPassphrase(const std::string& passphrase) OVERRIDE;
     63   virtual void EnableEncryptEverything() OVERRIDE;
     64   virtual bool EncryptEverythingEnabled() const OVERRIDE;
     65   virtual PassphraseType GetPassphraseType() const OVERRIDE;
     66 
     67   // NigoriHandler implementation.
     68   // Note: all methods are invoked while the caller holds a transaction.
     69   virtual void ApplyNigoriUpdate(
     70       const sync_pb::NigoriSpecifics& nigori,
     71       syncable::BaseTransaction* const trans) OVERRIDE;
     72   virtual void UpdateNigoriFromEncryptedTypes(
     73       sync_pb::NigoriSpecifics* nigori,
     74       syncable::BaseTransaction* const trans) const OVERRIDE;
     75   virtual bool NeedKeystoreKey(
     76       syncable::BaseTransaction* const trans) const OVERRIDE;
     77   virtual bool SetKeystoreKeys(
     78       const google::protobuf::RepeatedPtrField<google::protobuf::string>& keys,
     79       syncable::BaseTransaction* const trans) OVERRIDE;
     80   // Can be called from any thread.
     81   virtual ModelTypeSet GetEncryptedTypes(
     82       syncable::BaseTransaction* const trans) const OVERRIDE;
     83 
     84   // Unsafe getters. Use only if sync is not up and running and there is no risk
     85   // of other threads calling this.
     86   Cryptographer* GetCryptographerUnsafe();
     87   ModelTypeSet GetEncryptedTypesUnsafe();
     88 
     89   bool MigratedToKeystore();
     90   base::Time migration_time() const;
     91   base::Time custom_passphrase_time() const;
     92 
     93  private:
     94   friend class SyncEncryptionHandlerImplTest;
     95   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
     96                            NigoriEncryptionTypes);
     97   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
     98                            EncryptEverythingExplicit);
     99   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    100                            EncryptEverythingImplicit);
    101   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    102                            UnknownSensitiveTypes);
    103   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    104                            GetKeystoreDecryptor);
    105   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    106                            ReceiveMigratedNigoriKeystorePass);
    107   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    108                            ReceiveUmigratedNigoriAfterMigration);
    109   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    110                            ReceiveOldMigratedNigori);
    111   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    112                            SetKeystoreAfterReceivingMigratedNigori);
    113   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    114                            SetCustomPassAfterMigration);
    115   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    116                            SetCustomPassAfterMigrationNoKeystoreKey);
    117   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    118                            SetImplicitPassAfterMigrationNoKeystoreKey);
    119   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    120                            MigrateOnEncryptEverythingKeystorePassphrase);
    121   FRIEND_TEST_ALL_PREFIXES(SyncEncryptionHandlerImplTest,
    122                            ReceiveMigratedNigoriWithOldPassphrase);
    123 
    124   // Container for members that require thread safety protection.  All members
    125   // that can be accessed from more than one thread should be held here and
    126   // accessed via UnlockVault(..) and UnlockVaultMutable(..), which enforce
    127   // that a transaction is held.
    128   struct Vault {
    129     Vault(Encryptor* encryptor, ModelTypeSet encrypted_types);
    130     ~Vault();
    131 
    132     // Sync's cryptographer. Used for encrypting and decrypting sync data.
    133     Cryptographer cryptographer;
    134     // The set of types that require encryption.
    135     ModelTypeSet encrypted_types;
    136 
    137    private:
    138     DISALLOW_COPY_AND_ASSIGN(Vault);
    139   };
    140 
    141   // Iterate over all encrypted types ensuring each entry is properly encrypted.
    142   void ReEncryptEverything(WriteTransaction* trans);
    143 
    144   // Apply a nigori update. Updates internal and cryptographer state.
    145   // Returns true on success, false if |nigori| was incompatible, and the
    146   // nigori node must be corrected.
    147   // Note: must be called from within a transaction.
    148   bool ApplyNigoriUpdateImpl(const sync_pb::NigoriSpecifics& nigori,
    149                              syncable::BaseTransaction* const trans);
    150 
    151   // Wrapper around WriteEncryptionStateToNigori that creates a new write
    152   // transaction.
    153   void RewriteNigori();
    154 
    155   // Write the current encryption state into the nigori node. This includes
    156   // the encrypted types/encrypt everything state, as well as the keybag/
    157   // explicit passphrase state (if the cryptographer is ready).
    158   void WriteEncryptionStateToNigori(WriteTransaction* trans);
    159 
    160   // Updates local encrypted types from |nigori|.
    161   // Returns true if the local set of encrypted types either matched or was
    162   // a subset of that in |nigori|. Returns false if the local state already
    163   // had stricter encryption than |nigori|, and the nigori node needs to be
    164   // updated with the newer encryption state.
    165   // Note: must be called from within a transaction.
    166   bool UpdateEncryptedTypesFromNigori(
    167       const sync_pb::NigoriSpecifics& nigori,
    168       syncable::BaseTransaction* const trans);
    169 
    170   // TODO(zea): make these public and have them replace SetEncryptionPassphrase
    171   // and SetDecryptionPassphrase.
    172   // Helper methods for handling passphrases once keystore migration has taken
    173   // place.
    174   //
    175   // Sets a new custom passphrase. Should only be called if a custom passphrase
    176   // is not already set.
    177   // Triggers OnPassphraseAccepted on success, OnPassphraseRequired if a custom
    178   // passphrase already existed.
    179   void SetCustomPassphrase(const std::string& passphrase,
    180                            WriteTransaction* trans,
    181                            WriteNode* nigori_node);
    182   // Decrypt the encryption keybag using a user provided passphrase.
    183   // Should only be called if the current passphrase is a frozen implicit
    184   // passphrase or a custom passphrase.
    185   // Triggers OnPassphraseAccepted on success, OnPassphraseRequired on failure.
    186   void DecryptPendingKeysWithExplicitPassphrase(const std::string& passphrase,
    187                                                 WriteTransaction* trans,
    188                                                 WriteNode* nigori_node);
    189 
    190   // The final step of SetEncryptionPassphrase and SetDecryptionPassphrase that
    191   // notifies observers of the result of the set passphrase operation, updates
    192   // the nigori node, and does re-encryption.
    193   // |success|: true if the operation was successful and false otherwise. If
    194   //            success == false, we send an OnPassphraseRequired notification.
    195   // |bootstrap_token|: used to inform observers if the cryptographer's
    196   //                    bootstrap token was updated.
    197   // |is_explicit|: used to differentiate between a custom passphrase (true) and
    198   //                a GAIA passphrase that is implicitly used for encryption
    199   //                (false).
    200   // |trans| and |nigori_node|: used to access data in the cryptographer.
    201   void FinishSetPassphrase(bool success,
    202                            const std::string& bootstrap_token,
    203                            WriteTransaction* trans,
    204                            WriteNode* nigori_node);
    205 
    206   // Merges the given set of encrypted types with the existing set and emits a
    207   // notification if necessary.
    208   // Note: must be called from within a transaction.
    209   void MergeEncryptedTypes(ModelTypeSet new_encrypted_types,
    210                            syncable::BaseTransaction* const trans);
    211 
    212   // Helper methods for ensuring transactions are held when accessing
    213   // |vault_unsafe_|.
    214   Vault* UnlockVaultMutable(syncable::BaseTransaction* const trans);
    215   const Vault& UnlockVault(syncable::BaseTransaction* const trans) const;
    216 
    217   // Helper method for determining if migration of a nigori node should be
    218   // triggered or not.
    219   // Conditions for triggering migration:
    220   // 1. Cryptographer has no pending keys
    221   // 2. Nigori node isn't already properly migrated or we need to rotate keys.
    222   // 3. Keystore key is available.
    223   // Note: if the nigori node is migrated but has an invalid state, will return
    224   // true (e.g. node has KEYSTORE_PASSPHRASE, local is CUSTOM_PASSPHRASE).
    225   bool ShouldTriggerMigration(const sync_pb::NigoriSpecifics& nigori,
    226                               const Cryptographer& cryptographer) const;
    227 
    228   // Performs the actual migration of the |nigori_node| to support keystore
    229   // encryption iff ShouldTriggerMigration(..) returns true.
    230   bool AttemptToMigrateNigoriToKeystore(WriteTransaction* trans,
    231                                         WriteNode* nigori_node);
    232 
    233   // Fill |encrypted_blob| with the keystore decryptor token if
    234   // |encrypted_blob|'s contents didn't already contain the key.
    235   // The keystore decryptor token is the serialized current default encryption
    236   // key, encrypted with the keystore key.
    237   bool GetKeystoreDecryptor(
    238       const Cryptographer& cryptographer,
    239       const std::string& keystore_key,
    240       sync_pb::EncryptedData* encrypted_blob);
    241 
    242   // Helper method for installing the keys encrypted in |encryption_keybag|
    243   // into |cryptographer|.
    244   // Returns true on success, false if we were unable to install the keybag.
    245   // Will not update the default key.
    246   bool AttemptToInstallKeybag(const sync_pb::EncryptedData& keybag,
    247                               bool update_default,
    248                               Cryptographer* cryptographer);
    249 
    250   // Helper method for decrypting pending keys with the keystore bootstrap.
    251   // If successful, the default will become the key encrypted in the keystore
    252   // bootstrap, and will return true. Else will return false.
    253   bool DecryptPendingKeysWithKeystoreKey(
    254       const std::string& keystore_key,
    255       const sync_pb::EncryptedData& keystore_bootstrap,
    256       Cryptographer* cryptographer);
    257 
    258   // Helper to enable encrypt everything, notifying observers if necessary.
    259   // Will not perform re-encryption.
    260   void EnableEncryptEverythingImpl(syncable::BaseTransaction* const trans);
    261 
    262   // If an explicit passphrase is in use, returns the time at which it was set
    263   // (if known). Else return base::Time().
    264   base::Time GetExplicitPassphraseTime() const;
    265 
    266   base::ThreadChecker thread_checker_;
    267 
    268   ObserverList<SyncEncryptionHandler::Observer> observers_;
    269 
    270   // The current user share (for creating transactions).
    271   UserShare* user_share_;
    272 
    273   // Container for all data that can be accessed from multiple threads. Do not
    274   // access this object directly. Instead access it via UnlockVault(..) and
    275   // UnlockVaultMutable(..).
    276   Vault vault_unsafe_;
    277 
    278   // Sync encryption state that is only modified and accessed from the sync
    279   // thread.
    280   // Whether all current and future types should be encrypted.
    281   bool encrypt_everything_;
    282   // The current state of the passphrase required to decrypt the encryption
    283   // keys stored in the nigori node.
    284   PassphraseType passphrase_type_;
    285 
    286   // The current keystore key provided by the server.
    287   std::string keystore_key_;
    288 
    289   // The set of old keystore keys. Every time a key rotation occurs, the server
    290   // sends down all previous keystore keys as well as the new key. We preserve
    291   // the old keys so that when we re-encrypt we can ensure they're all added to
    292   // the keybag (and to detect that a key rotation has occurred).
    293   std::vector<std::string> old_keystore_keys_;
    294 
    295   // The number of times we've automatically (i.e. not via SetPassphrase or
    296   // conflict resolver) updated the nigori's encryption keys in this chrome
    297   // instantiation.
    298   int nigori_overwrite_count_;
    299 
    300   // The time the nigori was migrated to support keystore encryption.
    301   base::Time migration_time_;
    302 
    303   // The time the custom passphrase was set for this account. Not valid
    304   // if there is no custom passphrase or the custom passphrase was set
    305   // before support for this field was added.
    306   base::Time custom_passphrase_time_;
    307 
    308   base::WeakPtrFactory<SyncEncryptionHandlerImpl> weak_ptr_factory_;
    309 
    310   DISALLOW_COPY_AND_ASSIGN(SyncEncryptionHandlerImpl);
    311 };
    312 
    313 }  // namespace syncer
    314 
    315 #endif  // SYNC_INTERNAL_API_PUBLIC_SYNC_ENCRYPTION_HANDLER_IMPL_H_
    316