1 // Copyright 2014 The Chromium Authors. All rights reserved.
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"
10 #include "base/basictypes.h"
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/location.h"
14 #include "base/logging.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/task_runner.h"
17 #include "base/task_runner_util.h"
18 #include "base/values.h"
19 #include "components/ownership/owner_key_util.h"
20 #include "crypto/scoped_nss_types.h"
22 namespace em
= enterprise_management
;
28 using ScopedSGNContext
=
29 scoped_ptr
<SGNContext
,
30 crypto::NSSDestroyer1
<SGNContext
, SGN_DestroyContext
, PR_TRUE
>>;
32 scoped_ptr
<em::PolicyFetchResponse
> AssembleAndSignPolicy(
33 scoped_ptr
<em::PolicyData
> policy
,
34 SECKEYPrivateKey
* private_key
) {
35 // Assemble the policy.
36 scoped_ptr
<em::PolicyFetchResponse
> policy_response(
37 new em::PolicyFetchResponse());
38 if (!policy
->SerializeToString(policy_response
->mutable_policy_data())) {
39 LOG(ERROR
) << "Failed to encode policy payload.";
40 return scoped_ptr
<em::PolicyFetchResponse
>(nullptr).Pass();
43 ScopedSGNContext
sign_context(
44 SGN_NewContext(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION
, private_key
));
50 SECItem signature_item
;
51 if (SGN_Begin(sign_context
.get()) != SECSuccess
||
52 SGN_Update(sign_context
.get(),
53 reinterpret_cast<const uint8
*>(
54 policy_response
->policy_data().c_str()),
55 policy_response
->policy_data().size()) != SECSuccess
||
56 SGN_End(sign_context
.get(), &signature_item
) != SECSuccess
) {
57 LOG(ERROR
) << "Failed to create policy signature.";
61 policy_response
->mutable_policy_data_signature()->assign(
62 reinterpret_cast<const char*>(signature_item
.data
), signature_item
.len
);
63 SECITEM_FreeItem(&signature_item
, PR_FALSE
);
65 return policy_response
.Pass();
70 OwnerSettingsService::OwnerSettingsService(
71 const scoped_refptr
<ownership::OwnerKeyUtil
>& owner_key_util
)
72 : owner_key_util_(owner_key_util
), weak_factory_(this) {
75 OwnerSettingsService::~OwnerSettingsService() {
76 DCHECK(thread_checker_
.CalledOnValidThread());
79 void OwnerSettingsService::AddObserver(Observer
* observer
) {
80 if (observer
&& !observers_
.HasObserver(observer
))
81 observers_
.AddObserver(observer
);
84 void OwnerSettingsService::RemoveObserver(Observer
* observer
) {
85 observers_
.RemoveObserver(observer
);
88 bool OwnerSettingsService::IsOwner() {
89 DCHECK(thread_checker_
.CalledOnValidThread());
90 return private_key_
.get() && private_key_
->key();
93 void OwnerSettingsService::IsOwnerAsync(const IsOwnerCallback
& callback
) {
94 DCHECK(thread_checker_
.CalledOnValidThread());
95 if (private_key_
.get()) {
96 base::MessageLoop::current()->PostTask(FROM_HERE
,
97 base::Bind(callback
, IsOwner()));
99 pending_is_owner_callbacks_
.push_back(callback
);
103 bool OwnerSettingsService::AssembleAndSignPolicyAsync(
104 base::TaskRunner
* task_runner
,
105 scoped_ptr
<em::PolicyData
> policy
,
106 const AssembleAndSignPolicyAsyncCallback
& callback
) {
107 DCHECK(thread_checker_
.CalledOnValidThread());
108 if (!task_runner
|| !IsOwner())
110 return base::PostTaskAndReplyWithResult(
114 &AssembleAndSignPolicy
, base::Passed(&policy
), private_key_
->key()),
118 bool OwnerSettingsService::SetBoolean(const std::string
& setting
, bool value
) {
119 DCHECK(thread_checker_
.CalledOnValidThread());
120 base::FundamentalValue
in_value(value
);
121 return Set(setting
, in_value
);
124 bool OwnerSettingsService::SetInteger(const std::string
& setting
, int value
) {
125 DCHECK(thread_checker_
.CalledOnValidThread());
126 base::FundamentalValue
in_value(value
);
127 return Set(setting
, in_value
);
130 bool OwnerSettingsService::SetDouble(const std::string
& setting
, double value
) {
131 DCHECK(thread_checker_
.CalledOnValidThread());
132 base::FundamentalValue
in_value(value
);
133 return Set(setting
, in_value
);
136 bool OwnerSettingsService::SetString(const std::string
& setting
,
137 const std::string
& value
) {
138 DCHECK(thread_checker_
.CalledOnValidThread());
139 base::StringValue
in_value(value
);
140 return Set(setting
, in_value
);
143 void OwnerSettingsService::ReloadKeypair() {
145 base::Bind(&OwnerSettingsService::OnKeypairLoaded
, as_weak_ptr()));
148 void OwnerSettingsService::OnKeypairLoaded(
149 const scoped_refptr
<PublicKey
>& public_key
,
150 const scoped_refptr
<PrivateKey
>& private_key
) {
151 DCHECK(thread_checker_
.CalledOnValidThread());
153 public_key_
= public_key
;
154 private_key_
= private_key
;
156 const bool is_owner
= IsOwner();
157 std::vector
<IsOwnerCallback
> is_owner_callbacks
;
158 is_owner_callbacks
.swap(pending_is_owner_callbacks_
);
159 for (std::vector
<IsOwnerCallback
>::iterator
it(is_owner_callbacks
.begin());
160 it
!= is_owner_callbacks
.end();
165 OnPostKeypairLoadedActions();
168 } // namespace ownership