-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DTC-KeyManagement] Create KeyLoader
Creates the KeyLoader class that loads and synchronizes the signing key. Design: go/dtc-temp-key-storage Bug: b/290076221 Change-Id: I22ecdc60077d5c6b5a6f8ae16dd7bd6dd22c305a Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4727890 Reviewed-by: Sébastien Lalancette <seblalancette@chromium.org> Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com> Commit-Queue: Hamda Mare <hmare@google.com> Cr-Commit-Position: refs/heads/main@{#1185162}
- Loading branch information
hmare
authored and
Chromium LUCI CQ
committed
Aug 18, 2023
1 parent
8aa7c8b
commit df45d07
Showing
8 changed files
with
568 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_loader.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_loader.h" | ||
|
||
#include <utility> | ||
|
||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_loader_impl.h" | ||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mojo_key_network_delegate.h" | ||
#include "services/network/public/cpp/shared_url_loader_factory.h" | ||
#if BUILDFLAG(IS_WIN) | ||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h" | ||
#endif // BUILDFLAG(IS_WIN) | ||
|
||
namespace enterprise_connectors { | ||
|
||
KeyLoader::DTCLoadKeyResult::DTCLoadKeyResult() = default; | ||
KeyLoader::DTCLoadKeyResult::DTCLoadKeyResult( | ||
int code, | ||
scoped_refptr<SigningKeyPair> key_pair) | ||
: status_code(code), key_pair(std::move(key_pair)) {} | ||
|
||
KeyLoader::DTCLoadKeyResult::DTCLoadKeyResult(DTCLoadKeyResult&& other) = | ||
default; | ||
|
||
KeyLoader::DTCLoadKeyResult& KeyLoader::DTCLoadKeyResult::operator=( | ||
KeyLoader::DTCLoadKeyResult&& other) = default; | ||
|
||
KeyLoader::DTCLoadKeyResult::~DTCLoadKeyResult() = default; | ||
|
||
// static | ||
std::unique_ptr<KeyLoader> KeyLoader::Create( | ||
policy::BrowserDMTokenStorage* dm_token_storage, | ||
policy::DeviceManagementService* device_management_service, | ||
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { | ||
std::unique_ptr<KeyNetworkDelegate> network_delegate; | ||
if (url_loader_factory) { | ||
network_delegate = | ||
std::make_unique<MojoKeyNetworkDelegate>(std::move(url_loader_factory)); | ||
} else { | ||
#if BUILDFLAG(IS_WIN) | ||
network_delegate = std::make_unique<WinKeyNetworkDelegate>(); | ||
#else | ||
return nullptr; | ||
#endif // BUILDFLAG(IS_WIN) | ||
} | ||
|
||
return std::make_unique<KeyLoaderImpl>( | ||
dm_token_storage, device_management_service, std::move(network_delegate)); | ||
} | ||
|
||
} // namespace enterprise_connectors |
57 changes: 57 additions & 0 deletions
57
chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_loader.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_BROWSER_KEY_LOADER_H_ | ||
#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_BROWSER_KEY_LOADER_H_ | ||
|
||
#include <memory> | ||
|
||
#include "base/functional/callback_forward.h" | ||
#include "base/memory/scoped_refptr.h" | ||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/common/key_types.h" | ||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.h" | ||
#include "third_party/abseil-cpp/absl/types/optional.h" | ||
|
||
namespace network { | ||
class SharedURLLoaderFactory; | ||
} // namespace network | ||
|
||
namespace policy { | ||
class BrowserDMTokenStorage; | ||
class DeviceManagementService; | ||
} // namespace policy | ||
|
||
namespace enterprise_connectors { | ||
|
||
class KeyLoader { | ||
public: | ||
struct DTCLoadKeyResult { | ||
DTCLoadKeyResult(); | ||
DTCLoadKeyResult(int status_code, scoped_refptr<SigningKeyPair> key_pair); | ||
DTCLoadKeyResult(DTCLoadKeyResult&&); | ||
DTCLoadKeyResult& operator=(DTCLoadKeyResult&&); | ||
~DTCLoadKeyResult(); | ||
// HTTP response code from the key upload request. | ||
absl::optional<int> status_code; | ||
// Permanent signing key. | ||
scoped_refptr<SigningKeyPair> key_pair; | ||
}; | ||
|
||
using LoadKeyCallback = base::OnceCallback<void(DTCLoadKeyResult)>; | ||
|
||
static std::unique_ptr<KeyLoader> Create( | ||
policy::BrowserDMTokenStorage* dm_token_storage, | ||
policy::DeviceManagementService* device_management_service, | ||
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); | ||
|
||
virtual ~KeyLoader() = default; | ||
|
||
// Loads the key from the permanent key storage. The result of the key | ||
// load/synchronization is returned via the `callback`. | ||
virtual void LoadKey(LoadKeyCallback callback) = 0; | ||
}; | ||
|
||
} // namespace enterprise_connectors | ||
|
||
#endif // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_BROWSER_KEY_LOADER_H_ |
134 changes: 134 additions & 0 deletions
134
chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_loader_impl.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include <utility> | ||
|
||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_loader_impl.h" | ||
|
||
#include "base/check.h" | ||
#include "base/functional/bind.h" | ||
#include "base/metrics/histogram_functions.h" | ||
#include "base/task/task_traits.h" | ||
#include "base/task/thread_pool.h" | ||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_utils.h" | ||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/metrics_utils.h" | ||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_upload_request.h" | ||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/util.h" | ||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_util.h" | ||
#include "components/enterprise/browser/controller/browser_dm_token_storage.h" | ||
#include "components/policy/core/common/cloud/device_management_service.h" | ||
|
||
namespace enterprise_connectors { | ||
|
||
namespace { | ||
|
||
// Creating the request object involves generating a signature which may be | ||
// resource intensive. It is, therefore, on a background thread. | ||
absl::optional<const KeyUploadRequest> CreateRequest( | ||
const GURL& dm_server_url, | ||
const std::string& dm_token, | ||
scoped_refptr<SigningKeyPair> key_pair) { | ||
if (!key_pair) { | ||
return absl::nullopt; | ||
} | ||
return KeyUploadRequest::Create(dm_server_url, dm_token, *key_pair); | ||
} | ||
|
||
} // namespace | ||
|
||
KeyLoaderImpl::KeyLoaderImpl( | ||
policy::BrowserDMTokenStorage* dm_token_storage, | ||
policy::DeviceManagementService* device_management_service, | ||
std::unique_ptr<KeyNetworkDelegate> network_delegate) | ||
: dm_token_storage_(dm_token_storage), | ||
device_management_service_(device_management_service), | ||
network_delegate_(std::move(network_delegate)) { | ||
DCHECK(dm_token_storage_); | ||
DCHECK(device_management_service_); | ||
DCHECK(network_delegate_); | ||
} | ||
|
||
KeyLoaderImpl::~KeyLoaderImpl() = default; | ||
|
||
void KeyLoaderImpl::LoadKey(LoadKeyCallback callback) { | ||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | ||
base::ThreadPool::PostTaskAndReplyWithResult( | ||
FROM_HERE, | ||
{base::MayBlock(), base::TaskPriority::USER_BLOCKING, | ||
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, | ||
base::BindOnce(&LoadPersistedKey), | ||
base::BindOnce(&KeyLoaderImpl::SynchronizePublicKey, | ||
weak_factory_.GetWeakPtr(), std::move(callback))); | ||
} | ||
|
||
void KeyLoaderImpl::SynchronizePublicKey( | ||
LoadKeyCallback callback, | ||
scoped_refptr<SigningKeyPair> key_pair) { | ||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | ||
|
||
if (!key_pair) { | ||
LogSynchronizationError(DTSynchronizationError::kMissingKeyPair); | ||
std::move(callback).Run(DTCLoadKeyResult()); | ||
return; | ||
} | ||
|
||
auto dm_token = dm_token_storage_->RetrieveDMToken(); | ||
if (!dm_token.is_valid()) { | ||
LogSynchronizationError(DTSynchronizationError::kInvalidDmToken); | ||
std::move(callback).Run(DTCLoadKeyResult()); | ||
return; | ||
} | ||
|
||
auto dm_server_url = GetUploadBrowserPublicKeyUrl( | ||
dm_token_storage_->RetrieveClientId(), dm_token.value(), | ||
device_management_service_); | ||
if (!dm_server_url) { | ||
LogSynchronizationError(DTSynchronizationError::kInvalidServerUrl); | ||
std::move(callback).Run(DTCLoadKeyResult()); | ||
return; | ||
} | ||
|
||
base::ThreadPool::PostTaskAndReplyWithResult( | ||
FROM_HERE, | ||
{base::MayBlock(), base::TaskPriority::USER_BLOCKING, | ||
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, | ||
base::BindOnce(&CreateRequest, GURL(dm_server_url.value()), | ||
dm_token.value(), key_pair), | ||
base::BindOnce(&KeyLoaderImpl::OnKeyUploadRequestCreated, | ||
weak_factory_.GetWeakPtr(), key_pair, | ||
std::move(callback))); | ||
} | ||
|
||
void KeyLoaderImpl::OnKeyUploadRequestCreated( | ||
scoped_refptr<SigningKeyPair> key_pair, | ||
LoadKeyCallback callback, | ||
absl::optional<const KeyUploadRequest> upload_request) { | ||
if (!upload_request) { | ||
LogSynchronizationError(DTSynchronizationError::kCannotBuildRequest); | ||
std::move(callback).Run(DTCLoadKeyResult()); | ||
return; | ||
} | ||
|
||
network_delegate_->SendPublicKeyToDmServer( | ||
upload_request->dm_server_url(), upload_request->dm_token(), | ||
upload_request->request_body(), | ||
base::BindOnce(&KeyLoaderImpl::OnKeyUploadCompleted, | ||
weak_factory_.GetWeakPtr(), std::move(key_pair), | ||
std::move(callback))); | ||
} | ||
|
||
void KeyLoaderImpl::OnKeyUploadCompleted( | ||
scoped_refptr<enterprise_connectors::SigningKeyPair> key_pair, | ||
LoadKeyCallback callback, | ||
int status_code) { | ||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); | ||
|
||
static constexpr char kUploadCodeHistogram[] = | ||
"Enterprise.DeviceTrust.SyncSigningKey.UploadCode"; | ||
base::UmaHistogramSparse(kUploadCodeHistogram, status_code); | ||
|
||
std::move(callback).Run(DTCLoadKeyResult(status_code, std::move(key_pair))); | ||
} | ||
|
||
} // namespace enterprise_connectors |
66 changes: 66 additions & 0 deletions
66
chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_loader_impl.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_BROWSER_KEY_LOADER_IMPL_H_ | ||
#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_BROWSER_KEY_LOADER_IMPL_H_ | ||
|
||
#include <memory> | ||
|
||
#include "base/memory/raw_ptr.h" | ||
#include "base/memory/scoped_refptr.h" | ||
#include "base/memory/weak_ptr.h" | ||
#include "base/sequence_checker.h" | ||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/browser/key_loader.h" | ||
#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.h" | ||
|
||
namespace policy { | ||
class BrowserDMTokenStorage; | ||
class DeviceManagementService; | ||
} // namespace policy | ||
|
||
namespace enterprise_connectors { | ||
class KeyNetworkDelegate; | ||
class KeyUploadRequest; | ||
|
||
class KeyLoaderImpl : public KeyLoader { | ||
public: | ||
KeyLoaderImpl(policy::BrowserDMTokenStorage* dm_token_storage, | ||
policy::DeviceManagementService* device_management_service, | ||
std::unique_ptr<KeyNetworkDelegate> network_delegate); | ||
~KeyLoaderImpl() override; | ||
|
||
// KeyLoader: | ||
void LoadKey(LoadKeyCallback callback) override; | ||
|
||
private: | ||
// Performs the key synchronization on the `key_pair`. | ||
void SynchronizePublicKey(LoadKeyCallback callback, | ||
scoped_refptr<SigningKeyPair> key_pair); | ||
|
||
// Uses the `upload_request` to upload the `key_pair` to the DM Server. | ||
void OnKeyUploadRequestCreated( | ||
scoped_refptr<SigningKeyPair> key_pair, | ||
LoadKeyCallback callback, | ||
absl::optional<const KeyUploadRequest> upload_request); | ||
|
||
// Builds the load key result using the HTTP response `status_code` and | ||
// `key_pair`, and returns the result to the `callback`. | ||
void OnKeyUploadCompleted(scoped_refptr<SigningKeyPair> key_pair, | ||
LoadKeyCallback callback, | ||
int status_code); | ||
|
||
raw_ptr<policy::BrowserDMTokenStorage> dm_token_storage_; | ||
raw_ptr<policy::DeviceManagementService> device_management_service_; | ||
std::unique_ptr<KeyNetworkDelegate> network_delegate_; | ||
|
||
// Checker used to validate that non-background tasks should be | ||
// running on the original sequence. | ||
SEQUENCE_CHECKER(sequence_checker_); | ||
|
||
base::WeakPtrFactory<KeyLoaderImpl> weak_factory_{this}; | ||
}; | ||
|
||
} // namespace enterprise_connectors | ||
|
||
#endif // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_BROWSER_KEY_LOADER_IMPL_H_ |
Oops, something went wrong.