Commit 9c85a9d2 authored by Erik Chen's avatar Erik Chen Committed by Commit Bot

Add lacros plumbing for chromeOS attestation blessed extension API.

Attestation is the process of proving ownership of a private
cryptographic key. One side issues a challenge, and the entity must sign
the challenge using a private key. chromeOS exposes blessed extension
APIs that allow force-installed policy extensions to issue attestation
challenges. By default, these are not available on lacros.

This CL adds basic plumbing for
enterprise.platformKeys.challengeMachineKey. This is not intended to be
a fully functional implementation -- that will require further
refactoring and debugging from domain experts.

Bug: 1113443
Change-Id: I8781ef1367242de59faacb372cf6453925fdfa86
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2324303Reviewed-by: default avatarJorge Lucangeli Obes <jorgelo@chromium.org>
Reviewed-by: default avatarMaksim Ivanov <emaxx@chromium.org>
Reviewed-by: default avatarKaran Bhatia <karandeepb@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Reviewed-by: default avatarMichael Ershov <miersh@google.com>
Commit-Queue: Erik Chen <erikchen@chromium.org>
Auto-Submit: Erik Chen <erikchen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#797435}
parent 1edcc9f6
...@@ -926,6 +926,8 @@ source_set("chromeos") { ...@@ -926,6 +926,8 @@ source_set("chromeos") {
"concierge_helper_service.h", "concierge_helper_service.h",
"crosapi/ash_chrome_service_impl.cc", "crosapi/ash_chrome_service_impl.cc",
"crosapi/ash_chrome_service_impl.h", "crosapi/ash_chrome_service_impl.h",
"crosapi/attestation_ash.cc",
"crosapi/attestation_ash.h",
"crosapi/browser_loader.cc", "crosapi/browser_loader.cc",
"crosapi/browser_loader.h", "crosapi/browser_loader.h",
"crosapi/browser_manager.cc", "crosapi/browser_manager.cc",
......
...@@ -4,11 +4,15 @@ ...@@ -4,11 +4,15 @@
#include "chrome/browser/chromeos/crosapi/ash_chrome_service_impl.h" #include "chrome/browser/chromeos/crosapi/ash_chrome_service_impl.h"
#include <memory>
#include <utility> #include <utility>
#include <vector>
#include "base/logging.h" #include "base/logging.h"
#include "chrome/browser/chromeos/crosapi/attestation_ash.h"
#include "chrome/browser/chromeos/crosapi/screen_manager_crosapi.h" #include "chrome/browser/chromeos/crosapi/screen_manager_crosapi.h"
#include "chrome/browser/chromeos/crosapi/select_file_ash.h" #include "chrome/browser/chromeos/crosapi/select_file_ash.h"
#include "chromeos/crosapi/mojom/attestation.mojom.h"
#include "chromeos/crosapi/mojom/screen_manager.mojom.h" #include "chromeos/crosapi/mojom/screen_manager.mojom.h"
#include "chromeos/crosapi/mojom/select_file.mojom.h" #include "chromeos/crosapi/mojom/select_file.mojom.h"
...@@ -25,6 +29,12 @@ AshChromeServiceImpl::AshChromeServiceImpl( ...@@ -25,6 +29,12 @@ AshChromeServiceImpl::AshChromeServiceImpl(
AshChromeServiceImpl::~AshChromeServiceImpl() = default; AshChromeServiceImpl::~AshChromeServiceImpl() = default;
void AshChromeServiceImpl::BindAttestation(
mojo::PendingReceiver<crosapi::mojom::Attestation> receiver) {
attestation_ash_ =
std::make_unique<crosapi::AttestationAsh>(std::move(receiver));
}
void AshChromeServiceImpl::BindSelectFile( void AshChromeServiceImpl::BindSelectFile(
mojo::PendingReceiver<mojom::SelectFile> receiver) { mojo::PendingReceiver<mojom::SelectFile> receiver) {
select_file_crosapi_ = std::make_unique<SelectFileAsh>(std::move(receiver)); select_file_crosapi_ = std::make_unique<SelectFileAsh>(std::move(receiver));
......
...@@ -15,6 +15,7 @@ class ScreenManagerCrosapi; ...@@ -15,6 +15,7 @@ class ScreenManagerCrosapi;
namespace crosapi { namespace crosapi {
class AttestationAsh;
class SelectFileAsh; class SelectFileAsh;
// Implementation of AshChromeService. It provides a set of APIs that // Implementation of AshChromeService. It provides a set of APIs that
...@@ -26,6 +27,8 @@ class AshChromeServiceImpl : public mojom::AshChromeService { ...@@ -26,6 +27,8 @@ class AshChromeServiceImpl : public mojom::AshChromeService {
~AshChromeServiceImpl() override; ~AshChromeServiceImpl() override;
// crosapi::mojom::AshChromeService: // crosapi::mojom::AshChromeService:
void BindAttestation(
mojo::PendingReceiver<crosapi::mojom::Attestation> receiver) override;
void BindScreenManager( void BindScreenManager(
mojo::PendingReceiver<mojom::ScreenManager> receiver) override; mojo::PendingReceiver<mojom::ScreenManager> receiver) override;
void BindSelectFile( void BindSelectFile(
...@@ -34,6 +37,7 @@ class AshChromeServiceImpl : public mojom::AshChromeService { ...@@ -34,6 +37,7 @@ class AshChromeServiceImpl : public mojom::AshChromeService {
private: private:
mojo::Receiver<mojom::AshChromeService> receiver_; mojo::Receiver<mojom::AshChromeService> receiver_;
std::unique_ptr<crosapi::AttestationAsh> attestation_ash_;
std::unique_ptr<ScreenManagerCrosapi> screen_manager_crosapi_; std::unique_ptr<ScreenManagerCrosapi> screen_manager_crosapi_;
std::unique_ptr<SelectFileAsh> select_file_crosapi_; std::unique_ptr<SelectFileAsh> select_file_crosapi_;
}; };
......
// Copyright 2020 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 "chrome/browser/chromeos/crosapi/attestation_ash.h"
#include <utility>
#include "chrome/browser/chromeos/attestation/tpm_challenge_key.h"
#include "chrome/browser/profiles/profile_manager.h"
namespace crosapi {
AttestationAsh::AttestationAsh(
mojo::PendingReceiver<mojom::Attestation> receiver)
: receiver_(this, std::move(receiver)) {}
AttestationAsh::~AttestationAsh() = default;
void AttestationAsh::ChallengeKey(const std::string& challenge,
mojom::ChallengeKeyType type,
ChallengeKeyCallback callback) {
if (!crosapi::mojom::IsKnownEnumValue(type)) {
mojom::ChallengeKeyResultPtr result_ptr = mojom::ChallengeKeyResult::New();
result_ptr->set_error_message("unsupported challenge key type");
std::move(callback).Run(std::move(result_ptr));
return;
}
chromeos::attestation::AttestationKeyType key_type;
switch (type) {
case mojom::ChallengeKeyType::kUser:
key_type = chromeos::attestation::KEY_USER;
break;
case mojom::ChallengeKeyType::kDevice:
key_type = chromeos::attestation::KEY_DEVICE;
break;
}
Profile* profile = ProfileManager::GetActiveUserProfile();
std::unique_ptr<chromeos::attestation::TpmChallengeKey> challenge_key =
chromeos::attestation::TpmChallengeKeyFactory::Create();
chromeos::attestation::TpmChallengeKey* challenge_key_ptr =
challenge_key.get();
outstanding_challenges_.push_back(std::move(challenge_key));
challenge_key_ptr->BuildResponse(
key_type, profile,
base::BindOnce(&AttestationAsh::DidChallengeKey,
weak_factory_.GetWeakPtr(), std::move(callback),
challenge_key_ptr),
challenge,
/*register_key=*/false, /*key_name_for_spkac=*/"");
}
void AttestationAsh::DidChallengeKey(
ChallengeKeyCallback callback,
void* challenge_key_ptr,
const chromeos::attestation::TpmChallengeKeyResult& result) {
mojom::ChallengeKeyResultPtr result_ptr = mojom::ChallengeKeyResult::New();
if (result.IsSuccess()) {
result_ptr->set_challenge_response(result.challenge_response);
} else {
result_ptr->set_error_message(result.GetErrorMessage());
}
std::move(callback).Run(std::move(result_ptr));
// Remove the outstanding challenge_key object.
bool found = false;
for (auto it = outstanding_challenges_.begin();
it != outstanding_challenges_.end(); ++it) {
if (it->get() == challenge_key_ptr) {
outstanding_challenges_.erase(it);
found = true;
break;
}
}
DCHECK(found);
}
} // namespace crosapi
// Copyright 2020 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 CHROME_BROWSER_CHROMEOS_CROSAPI_ATTESTATION_ASH_H_
#define CHROME_BROWSER_CHROMEOS_CROSAPI_ATTESTATION_ASH_H_
#include <memory>
#include <vector>
#include "base/memory/weak_ptr.h"
#include "chromeos/crosapi/mojom/attestation.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
namespace chromeos {
namespace attestation {
class TpmChallengeKey;
struct TpmChallengeKeyResult;
} // namespace attestation
} // namespace chromeos
namespace crosapi {
// This class is the ash implementation of the Attestation crosapi. It allows
// lacros to expose blessed extension APIs which issue key challenges. These in
// turn are forwarded to ash, which signs the challenge with a private key.
class AttestationAsh : public mojom::Attestation {
public:
explicit AttestationAsh(mojo::PendingReceiver<mojom::Attestation> receiver);
AttestationAsh(const AttestationAsh&) = delete;
AttestationAsh& operator=(const AttestationAsh&) = delete;
~AttestationAsh() override;
// mojom::Attestation:
void ChallengeKey(const std::string& challenge,
mojom::ChallengeKeyType type,
ChallengeKeyCallback callback) override;
private:
// |challenge| is used as a opaque identifier to match against the unique_ptr
// in outstanding_challenges_. It should not be dereferenced.
void DidChallengeKey(
ChallengeKeyCallback callback,
void* challenge,
const chromeos::attestation::TpmChallengeKeyResult& result);
// Container to keep outstanding challenges alive.
std::vector<std::unique_ptr<chromeos::attestation::TpmChallengeKey>>
outstanding_challenges_;
mojo::Receiver<mojom::Attestation> receiver_;
base::WeakPtrFactory<AttestationAsh> weak_factory_{this};
};
} // namespace crosapi
#endif // CHROME_BROWSER_CHROMEOS_CROSAPI_ATTESTATION_ASH_H_
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import("//build/config/chromeos/ui_mode.gni")
import("//build/config/features.gni") import("//build/config/features.gni")
import("//build/config/ui.gni") import("//build/config/ui.gni")
import("//chrome/common/features.gni") import("//chrome/common/features.gni")
...@@ -753,6 +754,7 @@ static_library("extensions") { ...@@ -753,6 +754,7 @@ static_library("extensions") {
"//apps", "//apps",
"//base/util/values:values_util", "//base/util/values:values_util",
"//build:branding_buildflags", "//build:branding_buildflags",
"//build:lacros_buildflags",
"//chrome:extra_resources", "//chrome:extra_resources",
"//chrome:resources", "//chrome:resources",
"//chrome:strings", "//chrome:strings",
...@@ -923,6 +925,20 @@ static_library("extensions") { ...@@ -923,6 +925,20 @@ static_library("extensions") {
deps += [ "//components/autofill_assistant/browser" ] deps += [ "//components/autofill_assistant/browser" ]
} }
if (chromeos_is_browser_only || is_chromeos) {
sources += [ "api/enterprise_platform_keys/enterprise_platform_keys_api.h" ]
if (chromeos_is_browser_only) {
sources += [
"api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.cc",
"api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.h",
]
deps += [
"//chromeos/crosapi/mojom",
"//chromeos/lacros",
]
}
}
if (is_chromeos) { if (is_chromeos) {
sources += [ sources += [
"api/certificate_provider/certificate_provider_api.cc", "api/certificate_provider/certificate_provider_api.cc",
...@@ -931,8 +947,8 @@ static_library("extensions") { ...@@ -931,8 +947,8 @@ static_library("extensions") {
"api/enterprise_device_attributes/enterprise_device_attributes_api.h", "api/enterprise_device_attributes/enterprise_device_attributes_api.h",
"api/enterprise_networking_attributes/enterprise_networking_attributes_api.cc", "api/enterprise_networking_attributes/enterprise_networking_attributes_api.cc",
"api/enterprise_networking_attributes/enterprise_networking_attributes_api.h", "api/enterprise_networking_attributes/enterprise_networking_attributes_api.h",
"api/enterprise_platform_keys/enterprise_platform_keys_api.cc", "api/enterprise_platform_keys/enterprise_platform_keys_api_ash.cc",
"api/enterprise_platform_keys/enterprise_platform_keys_api.h", "api/enterprise_platform_keys/enterprise_platform_keys_api_ash.h",
"api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc", "api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.cc",
"api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h", "api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h",
"api/file_handlers/non_native_file_system_delegate_chromeos.cc", "api/file_handlers/non_native_file_system_delegate_chromeos.cc",
......
// Copyright 2014 The Chromium Authors. All rights reserved. // Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// This file is included from autogenerated files based on
// chrome/common/extensions/api/enterprise_platform_keys_internal.idl and
// chrome/common/extensions/api/enterprise_platform_keys.idl.
#ifndef CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_H_ #ifndef CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_H_
#define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_H_ #define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_H_
#include <memory> #include "build/lacros_buildflags.h"
#include <string>
#include <vector>
#include "base/memory/ref_counted.h"
#include "chrome/browser/chromeos/platform_keys/platform_keys_service.h"
#include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h"
#include "extensions/browser/extension_function.h"
namespace net {
class X509Certificate;
using CertificateList = std::vector<scoped_refptr<X509Certificate>>;
} // namespace net
namespace extensions {
class EnterprisePlatformKeysInternalGenerateKeyFunction
: public ExtensionFunction {
private:
~EnterprisePlatformKeysInternalGenerateKeyFunction() override;
ResponseAction Run() override;
// Called when the key was generated. If an error occurred, |public_key_der|
// will be empty.
void OnGeneratedKey(const std::string& public_key_der,
chromeos::platform_keys::Status status);
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeysInternal.generateKey",
ENTERPRISE_PLATFORMKEYSINTERNAL_GENERATEKEY)
};
class EnterprisePlatformKeysGetCertificatesFunction : public ExtensionFunction {
private:
~EnterprisePlatformKeysGetCertificatesFunction() override;
ResponseAction Run() override;
// Called when the list of certificates was determined. If an error occurred,
// |certs| will be nullptr.
void OnGotCertificates(std::unique_ptr<net::CertificateList> certs,
chromeos::platform_keys::Status status);
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.getCertificates",
ENTERPRISE_PLATFORMKEYS_GETCERTIFICATES)
};
class EnterprisePlatformKeysImportCertificateFunction
: public ExtensionFunction {
private:
~EnterprisePlatformKeysImportCertificateFunction() override;
ResponseAction Run() override;
// Called when the certificate was imported.
void OnImportedCertificate(chromeos::platform_keys::Status status);
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.importCertificate",
ENTERPRISE_PLATFORMKEYS_IMPORTCERTIFICATE)
};
class EnterprisePlatformKeysRemoveCertificateFunction
: public ExtensionFunction {
private:
~EnterprisePlatformKeysRemoveCertificateFunction() override;
ResponseAction Run() override;
// Called when the certificate was removed.
void OnRemovedCertificate(chromeos::platform_keys::Status status);
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.removeCertificate",
ENTERPRISE_PLATFORMKEYS_REMOVECERTIFICATE)
};
class EnterprisePlatformKeysInternalGetTokensFunction
: public ExtensionFunction {
private:
~EnterprisePlatformKeysInternalGetTokensFunction() override;
ResponseAction Run() override;
// Called when the list of tokens was determined. If an error occurred,
// |token_ids| will be nullptr.
void OnGotTokens(
std::unique_ptr<std::vector<chromeos::platform_keys::TokenId>> token_ids,
chromeos::platform_keys::Status status);
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeysInternal.getTokens",
ENTERPRISE_PLATFORMKEYSINTERNAL_GETTOKENS)
};
class EnterprisePlatformKeysChallengeMachineKeyFunction
: public ExtensionFunction {
public:
EnterprisePlatformKeysChallengeMachineKeyFunction();
private:
~EnterprisePlatformKeysChallengeMachineKeyFunction() override;
ResponseAction Run() override;
// Called when the challenge operation is complete.
void OnChallengedKey(
const chromeos::attestation::TpmChallengeKeyResult& result);
EPKPChallengeKey impl_;
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeMachineKey",
ENTERPRISE_PLATFORMKEYS_CHALLENGEMACHINEKEY)
};
class EnterprisePlatformKeysChallengeUserKeyFunction
: public ExtensionFunction {
public:
EnterprisePlatformKeysChallengeUserKeyFunction();
private:
~EnterprisePlatformKeysChallengeUserKeyFunction() override;
ResponseAction Run() override;
// Called when the challenge operation is complete.
void OnChallengedKey(
const chromeos::attestation::TpmChallengeKeyResult& result);
EPKPChallengeKey impl_;
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeUserKey",
ENTERPRISE_PLATFORMKEYS_CHALLENGEUSERKEY)
};
} // namespace extensions #if BUILDFLAG(IS_LACROS)
#include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_lacros.h"
#else
#include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_ash.h"
#endif
#endif // CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_H_ #endif // CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_H_
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h" #include "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api_ash.h"
#include <utility> #include <utility>
......
// Copyright 2014 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 CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_ASH_H_
#define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_ASH_H_
#include <memory>
#include <string>
#include <vector>
#include "base/memory/ref_counted.h"
#include "chrome/browser/chromeos/platform_keys/platform_keys_service.h"
#include "chrome/browser/extensions/api/enterprise_platform_keys_private/enterprise_platform_keys_private_api.h"
#include "extensions/browser/extension_function.h"
namespace net {
class X509Certificate;
using CertificateList = std::vector<scoped_refptr<X509Certificate>>;
} // namespace net
namespace extensions {
class EnterprisePlatformKeysInternalGenerateKeyFunction
: public ExtensionFunction {
private:
~EnterprisePlatformKeysInternalGenerateKeyFunction() override;
ResponseAction Run() override;
// Called when the key was generated. If an error occurred, |public_key_der|
// will be empty.
void OnGeneratedKey(const std::string& public_key_der,
chromeos::platform_keys::Status status);
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeysInternal.generateKey",
ENTERPRISE_PLATFORMKEYSINTERNAL_GENERATEKEY)
};
class EnterprisePlatformKeysGetCertificatesFunction : public ExtensionFunction {
private:
~EnterprisePlatformKeysGetCertificatesFunction() override;
ResponseAction Run() override;
// Called when the list of certificates was determined. If an error occurred,
// |certs| will be nullptr.
void OnGotCertificates(std::unique_ptr<net::CertificateList> certs,
chromeos::platform_keys::Status status);
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.getCertificates",
ENTERPRISE_PLATFORMKEYS_GETCERTIFICATES)
};
class EnterprisePlatformKeysImportCertificateFunction
: public ExtensionFunction {
private:
~EnterprisePlatformKeysImportCertificateFunction() override;
ResponseAction Run() override;
// Called when the certificate was imported.
void OnImportedCertificate(chromeos::platform_keys::Status status);
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.importCertificate",
ENTERPRISE_PLATFORMKEYS_IMPORTCERTIFICATE)
};
class EnterprisePlatformKeysRemoveCertificateFunction
: public ExtensionFunction {
private:
~EnterprisePlatformKeysRemoveCertificateFunction() override;
ResponseAction Run() override;
// Called when the certificate was removed.
void OnRemovedCertificate(chromeos::platform_keys::Status status);
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.removeCertificate",
ENTERPRISE_PLATFORMKEYS_REMOVECERTIFICATE)
};
class EnterprisePlatformKeysInternalGetTokensFunction
: public ExtensionFunction {
private:
~EnterprisePlatformKeysInternalGetTokensFunction() override;
ResponseAction Run() override;
// Called when the list of tokens was determined. If an error occurred,
// |token_ids| will be nullptr.
void OnGotTokens(
std::unique_ptr<std::vector<chromeos::platform_keys::TokenId>> token_ids,
chromeos::platform_keys::Status status);
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeysInternal.getTokens",
ENTERPRISE_PLATFORMKEYSINTERNAL_GETTOKENS)
};
class EnterprisePlatformKeysChallengeMachineKeyFunction
: public ExtensionFunction {
public:
EnterprisePlatformKeysChallengeMachineKeyFunction();
private:
~EnterprisePlatformKeysChallengeMachineKeyFunction() override;
ResponseAction Run() override;
// Called when the challenge operation is complete.
void OnChallengedKey(
const chromeos::attestation::TpmChallengeKeyResult& result);
EPKPChallengeKey impl_;
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeMachineKey",
ENTERPRISE_PLATFORMKEYS_CHALLENGEMACHINEKEY)
};
class EnterprisePlatformKeysChallengeUserKeyFunction
: public ExtensionFunction {
public:
EnterprisePlatformKeysChallengeUserKeyFunction();
private:
~EnterprisePlatformKeysChallengeUserKeyFunction() override;
ResponseAction Run() override;
// Called when the challenge operation is complete.
void OnChallengedKey(
const chromeos::attestation::TpmChallengeKeyResult& result);
EPKPChallengeKey impl_;
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeUserKey",
ENTERPRISE_PLATFORMKEYS_CHALLENGEUSERKEY)
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_ASH_H_
// Copyright 2020 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 "chrome/browser/extensions/api/enterprise_platform_keys/enterprise_platform_keys_api.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "chrome/browser/extensions/api/platform_keys/platform_keys_api.h"
#include "chrome/common/extensions/api/enterprise_platform_keys.h"
#include "chromeos/lacros/lacros_chrome_service_impl.h"
namespace extensions {
namespace {
namespace api_epk = api::enterprise_platform_keys;
std::vector<uint8_t> VectorFromString(const std::string& s) {
return std::vector<uint8_t>(s.begin(), s.end());
}
std::string StringFromVector(const std::vector<uint8_t>& v) {
return std::string(v.begin(), v.end());
}
const char kLacrosNotImplementedError[] = "not-implemented-yet-for-lacros";
} // namespace
ExtensionFunction::ResponseAction LacrosNotImplementedExtensionFunction::Run() {
return RespondNow(Error(kLacrosNotImplementedError));
}
ExtensionFunction::ResponseAction
EnterprisePlatformKeysChallengeMachineKeyFunction::Run() {
std::unique_ptr<api_epk::ChallengeMachineKey::Params> params(
api_epk::ChallengeMachineKey::Params::Create(*args_));
EXTENSION_FUNCTION_VALIDATE(params);
// TODO(https://crbug.com/1113443): This implementation needs to check if the
// extension is allowlisted via the AttestationExtensionWhitelist policy.
auto c = base::BindOnce(
&EnterprisePlatformKeysChallengeMachineKeyFunction::OnChallengedKeyLacros,
this);
chromeos::LacrosChromeServiceImpl::Get()->attestation_remote()->ChallengeKey(
StringFromVector(params->challenge),
crosapi::mojom::ChallengeKeyType::kDevice, std::move(c));
return RespondLater();
}
void EnterprisePlatformKeysChallengeMachineKeyFunction::OnChallengedKeyLacros(
crosapi::mojom::ChallengeKeyResultPtr result) {
switch (result->which()) {
case crosapi::mojom::ChallengeKeyResult::Tag::ERROR_MESSAGE:
Respond(Error(result->get_error_message()));
return;
case crosapi::mojom::ChallengeKeyResult::Tag::CHALLENGE_RESPONSE:
Respond(ArgumentList(api_epk::ChallengeMachineKey::Results::Create(
VectorFromString(result->get_challenge_response()))));
return;
}
}
} // namespace extensions
// Copyright 2020 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 CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_LACROS_H_
#define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_LACROS_H_
#include "chromeos/crosapi/mojom/attestation.mojom.h"
#include "extensions/browser/extension_function.h"
namespace extensions {
class LacrosNotImplementedExtensionFunction : public ExtensionFunction {
protected:
~LacrosNotImplementedExtensionFunction() override = default;
private:
ResponseAction Run() override;
};
class EnterprisePlatformKeysGetCertificatesFunction
: public LacrosNotImplementedExtensionFunction {
private:
~EnterprisePlatformKeysGetCertificatesFunction() override = default;
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.getCertificates",
ENTERPRISE_PLATFORMKEYS_GETCERTIFICATES)
};
class EnterprisePlatformKeysImportCertificateFunction
: public LacrosNotImplementedExtensionFunction {
private:
~EnterprisePlatformKeysImportCertificateFunction() override = default;
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.importCertificate",
ENTERPRISE_PLATFORMKEYS_IMPORTCERTIFICATE)
};
class EnterprisePlatformKeysRemoveCertificateFunction
: public LacrosNotImplementedExtensionFunction {
private:
~EnterprisePlatformKeysRemoveCertificateFunction() override = default;
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.removeCertificate",
ENTERPRISE_PLATFORMKEYS_REMOVECERTIFICATE)
};
class EnterprisePlatformKeysInternalGetTokensFunction
: public LacrosNotImplementedExtensionFunction {
private:
~EnterprisePlatformKeysInternalGetTokensFunction() override = default;
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeysInternal.getTokens",
ENTERPRISE_PLATFORMKEYSINTERNAL_GETTOKENS)
};
class EnterprisePlatformKeysChallengeMachineKeyFunction
: public ExtensionFunction {
private:
~EnterprisePlatformKeysChallengeMachineKeyFunction() override = default;
ResponseAction Run() override;
void OnChallengedKeyLacros(crosapi::mojom::ChallengeKeyResultPtr result);
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeMachineKey",
ENTERPRISE_PLATFORMKEYS_CHALLENGEMACHINEKEY)
};
class EnterprisePlatformKeysChallengeUserKeyFunction
: public LacrosNotImplementedExtensionFunction {
private:
~EnterprisePlatformKeysChallengeUserKeyFunction() override = default;
DECLARE_EXTENSION_FUNCTION("enterprise.platformKeys.challengeUserKey",
ENTERPRISE_PLATFORMKEYS_CHALLENGEUSERKEY)
};
} // namespace extensions
#endif // CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_PLATFORM_KEYS_ENTERPRISE_PLATFORM_KEYS_API_LACROS_H_
...@@ -605,6 +605,7 @@ static_library("constants") { ...@@ -605,6 +605,7 @@ static_library("constants") {
"//base", "//base",
"//base/third_party/dynamic_annotations", "//base/third_party/dynamic_annotations",
"//build:branding_buildflags", "//build:branding_buildflags",
"//build:lacros_buildflags",
"//components/bookmarks/common", "//components/bookmarks/common",
"//components/nacl/common:switches", "//components/nacl/common:switches",
"//components/offline_pages/buildflags", "//components/offline_pages/buildflags",
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
import("//build/config/chromeos/ui_mode.gni")
import("//build/config/features.gni") import("//build/config/features.gni")
import("//chrome/common/features.gni") import("//chrome/common/features.gni")
...@@ -76,6 +77,10 @@ if (is_chromeos || is_mac || is_win) { ...@@ -76,6 +77,10 @@ if (is_chromeos || is_mac || is_win) {
schema_sources_ += [ "networking_cast_private.idl" ] schema_sources_ += [ "networking_cast_private.idl" ]
} }
if (is_chromeos || chromeos_is_browser_only) {
schema_sources_ += [ "enterprise_platform_keys.idl" ]
}
if (is_chromeos) { if (is_chromeos) {
schema_sources_ += [ schema_sources_ += [
"certificate_provider.idl", "certificate_provider.idl",
...@@ -84,7 +89,6 @@ if (is_chromeos) { ...@@ -84,7 +89,6 @@ if (is_chromeos) {
"echo_private.json", "echo_private.json",
"enterprise_device_attributes.idl", "enterprise_device_attributes.idl",
"enterprise_networking_attributes.idl", "enterprise_networking_attributes.idl",
"enterprise_platform_keys.idl",
"enterprise_platform_keys_internal.idl", "enterprise_platform_keys_internal.idl",
"enterprise_platform_keys_private.json", "enterprise_platform_keys_private.json",
"file_browser_handler_internal.json", "file_browser_handler_internal.json",
......
...@@ -6,6 +6,7 @@ import("//mojo/public/tools/bindings/mojom.gni") ...@@ -6,6 +6,7 @@ import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") { mojom("mojom") {
sources = [ sources = [
"attestation.mojom",
"crosapi.mojom", "crosapi.mojom",
"screen_manager.mojom", "screen_manager.mojom",
"select_file.mojom", "select_file.mojom",
......
// Copyright 2020 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.
module crosapi.mojom;
[Extensible]
enum ChallengeKeyType {
// The challenge is attested by keys belonging to the current user.
kUser = 0,
// The challenge is attested by keys belonging to the device.
kDevice = 1,
};
union ChallengeKeyResult {
// Implies failure.
string error_message;
// Implies success.
string challenge_response;
};
// This interface is implemented by ash-chrome. It provides lacros-chrome a
// mechanism to use the system keystore to attest challenges.
interface Attestation {
// Requests that the OS keystore attest a challenge.
ChallengeKey@0(string challenge, ChallengeKeyType type) =>
(ChallengeKeyResult result);
};
...@@ -4,12 +4,16 @@ ...@@ -4,12 +4,16 @@
module crosapi.mojom; module crosapi.mojom;
import "chromeos/crosapi/mojom/attestation.mojom";
import "chromeos/crosapi/mojom/screen_manager.mojom"; import "chromeos/crosapi/mojom/screen_manager.mojom";
import "chromeos/crosapi/mojom/select_file.mojom"; import "chromeos/crosapi/mojom/select_file.mojom";
// AshChromeService defines the APIs that live in ash-chrome and are // AshChromeService defines the APIs that live in ash-chrome and are
// accessed from lacros-chrome. // accessed from lacros-chrome.
interface AshChromeService { interface AshChromeService {
// Binds the Attestation interface for challenging keys.
BindAttestation@2(pending_receiver<Attestation> receiver);
// Binds the ScreenManager interface for interacting with windows, screens and // Binds the ScreenManager interface for interacting with windows, screens and
// displays. // displays.
BindScreenManager@1(pending_receiver<ScreenManager> receiver); BindScreenManager@1(pending_receiver<ScreenManager> receiver);
......
...@@ -89,6 +89,12 @@ class LacrosChromeServiceNeverBlockingState ...@@ -89,6 +89,12 @@ class LacrosChromeServiceNeverBlockingState
ash_chrome_service_->BindScreenManager(std::move(pending_receiver)); ash_chrome_service_->BindScreenManager(std::move(pending_receiver));
} }
void BindAttestationReceiver(
mojo::PendingReceiver<crosapi::mojom::Attestation> pending_receiver) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ash_chrome_service_->BindAttestation(std::move(pending_receiver));
}
base::WeakPtr<LacrosChromeServiceNeverBlockingState> GetWeakPtr() { base::WeakPtr<LacrosChromeServiceNeverBlockingState> GetWeakPtr() {
return weak_factory_.GetWeakPtr(); return weak_factory_.GetWeakPtr();
} }
...@@ -158,6 +164,15 @@ LacrosChromeServiceImpl::LacrosChromeServiceImpl( ...@@ -158,6 +164,15 @@ LacrosChromeServiceImpl::LacrosChromeServiceImpl(
&LacrosChromeServiceNeverBlockingState::BindSelectFileReceiver, &LacrosChromeServiceNeverBlockingState::BindSelectFileReceiver,
weak_sequenced_state_, std::move(select_file_pending_receiver))); weak_sequenced_state_, std::move(select_file_pending_receiver)));
mojo::PendingReceiver<crosapi::mojom::Attestation>
attestation_pending_receiver =
attestation_remote_.BindNewPipeAndPassReceiver();
never_blocking_sequence_->PostTask(
FROM_HERE,
base::BindOnce(
&LacrosChromeServiceNeverBlockingState::BindAttestationReceiver,
weak_sequenced_state_, std::move(attestation_pending_receiver)));
DCHECK(!g_instance); DCHECK(!g_instance);
g_instance = this; g_instance = this;
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "chromeos/crosapi/mojom/attestation.mojom.h"
#include "chromeos/crosapi/mojom/crosapi.mojom.h" #include "chromeos/crosapi/mojom/crosapi.mojom.h"
#include "chromeos/crosapi/mojom/screen_manager.mojom.h" #include "chromeos/crosapi/mojom/screen_manager.mojom.h"
#include "chromeos/crosapi/mojom/select_file.mojom.h" #include "chromeos/crosapi/mojom/select_file.mojom.h"
...@@ -70,6 +71,13 @@ class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosChromeServiceImpl { ...@@ -70,6 +71,13 @@ class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosChromeServiceImpl {
return select_file_remote_; return select_file_remote_;
} }
// This must be called on the affine sequence. It exposes a remote that can
// be used to perform attestation on challenges.
mojo::Remote<crosapi::mojom::Attestation>& attestation_remote() {
DCHECK_CALLED_ON_VALID_SEQUENCE(affine_sequence_checker_);
return attestation_remote_;
}
// This may be called on any thread. // This may be called on any thread.
void BindScreenManagerReceiver( void BindScreenManagerReceiver(
mojo::PendingReceiver<crosapi::mojom::ScreenManager> pending_receiver); mojo::PendingReceiver<crosapi::mojom::ScreenManager> pending_receiver);
...@@ -91,6 +99,11 @@ class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosChromeServiceImpl { ...@@ -91,6 +99,11 @@ class COMPONENT_EXPORT(CHROMEOS_LACROS) LacrosChromeServiceImpl {
// constructor and it is immediately available for use. // constructor and it is immediately available for use.
mojo::Remote<crosapi::mojom::SelectFile> select_file_remote_; mojo::Remote<crosapi::mojom::SelectFile> select_file_remote_;
// This member allows lacros-chrome to use the Attestation interface. This
// member is affine to the affine sequence. It is initialized in the
// constructor and it is immediately available for use.
mojo::Remote<crosapi::mojom::Attestation> attestation_remote_;
// This member is instantiated on the affine sequence alongside the // This member is instantiated on the affine sequence alongside the
// constructor. All subsequent invocations of this member, including // constructor. All subsequent invocations of this member, including
// destruction, happen on the |never_blocking_sequence_|. // destruction, happen on the |never_blocking_sequence_|.
......
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