1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
// 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_
|