Commit 27e19891 authored by Josh Nohle's avatar Josh Nohle Committed by Commit Bot

[DeviceSync v2] Add CryptAuthDeviceSyncer abstract class

Children of the base CryptAuthDeviceSyncer class will implement the
CryptAuth v2 DeviceSync flow, which includes uploading local device
metadata, receiving remote device metadata, receiving device
feature statuses--supported/unsupported and enabled/disabled--for
multidevice (BetterTogether) features, and sharing the group private
key with remote devices. The metadata and group private key exchanges
are end-to-end encrypted.

The analogous class for v2 Enrollment is CryptAuthV2Enroller.

See design at https://go/cros-devicesync-v2-syncer.

Bug: 951969
Change-Id: Ie069759d72f096ce97ef081a43b7f118ed9ea574
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1648837
Commit-Queue: Josh Nohle <nohle@chromium.org>
Reviewed-by: default avatarKyle Horimoto <khorimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#667186}
parent eb8fc93c
...@@ -25,6 +25,8 @@ static_library("device_sync") { ...@@ -25,6 +25,8 @@ static_library("device_sync") {
"cryptauth_device_registry_impl.h", "cryptauth_device_registry_impl.h",
"cryptauth_device_sync_result.cc", "cryptauth_device_sync_result.cc",
"cryptauth_device_sync_result.h", "cryptauth_device_sync_result.h",
"cryptauth_device_syncer.cc",
"cryptauth_device_syncer.h",
"cryptauth_enroller.h", "cryptauth_enroller.h",
"cryptauth_enroller_factory_impl.cc", "cryptauth_enroller_factory_impl.cc",
"cryptauth_enroller_factory_impl.h", "cryptauth_enroller_factory_impl.h",
......
// Copyright 2019 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.
#include "chromeos/services/device_sync/cryptauth_device_syncer.h"
#include <utility>
namespace chromeos {
namespace device_sync {
CryptAuthDeviceSyncer::CryptAuthDeviceSyncer() = default;
CryptAuthDeviceSyncer::~CryptAuthDeviceSyncer() = default;
void CryptAuthDeviceSyncer::Sync(
const cryptauthv2::RequestContext& request_context,
DeviceSyncAttemptFinishedCallback callback) {
// Enforce that Sync() can only be called once.
DCHECK(!was_sync_called_);
was_sync_called_ = true;
callback_ = std::move(callback);
OnAttemptStarted(request_context);
}
void CryptAuthDeviceSyncer::OnAttemptFinished(
const CryptAuthDeviceSyncResult& device_sync_result) {
DCHECK(callback_);
std::move(callback_).Run(device_sync_result);
}
} // namespace device_sync
} // namespace chromeos
// Copyright 2019 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 CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_DEVICE_SYNCER_H_
#define CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_DEVICE_SYNCER_H_
#include "base/callback.h"
#include "base/macros.h"
#include "base/optional.h"
namespace cryptauthv2 {
class RequestContext;
} // namespace cryptauthv2
namespace chromeos {
namespace device_sync {
class CryptAuthDeviceSyncResult;
// Implements the client end of the CryptAuth v2 DeviceSync protocol, which
// consists of three to four request/response interactions with the CryptAuth
// servers:
//
// 1a) First SyncMetadataRequest: Contains what this device believes to be the
// group public key. This could be a newly generated key or one from local
// storage. The device's metadata is encrypted with this key and included in
// the request.
//
// 1b) First SyncMetadataResponse: The response from CryptAuth possibly includes
// the correct group key pair, where the private key is encrypted with this
// device's CryptAuthKeyBunde::kDeviceSyncBetterTogether public key. If the
// group public key is not set, the server is indicating that a new group
// key pair must be created by this device. In this case or if the group
// public key in the response differs from the one sent in the request,
// another SyncMetadataRequest is made. Otherwise, the second
// SyncMetadataRequest is skipped and the encrypted remote device metadata
// is decrypted using the group private key.
//
// 2a) (Possible) Second SyncMetadataRequest: Not invoked if the group public
// key from the first SyncMetadataResponse (1b) matches that sent in the
// first SyncMetadataRequest (1a). Now that the correct group key pair has
// been established, another request is made.
//
// 2b) (Possible) Second SyncMetadataResponse: The included remote device
// metadata can now be decrypted. The remote devices are only those
// registered in the DeviceSync:BetterTogether group, in other words, those
// using v2 DeviceSync.
//
// 3) BatchGetFeatureStatusesRequest/Response: Gets the supported and enabled
// states of all multidevice (BetterTogether) features for all devices.
//
// 4a) ShareGroupPrivateKeyRequest: Sends CryptAuth the device's group private
// key encrypted with each remote device's
// CryptAuthKeyBundle::kDeviceSyncBetterTogether public key. This ensures
// end-to-end encryption of the group private key and consequently the
// device metadata.
//
// 4b) ShareGroupPrivateKeyResponse: We view this response as an indication that
// the ShareGroupPrivateKeyRequest was successful.
//
// A CryptAuthDeviceSyncer object is designed to be used for only one Sync()
// call. For a new DeviceSync attempt, a new object should be created.
class CryptAuthDeviceSyncer {
public:
virtual ~CryptAuthDeviceSyncer();
using DeviceSyncAttemptFinishedCallback =
base::OnceCallback<void(const CryptAuthDeviceSyncResult&)>;
// Starts the v2 DeviceSync flow.
// |request_context|: Information about the DeviceSync attempt--such as
// invocation reason and device identifiers--that is sent to CryptAuth in
// each request.
// |callback|: Invoked when the DeviceSync attempt concludes, successfully or
// not. The CryptAuthDeviceSyncResult provides information about the
// outcome of the DeviceSync attempt and possibly a new ClientDirective.
void Sync(const cryptauthv2::RequestContext& request_context,
DeviceSyncAttemptFinishedCallback callback);
protected:
CryptAuthDeviceSyncer();
virtual void OnAttemptStarted(
const cryptauthv2::RequestContext& request_context) = 0;
void OnAttemptFinished(const CryptAuthDeviceSyncResult& device_sync_result);
DeviceSyncAttemptFinishedCallback callback_;
bool was_sync_called_ = false;
DISALLOW_COPY_AND_ASSIGN(CryptAuthDeviceSyncer);
};
} // namespace device_sync
} // namespace chromeos
#endif // CHROMEOS_SERVICES_DEVICE_SYNC_CRYPTAUTH_DEVICE_SYNCER_H_
...@@ -50,7 +50,8 @@ class CryptAuthEnrollmentResult; ...@@ -50,7 +50,8 @@ class CryptAuthEnrollmentResult;
// 2b) EnrollKeysResponse: We simply view this response as an indication that // 2b) EnrollKeysResponse: We simply view this response as an indication that
// the EnrollKeysRequest was successful. // the EnrollKeysRequest was successful.
// //
// An instance of this class can only call Enroll() once. // A CryptAuthV2Enroller object is designed to be used for only one Enroll()
// call. For a new Enrollment attempt, a new object should be created.
class CryptAuthV2Enroller { class CryptAuthV2Enroller {
public: public:
virtual ~CryptAuthV2Enroller(); virtual ~CryptAuthV2Enroller();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment