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