1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/chromeos/login/ownership_service.h"
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/file_path.h"
8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/file_util.h"
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/lazy_instance.h"
10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/synchronization/lock.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/browser_process.h"
12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// We want to use NewRunnableMethod for non-static methods of this class but
15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// need to disable reference counting since it is singleton.
16dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenDISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::OwnershipService);
17bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace chromeos {
19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic base::LazyInstance<OwnershipService> g_ownership_service(
2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    base::LINKER_INITIALIZED);
2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen//  static
24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenOwnershipService* OwnershipService::GetSharedInstance() {
2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return g_ownership_service.Pointer();
26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenOwnershipService::OwnershipService()
29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    : manager_(new OwnerManager),
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      utils_(OwnerKeyUtils::Create()),
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      policy_(NULL),
32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      ownership_status_(OWNERSHIP_UNKNOWN) {
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  notification_registrar_.Add(
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      this,
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NotificationType::OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED,
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NotificationService::AllSources());
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenOwnershipService::~OwnershipService() {}
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid OwnershipService::Prewarm() {
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Note that we cannot prewarm in constructor because in current codebase
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // object is created before spawning threads.
44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (g_ownership_service == this) {
45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Start getting ownership status.
46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    BrowserThread::PostTask(
47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        BrowserThread::FILE,
48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        FROM_HERE,
49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        NewRunnableMethod(this, &OwnershipService::FetchStatus));
50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else {
51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // This can happen only for particular test: OwnershipServiceTest. It uses
52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // mocks and for that uses OwnershipService not as a regular singleton but
53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // as a resurrecting object. This behaviour conflicts with
54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // DISABLE_RUNNABLE_METHOD_REFCOUNT.  So avoid posting task in those
55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // circumstances in order to avoid accessing already deleted object.
56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid OwnershipService::set_cached_policy(const em::PolicyData& pol) {
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  policy_.reset(pol.New());
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  policy_->CheckTypeAndMergeFrom(pol);
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool OwnershipService::has_cached_policy() {
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return policy_.get();
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst em::PolicyData& OwnershipService::cached_policy() {
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return *(policy_.get());
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool OwnershipService::IsAlreadyOwned() {
73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return file_util::PathExists(utils_->GetOwnerKeyFilePath());
74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
76dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenOwnershipService::Status OwnershipService::GetStatus(bool blocking) {
77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  Status status = OWNERSHIP_UNKNOWN;
78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool is_owned = false;
79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    ownership_status_lock_.Acquire();
81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    status = ownership_status_;
82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    ownership_status_lock_.Release();
83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (status != OWNERSHIP_UNKNOWN || !blocking)
84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      return status;
85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // Under common usage there is very short lapse of time when ownership
86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // status is still unknown after constructing OwnershipService.
87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    LOG(ERROR) << "Blocking on UI thread in OwnershipService::GetStatus";
88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    base::ThreadRestrictions::ScopedAllowIO allow_io;
89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    is_owned = IsAlreadyOwned();
90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else {
91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    is_owned = IsAlreadyOwned();
93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
94dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  status = is_owned ? OWNERSHIP_TAKEN : OWNERSHIP_NONE;
95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SetStatus(status);
96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return status;
97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
98bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OwnershipService::StartLoadOwnerKeyAttempt() {
100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::FILE, FROM_HERE,
102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      NewRunnableFunction(&TryLoadOwnerKeyAttempt, this));
103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid OwnershipService::StartUpdateOwnerKey(const std::vector<uint8>& new_key,
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                           OwnerManager::KeyUpdateDelegate* d) {
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::ID thread_id;
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!BrowserThread::GetCurrentThreadIdentifier(&thread_id))
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    thread_id = BrowserThread::UI;
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  BrowserThread::PostTask(
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserThread::FILE, FROM_HERE,
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewRunnableFunction(&OwnershipService::UpdateOwnerKey,
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          this,
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          thread_id,
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          new_key,
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          d));
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return;
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid OwnershipService::StartSigningAttempt(const std::string& data,
121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                           OwnerManager::Delegate* d) {
122731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::ID thread_id;
123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!BrowserThread::GetCurrentThreadIdentifier(&thread_id))
124731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    thread_id = BrowserThread::UI;
125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
126731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::FILE, FROM_HERE,
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NewRunnableFunction(&OwnershipService::TrySigningAttempt,
12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          this,
12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          thread_id,
13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          data,
13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          d));
132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return;
133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
134bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
135bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid OwnershipService::StartVerifyAttempt(const std::string& data,
136bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                          const std::vector<uint8>& signature,
137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                          OwnerManager::Delegate* d) {
138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::ID thread_id;
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!BrowserThread::GetCurrentThreadIdentifier(&thread_id))
140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    thread_id = BrowserThread::UI;
141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  BrowserThread::PostTask(
142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      BrowserThread::FILE, FROM_HERE,
14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NewRunnableFunction(&OwnershipService::TryVerifyAttempt,
14472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          this,
14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          thread_id,
14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          data,
14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          signature,
14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                          d));
149bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return;
150bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
151bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OwnershipService::Observe(NotificationType type,
153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                               const NotificationSource& source,
154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen                               const NotificationDetails& details) {
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (type.value == NotificationType::OWNER_KEY_FETCH_ATTEMPT_SUCCEEDED) {
156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    SetStatus(OWNERSHIP_TAKEN);
157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    notification_registrar_.RemoveAll();
158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else {
159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    NOTREACHED();
160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
163bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool OwnershipService::CurrentUserIsOwner() {
164bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // If this user has the private key associated with the owner's
165bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // public key, this user is the owner.
166bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return IsAlreadyOwned() && manager_->EnsurePrivateKey();
167bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
168bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid OwnershipService::UpdateOwnerKey(OwnershipService* service,
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      const BrowserThread::ID thread_id,
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      const std::vector<uint8>& new_key,
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      OwnerManager::KeyUpdateDelegate* d) {
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service->manager()->UpdateOwnerKey(thread_id, new_key, d);
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid OwnershipService::TryLoadOwnerKeyAttempt(OwnershipService* service) {
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!service->IsAlreadyOwned()) {
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    VLOG(1) << "Device not yet owned";
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service->manager()->LoadOwnerKey();
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid OwnershipService::TrySigningAttempt(OwnershipService* service,
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                         const BrowserThread::ID thread_id,
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                         const std::string& data,
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                         OwnerManager::Delegate* d) {
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!service->IsAlreadyOwned()) {
19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    LOG(ERROR) << "Device not yet owned";
19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    BrowserThread::PostTask(
19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        thread_id, FROM_HERE,
19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        NewRunnableFunction(&OwnershipService::FailAttempt, d));
19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service->manager()->Sign(thread_id, data, d);
20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static
20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid OwnershipService::TryVerifyAttempt(OwnershipService* service,
20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                        const BrowserThread::ID thread_id,
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                        const std::string& data,
20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                        const std::vector<uint8>& signature,
20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                        OwnerManager::Delegate* d) {
21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!service->IsAlreadyOwned()) {
21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    LOG(ERROR) << "Device not yet owned";
21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    BrowserThread::PostTask(
21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        thread_id, FROM_HERE,
21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        NewRunnableFunction(&OwnershipService::FailAttempt, d));
21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  service->manager()->Verify(thread_id, data, signature, d);
21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// static
22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid OwnershipService::FailAttempt(OwnerManager::Delegate* d) {
22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  d->OnKeyOpComplete(OwnerManager::KEY_UNAVAILABLE, std::vector<uint8>());
22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OwnershipService::FetchStatus() {
227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  Status status = IsAlreadyOwned() ? OWNERSHIP_TAKEN : OWNERSHIP_NONE;
229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SetStatus(status);
230dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
231dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
232dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid OwnershipService::SetStatus(Status new_status) {
233dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(new_status == OWNERSHIP_TAKEN || new_status == OWNERSHIP_NONE);
234dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  base::AutoLock lk(ownership_status_lock_);
235dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ownership_status_ = new_status;
236dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
237dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
238bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace chromeos
239