-
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.
Add ArcKeyMintBridge, CertStoreBridgeKeyMint and cert_store.mojom
Add ArcKeyMintBridge and CertStoreBridgeKeyMint. Mostly copied over from chrome/browser/ash/arc/keymaster, and will co-exist with the later. In follow-up CL(s), CertStoreService will determine whether system should use KeyMint or Keymaster, and choose either ArcKeyMintBridge or ArcKeymasterBridge. This CL also added a cert_store.mojom, copied over from chrome/services/keymaster/public/mojom/cert_store.mojom. Adding a separate mojom file allows for potential changes related to KeyMint, while keeping the one for Keymaster stable. It also allows easier deprecation of Keymaster in the future. As of this CL, ArcKeyMintBridge and CertStoreBridgeKeyMint are not yet being meaningfully used, thus should not break anything either. Bug: b:247941366 Test: autoninja -C out/Default/ ash_components_unittests && testing/xvfb.py ./out/Default/ash_components_unittests Test: autoninja -C out_hatch/Release/ chrome chrome_sandbox nacl_helper Change-Id: Ibf24793b671aa8ea091ac127a81578bc2d680018 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4189369 Reviewed-by: Alex Gough <ajgo@chromium.org> Reviewed-by: Yury Khmel <khmel@chromium.org> Commit-Queue: Yao Li <yaohuali@google.com> Reviewed-by: Ken Rockot <rockot@google.com> Cr-Commit-Position: refs/heads/main@{#1100784}
- Loading branch information
Showing
12 changed files
with
441 additions
and
7 deletions.
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
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 |
---|---|---|
@@ -1,5 +1,6 @@ | ||
include_rules = [ | ||
"+chrome/services/keymanagement/public", | ||
"+chrome/services/keymaster/public", | ||
"+chrome/services/keymint/public", | ||
"+services/tracing/public", | ||
] |
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
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
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
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,163 @@ | ||
// 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/ash/arc/keymint/arc_keymint_bridge.h" | ||
|
||
#include "ash/components/arc/arc_browser_context_keyed_service_factory_base.h" | ||
#include "ash/components/arc/session/arc_bridge_service.h" | ||
#include "base/memory/singleton.h" | ||
#include "chrome/browser/ash/arc/keymint/cert_store_bridge_keymint.h" | ||
#include "chromeos/ash/components/dbus/arc/arc_keymaster_client.h" // XXX | ||
#include "mojo/core/embedder/embedder.h" | ||
#include "mojo/public/cpp/platform/platform_channel.h" | ||
|
||
namespace arc { | ||
|
||
namespace { | ||
|
||
// Singleton factory for ArcKeyMintBridge | ||
class ArcKeyMintBridgeFactory | ||
: public internal::ArcBrowserContextKeyedServiceFactoryBase< | ||
ArcKeyMintBridge, | ||
ArcKeyMintBridgeFactory> { | ||
public: | ||
// Factory name used by ArcBrowserContextKeyedServiceFactoryBase. | ||
static constexpr const char* kName = "ArcKeyMintBridgeFactory"; | ||
|
||
static ArcKeyMintBridgeFactory* GetInstance() { | ||
return base::Singleton<ArcKeyMintBridgeFactory>::get(); | ||
} | ||
|
||
private: | ||
friend base::DefaultSingletonTraits<ArcKeyMintBridgeFactory>; | ||
ArcKeyMintBridgeFactory() = default; | ||
~ArcKeyMintBridgeFactory() override = default; | ||
}; | ||
|
||
} // namespace | ||
|
||
// static | ||
BrowserContextKeyedServiceFactory* ArcKeyMintBridge::GetFactory() { | ||
return ArcKeyMintBridgeFactory::GetInstance(); | ||
} | ||
|
||
// static | ||
ArcKeyMintBridge* ArcKeyMintBridge::GetForBrowserContext( | ||
content::BrowserContext* context) { | ||
return ArcKeyMintBridgeFactory::GetForBrowserContext(context); | ||
} | ||
|
||
ArcKeyMintBridge::ArcKeyMintBridge(content::BrowserContext* context, | ||
ArcBridgeService* bridge_service) | ||
: arc_bridge_service_(bridge_service), | ||
cert_store_bridge_( | ||
std::make_unique<keymint::CertStoreBridgeKeyMint>(context)), | ||
weak_factory_(this) { | ||
if (arc_bridge_service_) { | ||
arc_bridge_service_->keymint()->SetHost(this); | ||
} | ||
} | ||
|
||
ArcKeyMintBridge::~ArcKeyMintBridge() { | ||
if (arc_bridge_service_) { | ||
arc_bridge_service_->keymint()->SetHost(nullptr); | ||
} | ||
} | ||
|
||
void ArcKeyMintBridge::UpdatePlaceholderKeys( | ||
std::vector<keymint::mojom::ChromeOsKeyPtr> keys, | ||
UpdatePlaceholderKeysCallback callback) { | ||
if (cert_store_bridge_->IsProxyBound()) { | ||
cert_store_bridge_->UpdatePlaceholderKeysInKeyMint(std::move(keys), | ||
std::move(callback)); | ||
} else { | ||
BootstrapMojoConnection(base::BindOnce( | ||
&ArcKeyMintBridge::UpdatePlaceholderKeysAfterBootstrap, | ||
weak_factory_.GetWeakPtr(), std::move(keys), std::move(callback))); | ||
} | ||
} | ||
|
||
void ArcKeyMintBridge::UpdatePlaceholderKeysAfterBootstrap( | ||
std::vector<keymint::mojom::ChromeOsKeyPtr> keys, | ||
UpdatePlaceholderKeysCallback callback, | ||
bool bootstrapResult) { | ||
if (bootstrapResult) { | ||
cert_store_bridge_->UpdatePlaceholderKeysInKeyMint(std::move(keys), | ||
std::move(callback)); | ||
} else { | ||
std::move(callback).Run(/*success=*/false); | ||
} | ||
} | ||
|
||
void ArcKeyMintBridge::GetServer(GetServerCallback callback) { | ||
if (keymint_server_proxy_.is_bound()) { | ||
std::move(callback).Run(keymint_server_proxy_.Unbind()); | ||
} else { | ||
BootstrapMojoConnection( | ||
base::BindOnce(&ArcKeyMintBridge::GetServerAfterBootstrap, | ||
weak_factory_.GetWeakPtr(), std::move(callback))); | ||
} | ||
} | ||
|
||
void ArcKeyMintBridge::GetServerAfterBootstrap(GetServerCallback callback, | ||
bool bootstrapResult) { | ||
if (bootstrapResult) { | ||
std::move(callback).Run(keymint_server_proxy_.Unbind()); | ||
} else { | ||
std::move(callback).Run(mojo::NullRemote()); | ||
} | ||
} | ||
|
||
void ArcKeyMintBridge::OnBootstrapMojoConnection( | ||
BootstrapMojoConnectionCallback callback, | ||
bool result) { | ||
if (result) { | ||
DVLOG(1) << "Success bootstrapping Mojo in arc-keymasterd."; | ||
} else { | ||
LOG(ERROR) << "Error bootstrapping Mojo in arc-keymasterd."; | ||
keymint_server_proxy_.reset(); | ||
} | ||
std::move(callback).Run(result); | ||
} | ||
|
||
void ArcKeyMintBridge::BootstrapMojoConnection( | ||
BootstrapMojoConnectionCallback callback) { | ||
DVLOG(1) << "Bootstrapping arc-keymasterd Mojo connection via D-Bus."; | ||
|
||
mojo::OutgoingInvitation invitation; | ||
mojo::PlatformChannel channel; | ||
mojo::ScopedMessagePipeHandle server_pipe; | ||
if (mojo::core::IsMojoIpczEnabled()) { | ||
constexpr uint64_t kKeyMintPipeAttachment = 0; | ||
server_pipe = invitation.AttachMessagePipe(kKeyMintPipeAttachment); | ||
} else { | ||
server_pipe = invitation.AttachMessagePipe("arc-keymint-pipe"); | ||
} | ||
if (!server_pipe.is_valid()) { | ||
LOG(ERROR) << "ArcKeyMintBridge could not bind to invitation"; | ||
std::move(callback).Run(false); | ||
return; | ||
} | ||
|
||
// Bootstrap cert_store channel attached to the same invitation. | ||
cert_store_bridge_->BindToInvitation(&invitation); | ||
|
||
mojo::OutgoingInvitation::Send(std::move(invitation), | ||
base::kNullProcessHandle, | ||
channel.TakeLocalEndpoint()); | ||
|
||
keymint_server_proxy_.Bind(mojo::PendingRemote<mojom::keymint::KeyMintServer>( | ||
std::move(server_pipe), 0u)); | ||
DVLOG(1) << "Bound remote KeyMintServer interface to pipe."; | ||
keymint_server_proxy_.set_disconnect_handler( | ||
base::BindOnce(&mojo::Remote<mojom::keymint::KeyMintServer>::reset, | ||
base::Unretained(&keymint_server_proxy_))); | ||
// TODO(b/247941366): Create ArcKeyMintClient. | ||
ash::ArcKeymasterClient::Get()->BootstrapMojoConnection( | ||
channel.TakeRemoteEndpoint().TakePlatformHandle().TakeFD(), | ||
base::BindOnce(&ArcKeyMintBridge::OnBootstrapMojoConnection, | ||
weak_factory_.GetWeakPtr(), std::move(callback))); | ||
} | ||
|
||
} // namespace arc |
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,86 @@ | ||
// 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_ASH_ARC_KEYMINT_ARC_KEYMINT_BRIDGE_H_ | ||
#define CHROME_BROWSER_ASH_ARC_KEYMINT_ARC_KEYMINT_BRIDGE_H_ | ||
|
||
#include "ash/components/arc/arc_browser_context_keyed_service_factory_base.h" | ||
#include "ash/components/arc/mojom/keymint.mojom.h" | ||
#include "chrome/browser/ash/arc/keymint/cert_store_bridge_keymint.h" | ||
#include "components/keyed_service/core/keyed_service.h" | ||
#include "mojo/public/cpp/bindings/remote.h" | ||
|
||
namespace content { | ||
class BrowserContext; | ||
} // namespace content | ||
|
||
namespace arc { | ||
|
||
class ArcBridgeService; | ||
|
||
// This class is responsible for providing a KeyMintServer proxy by | ||
// bootstrapping a mojo connection with the arc-keymintd daemon. The mojo | ||
// connection is bootstrapped lazily during the first call to GetServer. Chrome | ||
// has no further involvement once the KeyMintServer proxy has been forwarded | ||
// to the KeyMintInstance in ARC. | ||
class ArcKeyMintBridge : public KeyedService, | ||
public mojom::keymint::KeyMintHost { | ||
public: | ||
using mojom::keymint::KeyMintHost::GetServerCallback; | ||
using UpdatePlaceholderKeysCallback = base::OnceCallback<void(bool)>; | ||
|
||
// Returns singleton instance for the given BrowserContext, or nullptr if the | ||
// browser |context| is not allowed to use ARC. | ||
static ArcKeyMintBridge* GetForBrowserContext( | ||
content::BrowserContext* context); | ||
|
||
ArcKeyMintBridge(content::BrowserContext* context, | ||
ArcBridgeService* bridge_service); | ||
|
||
ArcKeyMintBridge(const ArcKeyMintBridge&) = delete; | ||
ArcKeyMintBridge& operator=(const ArcKeyMintBridge&) = delete; | ||
|
||
~ArcKeyMintBridge() override; | ||
|
||
// Return the factory instance for this class. | ||
static BrowserContextKeyedServiceFactory* GetFactory(); | ||
|
||
// Update the list of placeholder keys to be instlaled in arc-keymasterd. | ||
// | ||
// Made virtual for override in tests. | ||
virtual void UpdatePlaceholderKeys( | ||
std::vector<keymint::mojom::ChromeOsKeyPtr> keys, | ||
UpdatePlaceholderKeysCallback callback); | ||
void UpdatePlaceholderKeysAfterBootstrap( | ||
std::vector<keymint::mojom::ChromeOsKeyPtr> keys, | ||
UpdatePlaceholderKeysCallback callback, | ||
bool bootstrapResult); | ||
// KeyMintHost mojo interface. | ||
void GetServer(GetServerCallback callback) override; | ||
|
||
private: | ||
using BootstrapMojoConnectionCallback = base::OnceCallback<void(bool)>; | ||
|
||
void BootstrapMojoConnection(BootstrapMojoConnectionCallback callback); | ||
void OnBootstrapMojoConnection(BootstrapMojoConnectionCallback callback, | ||
bool bootstrapResult); | ||
void GetServerAfterBootstrap(GetServerCallback callback, | ||
bool bootstrapResult); | ||
|
||
ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager. | ||
// | ||
// Points to a proxy bound to the implementation in arc-keymintd. | ||
mojo::Remote<mojom::keymint::KeyMintServer> keymint_server_proxy_; | ||
|
||
// Points to the host implementation in Chrome, used to interact with the | ||
// arc-keymintd daemon. | ||
std::unique_ptr<keymint::CertStoreBridgeKeyMint> cert_store_bridge_; | ||
|
||
// WeakPtrFactory to use for callbacks. | ||
base::WeakPtrFactory<ArcKeyMintBridge> weak_factory_; | ||
}; | ||
|
||
} // namespace arc | ||
|
||
#endif // CHROME_BROWSER_ASH_ARC_KEYMINT_ARC_KEYMINT_BRIDGE_H_ |
64 changes: 64 additions & 0 deletions
64
chrome/browser/ash/arc/keymint/cert_store_bridge_keymint.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,64 @@ | ||
// 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/ash/arc/keymint/cert_store_bridge_keymint.h" | ||
|
||
#include <cstdint> | ||
#include <utility> | ||
|
||
#include "base/functional/bind.h" | ||
#include "base/functional/callback.h" | ||
#include "base/logging.h" | ||
#include "mojo/core/embedder/embedder.h" | ||
#include "mojo/public/cpp/bindings/pending_remote.h" | ||
|
||
namespace arc::keymint { | ||
|
||
CertStoreBridgeKeyMint::CertStoreBridgeKeyMint(content::BrowserContext* context) | ||
: weak_ptr_factory_(this) {} | ||
|
||
CertStoreBridgeKeyMint::~CertStoreBridgeKeyMint() = default; | ||
|
||
void CertStoreBridgeKeyMint::UpdatePlaceholderKeysInKeyMint( | ||
std::vector<mojom::ChromeOsKeyPtr> keys, | ||
mojom::CertStoreInstance::UpdatePlaceholderKeysCallback callback) { | ||
if (cert_store_proxy_.is_bound()) { | ||
cert_store_proxy_->UpdatePlaceholderKeys(std::move(keys), | ||
std::move(callback)); | ||
} else { | ||
LOG(ERROR) << "Tried to update placeholders but cert store is not bound"; | ||
std::move(callback).Run(/*success=*/false); | ||
} | ||
} | ||
|
||
bool CertStoreBridgeKeyMint::IsProxyBound() const { | ||
return cert_store_proxy_.is_bound(); | ||
} | ||
|
||
void CertStoreBridgeKeyMint::BindToInvitation( | ||
mojo::OutgoingInvitation* invitation) { | ||
VLOG(2) << "CertStoreBridgeKeyMint::BootstrapMojoConnection"; | ||
|
||
mojo::ScopedMessagePipeHandle pipe; | ||
if (mojo::core::IsMojoIpczEnabled()) { | ||
constexpr uint64_t kCertStorePipeAttachment = 1; | ||
pipe = invitation->AttachMessagePipe(kCertStorePipeAttachment); | ||
} else { | ||
pipe = invitation->AttachMessagePipe("arc-cert-store-keymint-pipe"); | ||
} | ||
|
||
if (!pipe.is_valid()) { | ||
LOG(ERROR) << "CertStoreBridgeKeyMint could not bind to invitation"; | ||
return; | ||
} | ||
|
||
cert_store_proxy_.Bind(mojo::PendingRemote<keymint::mojom::CertStoreInstance>( | ||
std::move(pipe), 0u)); | ||
VLOG(2) << "Bound remote CertStoreInstance interface to pipe."; | ||
cert_store_proxy_.set_disconnect_handler( | ||
base::BindOnce(&mojo::Remote<keymint::mojom::CertStoreInstance>::reset, | ||
base::Unretained(&cert_store_proxy_))); | ||
} | ||
|
||
} // namespace arc::keymint |
Oops, something went wrong.