[M120 Migration][VD] Enable direct rendering for TVPlus
[platform/framework/web/chromium-efl.git] / components / ownership / owner_settings_service.cc
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.
4
5 #include "components/ownership/owner_settings_service.h"
6
7 #include <cryptohi.h>
8 #include <keyhi.h>
9 #include <stdint.h>
10
11 #include <utility>
12
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"
23
24 namespace em = enterprise_management;
25
26 namespace ownership {
27
28 namespace {
29
30 using ScopedSGNContext = std::unique_ptr<
31     SGNContext,
32     crypto::NSSDestroyer1<SGNContext, SGN_DestroyContext, PR_TRUE>>;
33
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
37 // |public_key|).
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());
43
44   // Assemble the policy.
45   std::unique_ptr<em::PolicyFetchResponse> policy_response(
46       new em::PolicyFetchResponse());
47
48   if (base::FeatureList::IsEnabled(ownership::kChromeSideOwnerKeyGeneration)) {
49     policy_response->set_new_public_key(public_key->data().data(),
50                                         public_key->data().size());
51   }
52
53   if (!policy->SerializeToString(policy_response->mutable_policy_data())) {
54     LOG(ERROR) << "Failed to encode policy payload.";
55     return nullptr;
56   }
57
58   ScopedSGNContext sign_context(SGN_NewContext(
59       SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, private_key->key()));
60   if (!sign_context) {
61     NOTREACHED();
62     return nullptr;
63   }
64
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.";
73     return nullptr;
74   }
75
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);
79
80   return policy_response;
81 }
82
83 }  // namespace
84
85 BASE_FEATURE(kChromeSideOwnerKeyGeneration,
86              "ChromeSideOwnerKeyGeneration",
87              base::FeatureState::FEATURE_ENABLED_BY_DEFAULT);
88
89 OwnerSettingsService::OwnerSettingsService(
90     const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util)
91     : owner_key_util_(owner_key_util) {}
92
93 OwnerSettingsService::~OwnerSettingsService() {
94   DCHECK(thread_checker_.CalledOnValidThread());
95 }
96
97 void OwnerSettingsService::AddObserver(Observer* observer) {
98   if (observer && !observers_.HasObserver(observer))
99     observers_.AddObserver(observer);
100 }
101
102 void OwnerSettingsService::RemoveObserver(Observer* observer) {
103   observers_.RemoveObserver(observer);
104 }
105
106 bool OwnerSettingsService::IsReady() {
107   DCHECK(thread_checker_.CalledOnValidThread());
108   return private_key_.get();
109 }
110
111 bool OwnerSettingsService::IsOwner() {
112   DCHECK(thread_checker_.CalledOnValidThread());
113   return private_key_.get() && private_key_->key();
114 }
115
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()));
121   } else {
122     pending_is_owner_callbacks_.push_back(std::move(callback));
123   }
124 }
125
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())
132     return false;
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(
139       FROM_HERE,
140       base::BindOnce(&AssembleAndSignPolicy, std::move(policy), public_key_,
141                      private_key_),
142       base::BindOnce(std::move(callback), public_key_));
143 }
144
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);
149 }
150
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);
155 }
156
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);
161 }
162
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);
168 }
169
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);
175 }
176
177 void OwnerSettingsService::ReloadKeypair() {
178   ReloadKeypairImpl(
179       base::BindOnce(&OwnerSettingsService::OnKeypairLoaded, as_weak_ptr()));
180 }
181
182 void OwnerSettingsService::OnKeypairLoaded(
183     scoped_refptr<PublicKey> public_key,
184     scoped_refptr<PrivateKey> private_key) {
185   DCHECK(thread_checker_.CalledOnValidThread());
186
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.
190   public_key_ =
191       public_key ? public_key
192                  : base::MakeRefCounted<ownership::PublicKey>(
193                        /*is_persisted=*/false, /*data=*/std::vector<uint8_t>());
194   private_key_ = private_key
195                      ? private_key
196                      : base::MakeRefCounted<ownership::PrivateKey>(nullptr);
197
198   std::vector<IsOwnerCallback> is_owner_callbacks;
199   is_owner_callbacks.swap(pending_is_owner_callbacks_);
200
201   const bool is_owner = IsOwner();
202   for (auto& callback : is_owner_callbacks)
203     std::move(callback).Run(is_owner);
204
205   OnPostKeypairLoadedActions();
206 }
207
208 }  // namespace ownership