Commit 59fd7055 authored by Omar Morsi's avatar Omar Morsi Committed by Commit Bot

KeyPermissionsService: Remove IsCorporateKeyForProfile

This CL removes the static function
KeyPermissionsService::IsCorporateKeyForProfile because it does not
account for device-wide keys which are currently always "corporate".
KeyPermissionsService::IsCorporateKey can be used instead.

Bug: 1127326
Change-Id: I927611abe296f710c6b7d2187cd1c6c6b5ae47e4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2426607
Commit-Queue: Omar Morsi <omorsi@google.com>
Reviewed-by: default avatarPavol Marko <pmarko@chromium.org>
Reviewed-by: default avatarEdman Anjos <edman@chromium.org>
Cr-Commit-Position: refs/heads/master@{#811210}
parent 5f96842c
......@@ -6,15 +6,22 @@
#include <cert.h>
#include <string>
#include <utility>
#include <vector>
#include "base/base64.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_forward.h"
#include "base/containers/queue.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_factory.h"
#include "chrome/browser/chromeos/platform_keys/key_permissions/key_permissions_service_impl.h"
#include "chrome/browser/chromeos/platform_keys/platform_keys.h"
#include "chrome/browser/chromeos/platform_keys/platform_keys_service.h"
#include "chrome/browser/chromeos/platform_keys/platform_keys_service_factory.h"
#include "chrome/browser/net/nss_context.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/profile.h"
......@@ -24,6 +31,8 @@
#include "components/arc/session/arc_bridge_service.h"
#include "components/policy/core/common/policy_namespace.h"
#include "components/policy/policy_constants.h"
#include "content/public/browser/browser_context.h"
#include "net/cert/scoped_nss_types.h"
#include "net/cert/x509_certificate.h"
#include "net/cert/x509_util_nss.h"
......@@ -72,22 +81,53 @@ scoped_refptr<net::X509Certificate> FindCertificateByAlias(
return x509_cert;
}
// Returns true if the certificate is allowed to be used by ARC. |cert| must be
// non-null.
// WARNING: Doesn't check the certificate slot, relies only on pref.
bool IsCertificateAllowed(const scoped_refptr<net::X509Certificate>& cert,
const PrefService* prefs) {
DCHECK(cert);
using IsCertificateAllowedCallback = base::OnceCallback<void(bool allowed)>;
void CheckKeyLocationAndCorporateFlag(
IsCertificateAllowedCallback callback,
const std::string& public_key_spki_der,
content::BrowserContext* const context,
base::Optional<bool> key_on_user_token,
chromeos::platform_keys::Status is_key_on_token_status) {
if (is_key_on_token_status != chromeos::platform_keys::Status::kSuccess) {
LOG(WARNING) << "Error while checking key location: "
<< chromeos::platform_keys::StatusToString(
is_key_on_token_status);
std::move(callback).Run(/*allowed=*/false);
return;
}
std::string spki_der = chromeos::platform_keys::GetSubjectPublicKeyInfo(cert);
std::string public_key_spki_der_b64;
base::Base64Encode(spki_der, &public_key_spki_der_b64);
if (!chromeos::platform_keys::KeyPermissionsServiceImpl::
IsCorporateKeyForProfile(public_key_spki_der_b64, prefs)) {
DVLOG(1) << "Certificate is not allowed to be used by ARC.";
return false;
DCHECK(key_on_user_token.has_value());
if (!key_on_user_token.value_or(false)) {
std::move(callback).Run(/*allowed=*/false);
return;
}
return true;
// Check if the key is marked for corporate usage.
chromeos::platform_keys::KeyPermissionsServiceFactory::GetForBrowserContext(
context)
->IsCorporateKey(public_key_spki_der, std::move(callback));
}
// Returns true if the certificate is allowed to be used by ARC. The certificate
// is allowed to be used by ARC if its key is marked for corporate usage and
// resides on a user token. |cert| must be non-null.
void IsCertificateAllowed(IsCertificateAllowedCallback callback,
scoped_refptr<net::X509Certificate> cert,
content::BrowserContext* const context) {
DCHECK(cert);
const std::string public_key_spki_der =
chromeos::platform_keys::GetSubjectPublicKeyInfo(cert);
// Check if the key is on the user token.
chromeos::platform_keys::PlatformKeysServiceFactory::GetForBrowserContext(
context)
->IsKeyOnToken(
chromeos::platform_keys::TokenId::kUser, public_key_spki_der,
base::BindOnce(&CheckKeyLocationAndCorporateFlag, std::move(callback),
public_key_spki_der, context));
}
} // namespace
......@@ -165,8 +205,7 @@ void ArcCertStoreBridge::GetKeyCharacteristics(
}
scoped_refptr<net::X509Certificate> cert = FindCertificateByAlias(alias);
if (!cert || !IsCertificateAllowed(
cert, Profile::FromBrowserContext(context_)->GetPrefs())) {
if (!cert) {
std::move(callback).Run(mojom::KeymasterError::ERROR_INVALID_KEY_BLOB,
base::nullopt);
return;
......@@ -188,8 +227,8 @@ void ArcCertStoreBridge::Begin(const std::string& alias,
}
scoped_refptr<net::X509Certificate> cert = FindCertificateByAlias(alias);
if (!cert || !IsCertificateAllowed(
cert, Profile::FromBrowserContext(context_)->GetPrefs())) {
if (!cert) {
std::move(callback).Run(mojom::KeymasterError::ERROR_INVALID_KEY_BLOB, 0);
return;
}
......@@ -280,24 +319,82 @@ void ArcCertStoreBridge::OnGetNSSCertDatabaseForProfile(
void ArcCertStoreBridge::OnCertificatesListed(
ListCertificatesCallback callback,
net::ScopedCERTCertificateList cert_list) {
std::vector<mojom::CertificatePtr> permitted_certs;
for (const auto& cert : cert_list) {
base::queue<net::ScopedCERTCertificate> cert_queue;
for (auto& cert : cert_list) {
cert_queue.push(std::move(cert));
}
net::ScopedCERTCertificateList allowed_certs;
FilterAllowedCertificatesRecursively(
base::BindOnce(&ArcCertStoreBridge::OnFilteredAllowedCertificates,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)),
std::move(cert_queue), std::move(allowed_certs));
}
void ArcCertStoreBridge::FilterAllowedCertificatesRecursively(
FilterAllowedCertificatesCallback callback,
base::queue<net::ScopedCERTCertificate> cert_queue,
net::ScopedCERTCertificateList allowed_certs) const {
if (cert_queue.empty()) {
std::move(callback).Run(std::move(allowed_certs));
return;
}
net::ScopedCERTCertificate cert = std::move(cert_queue.front());
cert_queue.pop();
scoped_refptr<net::X509Certificate> x509_cert =
net::x509_util::CreateX509CertificateFromCERTCertificate(cert.get());
if (!x509_cert) {
FilterAllowedCertificatesRecursively(
std::move(callback), std::move(cert_queue), std::move(allowed_certs));
return;
}
IsCertificateAllowed(
base::BindOnce(&ArcCertStoreBridge::FilterAllowedCertificateAndRecurse,
weak_ptr_factory_.GetWeakPtr(), std::move(callback),
std::move(cert_queue), std::move(allowed_certs),
std::move(cert)),
std::move(x509_cert), context_);
}
void ArcCertStoreBridge::FilterAllowedCertificateAndRecurse(
FilterAllowedCertificatesCallback callback,
base::queue<net::ScopedCERTCertificate> cert_queue,
net::ScopedCERTCertificateList allowed_certs,
net::ScopedCERTCertificate cert,
bool certificate_allowed) const {
if (certificate_allowed) {
allowed_certs.push_back(std::move(cert));
}
FilterAllowedCertificatesRecursively(
std::move(callback), std::move(cert_queue), std::move(allowed_certs));
}
void ArcCertStoreBridge::OnFilteredAllowedCertificates(
ListCertificatesCallback callback,
net::ScopedCERTCertificateList allowed_certs) {
std::vector<mojom::CertificatePtr> certificate_ptr_list;
for (const auto& cert : allowed_certs) {
mojom::CertificatePtr certificate = mojom::Certificate::New();
certificate->alias = cert->nickname;
scoped_refptr<net::X509Certificate> x509_cert =
net::x509_util::CreateX509CertificateFromCERTCertificate(cert.get());
if (!x509_cert) {
DVLOG(1) << "x509_util::CreateX509CertificateFromCERTCertificate failed";
continue;
}
if (IsCertificateAllowed(
x509_cert, Profile::FromBrowserContext(context_)->GetPrefs())) {
mojom::CertificatePtr certificate = mojom::Certificate::New();
certificate->alias = cert->nickname;
net::X509Certificate::GetPEMEncoded(x509_cert->cert_buffer(),
&certificate->cert);
permitted_certs.emplace_back(std::move(certificate));
}
net::X509Certificate::GetPEMEncoded(x509_cert->cert_buffer(),
&certificate->cert);
certificate_ptr_list.emplace_back(std::move(certificate));
}
std::move(callback).Run(std::move(permitted_certs));
std::move(callback).Run(std::move(certificate_ptr_list));
}
void ArcCertStoreBridge::UpdateFromKeyPermissionsPolicy() {
......
......@@ -8,7 +8,10 @@
#include <string>
#include <vector>
#include "base/callback_forward.h"
#include "base/containers/queue.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/chromeos/platform_keys/platform_keys.h"
#include "components/arc/mojom/cert_store.mojom.h"
#include "components/arc/session/arc_bridge_service.h"
#include "components/arc/session/connection_observer.h"
......@@ -73,6 +76,26 @@ class ArcCertStoreBridge
net::NSSCertDatabase* database);
void OnCertificatesListed(ListCertificatesCallback callback,
net::ScopedCERTCertificateList cert_list);
using FilterAllowedCertificatesCallback =
base::OnceCallback<void(net::ScopedCERTCertificateList allowed_certs)>;
void FilterAllowedCertificatesRecursively(
FilterAllowedCertificatesCallback callback,
base::queue<net::ScopedCERTCertificate> cert_queue,
net::ScopedCERTCertificateList allowed_certs) const;
void FilterAllowedCertificateAndRecurse(
FilterAllowedCertificatesCallback callback,
base::queue<net::ScopedCERTCertificate> cert_queue,
net::ScopedCERTCertificateList allowed_certs,
net::ScopedCERTCertificate cert,
bool certificate_allowed) const;
void OnFilteredAllowedCertificates(
ListCertificatesCallback callback,
net::ScopedCERTCertificateList allowed_certs);
void UpdateFromKeyPermissionsPolicy();
void UpdateCertificates();
......
......@@ -28,6 +28,8 @@
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "extensions/browser/state_store.h"
#include "net/cert/scoped_nss_types.h"
#include "net/cert/x509_util_nss.h"
namespace chromeos {
namespace platform_keys {
......@@ -611,7 +613,6 @@ void KeyPermissionsServiceImpl::IsCorporateKeyWithLocations(
if (status != Status::kSuccess) {
LOG(ERROR) << "Key locations retrieval failed: " << StatusToString(status);
std::move(callback).Run(/*corporate=*/false);
return;
}
std::string public_key_spki_der_b64;
......@@ -620,7 +621,7 @@ void KeyPermissionsServiceImpl::IsCorporateKeyWithLocations(
for (const auto key_location : key_locations) {
switch (key_location) {
case TokenId::kUser:
if (IsCorporateKeyForProfile(public_key_spki_der_b64, profile_prefs_)) {
if (IsUserKeyCorporate(public_key_spki_der_b64)) {
std::move(callback).Run(/*corporate=*/true);
return;
}
......@@ -687,21 +688,6 @@ void KeyPermissionsServiceImpl::SetCorporateKeyWithLocations(
}
}
// static
bool KeyPermissionsServiceImpl::IsCorporateKeyForProfile(
const std::string& public_key_spki_der_b64,
const PrefService* const profile_prefs) {
const base::DictionaryValue* prefs_entry =
GetPrefsEntry(public_key_spki_der_b64, profile_prefs);
if (prefs_entry) {
const base::Value* key_usage = prefs_entry->FindKey(kPrefKeyUsage);
if (!key_usage || !key_usage->is_string())
return false;
return key_usage->GetString() == kPrefKeyUsageCorporate;
}
return false;
}
// static
std::vector<std::string>
KeyPermissionsServiceImpl::GetCorporateKeyUsageAllowedAppIds(
......@@ -742,5 +728,18 @@ void KeyPermissionsServiceImpl::SetPlatformKeysOfExtension(
extension_id, kStateStorePlatformKeys, std::move(value));
}
bool KeyPermissionsServiceImpl::IsUserKeyCorporate(
const std::string& public_key_spki_der_b64) const {
const base::DictionaryValue* prefs_entry =
GetPrefsEntry(public_key_spki_der_b64, profile_prefs_);
if (prefs_entry) {
const base::Value* key_usage = prefs_entry->FindKey(kPrefKeyUsage);
if (!key_usage || !key_usage->is_string())
return false;
return key_usage->GetString() == kPrefKeyUsageCorporate;
}
return false;
}
} // namespace platform_keys
} // namespace chromeos
......@@ -169,13 +169,6 @@ class KeyPermissionsServiceImpl : public KeyPermissionsService {
void SetCorporateKey(const std::string& public_key_spki_der,
SetCorporateKeyCallback callback) const override;
// Returns true if |public_key_spki_der_b64| is a corporate usage key.
// TOOD(http://crbug.com/1127284): Remove this and migrate callers to
// IsCorporateKey().
static bool IsCorporateKeyForProfile(
const std::string& public_key_spki_der_b64,
const PrefService* const profile_prefs);
// Returns the list of apps and extensions ids allowed to use corporate usage
// keys by policy in |profile_policies|.
static std::vector<std::string> GetCorporateKeyUsageAllowedAppIds(
......@@ -193,6 +186,10 @@ class KeyPermissionsServiceImpl : public KeyPermissionsService {
void SetPlatformKeysOfExtension(const std::string& extension_id,
std::unique_ptr<base::Value> value);
// Returns true if |public_key_spki_der_b64| (which is located only on a user
// token) is marked for corporate usage.
bool IsUserKeyCorporate(const std::string& public_key_spki_der_b64) const;
void CanUserGrantPermissionForKeyWithLocations(
const std::string& public_key_spki_der,
CanUserGrantPermissionForKeyCallback callback,
......
......@@ -137,6 +137,13 @@ class MockPlatformKeysService : public PlatformKeysService {
GetAttributeForKeyCallback callback),
(override));
MOCK_METHOD(void,
IsKeyOnToken,
(TokenId token_id,
const std::string& public_key_spki_der,
IsKeyOnTokenCallback callback),
(override));
MOCK_METHOD(void,
SetMapToSoftokenAttrsForTesting,
(bool map_to_softoken_attrs_for_testing),
......
......@@ -90,6 +90,12 @@ using GetAttributeForKeyCallback =
base::OnceCallback<void(const base::Optional<std::string>& attribute_value,
Status status)>;
// If the availability of the key on the provided token has been successfully
// determined, |on_token| will contain the result. If an error occurs,
// |on_token| will be empty and an error |status| will be returned.
using IsKeyOnTokenCallback =
base::OnceCallback<void(base::Optional<bool> on_token, Status status)>;
// An observer that gets notified when the PlatformKeysService is being shut
// down.
class PlatformKeysServiceObserver : public base::CheckedObserver {
......@@ -250,6 +256,13 @@ class PlatformKeysService : public KeyedService {
KeyAttributeType attribute_type,
GetAttributeForKeyCallback callback) = 0;
// Determines if |public_key_spki_der| resides on |token_id|. |callback| will
// be invoked on the UI thread with the result. If an error occurred, an error
// |status| will be returned and base::nullopt |on_token| will be returned.
virtual void IsKeyOnToken(TokenId token_id,
const std::string& public_key_spki_der,
IsKeyOnTokenCallback callback) = 0;
// Softoken NSS PKCS11 module (used for testing) allows only predefined key
// attributes to be set and retrieved. Chaps supports setting and retrieving
// custom attributes.
......@@ -358,6 +371,9 @@ class PlatformKeysServiceImpl final : public PlatformKeysService {
const std::string& public_key_spki_der,
KeyAttributeType attribute_type,
GetAttributeForKeyCallback callback) override;
void IsKeyOnToken(TokenId token_id,
const std::string& public_key_spki_der,
IsKeyOnTokenCallback callback) override;
void SetMapToSoftokenAttrsForTesting(
bool map_to_softoken_attrs_for_testing) override;
bool IsSetMapToSoftokenAttrsForTesting();
......
......@@ -272,6 +272,18 @@ class GetAllKeysExecutionWaiter
return std::get<0>(result_callback_args());
}
};
class IsKeyOnTokenExecutionWaiter
: public ExecutionWaiter<base::Optional<bool>> {
public:
IsKeyOnTokenExecutionWaiter() = default;
~IsKeyOnTokenExecutionWaiter() = default;
base::Optional<bool> on_slot() const {
return std::get<0>(result_callback_args());
}
};
} // namespace
class PlatformKeysServiceBrowserTestBase
......@@ -526,6 +538,28 @@ IN_PROC_BROWSER_TEST_P(PlatformKeysServicePerProfileBrowserTest,
}
}
IN_PROC_BROWSER_TEST_P(PlatformKeysServicePerProfileBrowserTest,
IsKeyOnTokenWhenNot) {
// More than one available token are needed to test this.
if (GetParam().token_ids.size() < 2) {
return;
}
const TokenId token_id_1 = GetParam().token_ids[0];
const TokenId token_id_2 = GetParam().token_ids[1];
const std::string public_key = GenerateKeyPair(token_id_1);
IsKeyOnTokenExecutionWaiter is_key_on_token_waiter;
platform_keys_service()->IsKeyOnToken(token_id_2, public_key,
is_key_on_token_waiter.GetCallback());
is_key_on_token_waiter.Wait();
EXPECT_EQ(is_key_on_token_waiter.status(), Status::kSuccess);
ASSERT_TRUE(is_key_on_token_waiter.on_slot().has_value());
EXPECT_FALSE(is_key_on_token_waiter.on_slot().value());
}
INSTANTIATE_TEST_SUITE_P(
AllSupportedProfileTypes,
PlatformKeysServicePerProfileBrowserTest,
......@@ -534,7 +568,9 @@ INSTANTIATE_TEST_SUITE_P(
TestConfigPerProfile{ProfileToUse::kUnaffiliatedUserProfile,
{TokenId::kUser}},
TestConfigPerProfile{ProfileToUse::kAffiliatedUserProfile,
{TokenId::kUser, TokenId::kSystem}}));
{TokenId::kUser, TokenId::kSystem}},
TestConfigPerProfile{ProfileToUse::kAffiliatedUserProfile,
{TokenId::kSystem, TokenId::kUser}}));
class PlatformKeysServicePerTokenBrowserTest
: public PlatformKeysServiceBrowserTestBase,
......@@ -748,6 +784,34 @@ IN_PROC_BROWSER_TEST_P(PlatformKeysServicePerTokenBrowserTest,
EXPECT_TRUE(public_keys.empty());
}
IN_PROC_BROWSER_TEST_P(PlatformKeysServicePerTokenBrowserTest, IsKeyOnToken) {
const TokenId token_id = GetParam().token_id;
const std::string public_key = GenerateKeyPair(token_id);
IsKeyOnTokenExecutionWaiter is_key_on_token_waiter;
platform_keys_service()->IsKeyOnToken(token_id, public_key,
is_key_on_token_waiter.GetCallback());
is_key_on_token_waiter.Wait();
EXPECT_EQ(is_key_on_token_waiter.status(), Status::kSuccess);
ASSERT_TRUE(is_key_on_token_waiter.on_slot().has_value());
EXPECT_TRUE(is_key_on_token_waiter.on_slot().value());
}
IN_PROC_BROWSER_TEST_P(PlatformKeysServicePerTokenBrowserTest,
IsKeyOnTokenWhenNoKeysGenerated) {
const TokenId token_id = GetParam().token_id;
IsKeyOnTokenExecutionWaiter is_key_on_token_waiter;
platform_keys_service()->IsKeyOnToken(token_id, "test_public_key",
is_key_on_token_waiter.GetCallback());
is_key_on_token_waiter.Wait();
EXPECT_EQ(is_key_on_token_waiter.status(), Status::kSuccess);
ASSERT_TRUE(is_key_on_token_waiter.on_slot().has_value());
EXPECT_FALSE(is_key_on_token_waiter.on_slot().value());
}
INSTANTIATE_TEST_SUITE_P(
AllSupportedProfilesAndTokensTypes,
PlatformKeysServicePerTokenBrowserTest,
......@@ -781,6 +845,19 @@ IN_PROC_BROWSER_TEST_P(PlatformKeysServicePerUnavailableTokenBrowserTest,
EXPECT_NE(generate_key_waiter.status(), Status::kSuccess);
}
IN_PROC_BROWSER_TEST_P(PlatformKeysServicePerUnavailableTokenBrowserTest,
IsKeyOnToken) {
const TokenId token_id = GetParam().token_id;
IsKeyOnTokenExecutionWaiter is_key_on_token_waiter;
platform_keys_service()->IsKeyOnToken(token_id, "test_public_key",
is_key_on_token_waiter.GetCallback());
is_key_on_token_waiter.Wait();
EXPECT_NE(is_key_on_token_waiter.status(), Status::kSuccess);
EXPECT_FALSE(is_key_on_token_waiter.on_slot().has_value());
}
INSTANTIATE_TEST_SUITE_P(
AllSupportedProfilesAndTokensTypes,
PlatformKeysServicePerUnavailableTokenBrowserTest,
......
......@@ -623,6 +623,39 @@ class GetAttributeForKeyState : public NSSOperationState {
GetAttributeForKeyCallback callback_;
};
class IsKeyOnTokenState : public NSSOperationState {
public:
IsKeyOnTokenState(ServiceWeakPtr weak_ptr,
const std::string& public_key_spki_der,
IsKeyOnTokenCallback callback);
~IsKeyOnTokenState() override = default;
void OnError(const base::Location& from, Status status) override {
CallBack(from, /*on_token=*/base::nullopt, status);
}
void OnSuccess(const base::Location& from, bool on_token) {
CallBack(from, on_token, Status::kSuccess);
}
// Must be a DER encoding of a SubjectPublicKeyInfo.
const std::string public_key_spki_der_;
private:
void CallBack(const base::Location& from,
base::Optional<bool> on_token,
Status status) {
auto bound_callback =
base::BindOnce(std::move(callback_), on_token, status);
origin_task_runner_->PostTask(
from, base::BindOnce(&NSSOperationState::RunCallback,
std::move(bound_callback), service_weak_ptr_));
}
// Must be called on origin thread, therefore use CallBack().
IsKeyOnTokenCallback callback_;
};
NSSOperationState::NSSOperationState(ServiceWeakPtr weak_ptr)
: service_weak_ptr_(weak_ptr),
origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) {}
......@@ -729,6 +762,13 @@ GetAttributeForKeyState::GetAttributeForKeyState(
attribute_type_(attribute_type),
callback_(std::move(callback)) {}
IsKeyOnTokenState::IsKeyOnTokenState(ServiceWeakPtr weak_ptr,
const std::string& public_key_spki_der,
IsKeyOnTokenCallback callback)
: NSSOperationState(weak_ptr),
public_key_spki_der_(public_key_spki_der),
callback_(std::move(callback)) {}
// Returns the private key corresponding to the der-encoded
// |public_key_spki_der| if found in |slot|. If |slot| is nullptr, the
// private key will be searched in all slots.
......@@ -1418,6 +1458,16 @@ void GetAttributeForKeyWithDb(std::unique_ptr<GetAttributeForKeyState> state,
state->OnSuccess(FROM_HERE, attribute_value_str);
}
void IsKeyOnTokenWithDb(std::unique_ptr<IsKeyOnTokenState> state,
net::NSSCertDatabase* cert_db) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
DCHECK(state->slot_.get());
bool key_on_slot =
GetPrivateKey(state->public_key_spki_der_, state->slot_.get()) != nullptr;
state->OnSuccess(FROM_HERE, key_on_slot);
}
} // namespace
void PlatformKeysServiceImpl::GenerateRSAKey(TokenId token_id,
......@@ -1882,6 +1932,29 @@ void PlatformKeysServiceImpl::GetAttributeForKey(
delegate_.get(), state_ptr);
}
void PlatformKeysServiceImpl::IsKeyOnToken(
TokenId token_id,
const std::string& public_key_spki_der,
IsKeyOnTokenCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto state = std::make_unique<IsKeyOnTokenState>(
weak_factory_.GetWeakPtr(), public_key_spki_der, std::move(callback));
if (delegate_->IsShutDown()) {
state->OnError(FROM_HERE, Status::kErrorShutDown);
return;
}
// Get the pointer to |state| before base::Passed releases |state|.
NSSOperationState* state_ptr = state.get();
// The NSSCertDatabase object is not required. Only setting the state slot is
// required.
GetCertDatabase(token_id,
base::BindOnce(&IsKeyOnTokenWithDb, base::Passed(&state)),
delegate_.get(), state_ptr);
}
void PlatformKeysServiceImpl::SetMapToSoftokenAttrsForTesting(
bool map_to_softoken_attrs_for_testing) {
map_to_softoken_attrs_for_testing_ = map_to_softoken_attrs_for_testing;
......
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