root/sync/internal_api/public/sync_encryption_handler.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


// 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_

/* [<][>][^][v][top][bottom][index][help] */