summaryrefslogtreecommitdiffstats
path: root/chromium/sync/internal_api/public/sync_encryption_handler.h
blob: cd1cfc04f02c498f5972abab79dd363584ce3cdf (plain)
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
177
// 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 SYNC_INTERNAL_API_PUBLIC_SYNC_ENCRYPTION_HANDLER_H_
#define SYNC_INTERNAL_API_PUBLIC_SYNC_ENCRYPTION_HANDLER_H_

#include <string>

#include "base/time/time.h"
#include "sync/base/sync_export.h"
#include "sync/internal_api/public/base/model_type.h"

namespace sync_pb {
class EncryptedData;
}

namespace syncer {

class Cryptographer;

// 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.
};

// The different states for the encryption passphrase. These control if and how
// the user should be prompted for a decryption passphrase.
enum PassphraseType {
  IMPLICIT_PASSPHRASE = 0,             // GAIA-based passphrase (deprecated).
  KEYSTORE_PASSPHRASE = 1,             // Keystore passphrase.
  FROZEN_IMPLICIT_PASSPHRASE = 2,      // Frozen GAIA passphrase.
  CUSTOM_PASSPHRASE = 3,               // User-provided passphrase.
};

// 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 SYNC_EXPORT SyncEncryptionHandler {
 public:
  // All Observer methods are done synchronously from within a transaction and
  // on the sync thread.
  class SYNC_EXPORT 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;

   protected:
    virtual ~Observer();
  };

  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 EncryptEverythingEnabled() const = 0;

  // Returns the current state of the passphrase needed to decrypt the
  // bag of encryption keys in the nigori node.
  virtual PassphraseType GetPassphraseType() const = 0;

  // The set of types that are always encrypted.
  static ModelTypeSet SensitiveTypes();
};

}  // namespace syncer

#endif  // SYNC_INTERNAL_API_PUBLIC_SYNC_ENCRYPTION_HANDLER_H_