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.
4
5#include "components/ownership/owner_settings_service.h"
6
7#include "base/basictypes.h"
8#include "base/bind.h"
9#include "base/callback.h"
10#include "base/location.h"
11#include "base/logging.h"
12#include "base/message_loop/message_loop.h"
13#include "base/task_runner.h"
14#include "base/task_runner_util.h"
15#include "components/ownership/owner_key_util.h"
16#include "crypto/signature_creator.h"
17
18namespace em = enterprise_management;
19
20namespace ownership {
21
22namespace {
23
24std::string AssembleAndSignPolicy(scoped_ptr<em::PolicyData> policy,
25                                  crypto::RSAPrivateKey* private_key) {
26  // Assemble the policy.
27  em::PolicyFetchResponse policy_response;
28  if (!policy->SerializeToString(policy_response.mutable_policy_data())) {
29    LOG(ERROR) << "Failed to encode policy payload.";
30    return std::string();
31  }
32
33  // Generate the signature.
34  scoped_ptr<crypto::SignatureCreator> signature_creator(
35      crypto::SignatureCreator::Create(private_key,
36                                       crypto::SignatureCreator::SHA1));
37  signature_creator->Update(
38      reinterpret_cast<const uint8*>(policy_response.policy_data().c_str()),
39      policy_response.policy_data().size());
40  std::vector<uint8> signature_bytes;
41  std::string policy_blob;
42  if (!signature_creator->Final(&signature_bytes)) {
43    LOG(ERROR) << "Failed to create policy signature.";
44    return std::string();
45  }
46
47  policy_response.mutable_policy_data_signature()->assign(
48      reinterpret_cast<const char*>(vector_as_array(&signature_bytes)),
49      signature_bytes.size());
50  return policy_response.SerializeAsString();
51}
52
53}  // namepace
54
55OwnerSettingsService::OwnerSettingsService(
56    const scoped_refptr<ownership::OwnerKeyUtil>& owner_key_util)
57    : owner_key_util_(owner_key_util), weak_factory_(this) {
58}
59
60OwnerSettingsService::~OwnerSettingsService() {
61  DCHECK(thread_checker_.CalledOnValidThread());
62}
63
64bool OwnerSettingsService::IsOwner() {
65  DCHECK(thread_checker_.CalledOnValidThread());
66  return private_key_.get() && private_key_->key();
67}
68
69void OwnerSettingsService::IsOwnerAsync(const IsOwnerCallback& callback) {
70  DCHECK(thread_checker_.CalledOnValidThread());
71  if (private_key_.get()) {
72    base::MessageLoop::current()->PostTask(FROM_HERE,
73                                           base::Bind(callback, IsOwner()));
74  } else {
75    pending_is_owner_callbacks_.push_back(callback);
76  }
77}
78
79bool OwnerSettingsService::AssembleAndSignPolicyAsync(
80    base::TaskRunner* task_runner,
81    scoped_ptr<em::PolicyData> policy,
82    const AssembleAndSignPolicyAsyncCallback& callback) {
83  DCHECK(thread_checker_.CalledOnValidThread());
84  if (!task_runner || !IsOwner())
85    return false;
86  return base::PostTaskAndReplyWithResult(
87      task_runner,
88      FROM_HERE,
89      base::Bind(
90          &AssembleAndSignPolicy, base::Passed(&policy), private_key_->key()),
91      callback);
92}
93
94void OwnerSettingsService::ReloadKeypair() {
95  ReloadKeypairImpl(
96      base::Bind(&OwnerSettingsService::OnKeypairLoaded, as_weak_ptr()));
97}
98
99void OwnerSettingsService::OnKeypairLoaded(
100    const scoped_refptr<PublicKey>& public_key,
101    const scoped_refptr<PrivateKey>& private_key) {
102  DCHECK(thread_checker_.CalledOnValidThread());
103
104  public_key_ = public_key;
105  private_key_ = private_key;
106
107  const bool is_owner = IsOwner();
108  std::vector<IsOwnerCallback> is_owner_callbacks;
109  is_owner_callbacks.swap(pending_is_owner_callbacks_);
110  for (std::vector<IsOwnerCallback>::iterator it(is_owner_callbacks.begin());
111       it != is_owner_callbacks.end();
112       ++it) {
113    it->Run(is_owner);
114  }
115
116  OnPostKeypairLoadedActions();
117}
118
119}  // namespace ownership
120