1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/ownership/owner_settings_service.h"
13 #include "base/feature_list.h"
14 #include "base/functional/bind.h"
15 #include "base/functional/callback.h"
16 #include "base/location.h"
17 #include "base/logging.h"
18 #include "base/task/single_thread_task_runner.h"
19 #include "base/task/task_runner.h"
20 #include "base/values.h"
21 #include "components/ownership/owner_key_util.h"
22 #include "crypto/scoped_nss_types.h"
24 namespace em = enterprise_management;
30 using ScopedSGNContext = std::unique_ptr<
32 crypto::NSSDestroyer1<SGNContext, SGN_DestroyContext, PR_TRUE>>;
34 // |public_key| is included in the |policy|
35 // if the ChromeSideOwnerKeyGeneration Feature is enabled. |private_key|
36 // actually signs the |policy| (must belong to the same key pair as
38 std::unique_ptr<em::PolicyFetchResponse> AssembleAndSignPolicy(
39 std::unique_ptr<em::PolicyData> policy,
40 scoped_refptr<ownership::PublicKey> public_key,
41 scoped_refptr<ownership::PrivateKey> private_key) {
42 DCHECK(private_key->key());
44 // Assemble the policy.
45 std::unique_ptr<em::PolicyFetchResponse> policy_response(
46 new em::PolicyFetchResponse());
48 if (base::FeatureList::IsEnabled(ownership::kChromeSideOwnerKeyGeneration)) {
49 policy_response->set_new_public_key(public_key->data().data(),
50 public_key->data().size());
53 if (!policy->SerializeToString(policy_response->mutable_policy_data())) {
54 LOG(ERROR) << "Failed to encode policy payload.";
58 ScopedSGNContext sign_context(SGN_NewContext(
59 SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, private_key->key()));
65 SECItem signature_item;
66 if (SGN_Begin(sign_context.get()) != SECSuccess ||
67 SGN_Update(sign_context.get(),
68 reinterpret_cast<const uint8_t*>(
69 policy_response->policy_data().c_str()),
70 policy_response->policy_data().size()) != SECSuccess ||
71 SGN_End(sign_context.get(), &signature_item) != SECSuccess) {
72 LOG(ERROR) << "Failed to create policy signature.";
76 policy_response->mutable_policy_data_signature()->assign(
77 reinterpret_cast<const char*>(signature_item.data), signature_item.len);
78 SECITEM_FreeItem(&signature_item, PR_FALSE);
80 return policy_response;
85 BASE_FEATURE(kChromeSideOwnerKeyGeneration,
86 "ChromeSideOwnerKeyGeneration",
87 base::FeatureState::FEATURE_ENABLED_BY_DEFAULT);
89 OwnerSettingsService::OwnerSettingsService(
90 const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util)
91 : owner_key_util_(owner_key_util) {}
93 OwnerSettingsService::~OwnerSettingsService() {
94 DCHECK(thread_checker_.CalledOnValidThread());
97 void OwnerSettingsService::AddObserver(Observer* observer) {
98 if (observer && !observers_.HasObserver(observer))
99 observers_.AddObserver(observer);
102 void OwnerSettingsService::RemoveObserver(Observer* observer) {
103 observers_.RemoveObserver(observer);
106 bool OwnerSettingsService::IsReady() {
107 DCHECK(thread_checker_.CalledOnValidThread());
108 return private_key_.get();
111 bool OwnerSettingsService::IsOwner() {
112 DCHECK(thread_checker_.CalledOnValidThread());
113 return private_key_.get() && private_key_->key();
116 void OwnerSettingsService::IsOwnerAsync(IsOwnerCallback callback) {
117 DCHECK(thread_checker_.CalledOnValidThread());
118 if (private_key_.get()) {
119 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
120 FROM_HERE, base::BindOnce(std::move(callback), IsOwner()));
122 pending_is_owner_callbacks_.push_back(std::move(callback));
126 bool OwnerSettingsService::AssembleAndSignPolicyAsync(
127 base::TaskRunner* task_runner,
128 std::unique_ptr<em::PolicyData> policy,
129 AssembleAndSignPolicyAsyncCallback callback) {
130 DCHECK(thread_checker_.CalledOnValidThread());
131 if (!task_runner || !IsOwner())
133 // |public_key_| is explicitly forwarded down to
134 // |OwnerSettingsServiceAsh::OnSignedPolicyStored()| to make sure that only
135 // the key that was actually included in a policy gets marked as persisted
136 // (theoretically a different key can be re-assigned to |public_key_| in
137 // between the async calls).
138 return task_runner->PostTaskAndReplyWithResult(
140 base::BindOnce(&AssembleAndSignPolicy, std::move(policy), public_key_,
142 base::BindOnce(std::move(callback), public_key_));
145 bool OwnerSettingsService::SetBoolean(const std::string& setting, bool value) {
146 DCHECK(thread_checker_.CalledOnValidThread());
147 base::Value in_value(value);
148 return Set(setting, in_value);
151 bool OwnerSettingsService::SetInteger(const std::string& setting, int value) {
152 DCHECK(thread_checker_.CalledOnValidThread());
153 base::Value in_value(value);
154 return Set(setting, in_value);
157 bool OwnerSettingsService::SetDouble(const std::string& setting, double value) {
158 DCHECK(thread_checker_.CalledOnValidThread());
159 base::Value in_value(value);
160 return Set(setting, in_value);
163 void OwnerSettingsService::RunPendingIsOwnerCallbacksForTesting(bool is_owner) {
164 std::vector<IsOwnerCallback> is_owner_callbacks;
165 is_owner_callbacks.swap(pending_is_owner_callbacks_);
166 for (auto& callback : is_owner_callbacks)
167 std::move(callback).Run(is_owner);
170 bool OwnerSettingsService::SetString(const std::string& setting,
171 const std::string& value) {
172 DCHECK(thread_checker_.CalledOnValidThread());
173 base::Value in_value(value);
174 return Set(setting, in_value);
177 void OwnerSettingsService::ReloadKeypair() {
179 base::BindOnce(&OwnerSettingsService::OnKeypairLoaded, as_weak_ptr()));
182 void OwnerSettingsService::OnKeypairLoaded(
183 scoped_refptr<PublicKey> public_key,
184 scoped_refptr<PrivateKey> private_key) {
185 DCHECK(thread_checker_.CalledOnValidThread());
187 // The pointers themself should not be null to indicate that the keys finished
188 // loading (even if unsuccessfully). Absence of the actual data inside can
189 // indicate that the keys are unavailable.
191 public_key ? public_key
192 : base::MakeRefCounted<ownership::PublicKey>(
193 /*is_persisted=*/false, /*data=*/std::vector<uint8_t>());
194 private_key_ = private_key
196 : base::MakeRefCounted<ownership::PrivateKey>(nullptr);
198 std::vector<IsOwnerCallback> is_owner_callbacks;
199 is_owner_callbacks.swap(pending_is_owner_callbacks_);
201 const bool is_owner = IsOwner();
202 for (auto& callback : is_owner_callbacks)
203 std::move(callback).Run(is_owner);
205 OnPostKeypairLoadedActions();
208 } // namespace ownership