Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: chrome/browser/chromeos/attestation/attestation_policy_observer.cc

Issue 14220003: Finished implementing AttestationPolicyObserver. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/attestation/attestation_policy_observer.h" 5 #include "chrome/browser/chromeos/attestation/attestation_policy_observer.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h"
11 #include "base/time.h"
10 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h" 12 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h"
13 #include "chrome/browser/chromeos/attestation/attestation_key_payload.pb.h"
11 #include "chrome/browser/chromeos/settings/cros_settings.h" 14 #include "chrome/browser/chromeos/settings/cros_settings.h"
12 #include "chrome/browser/policy/cloud/cloud_policy_client.h" 15 #include "chrome/browser/policy/cloud/cloud_policy_client.h"
13 #include "chrome/browser/policy/cloud/cloud_policy_manager.h" 16 #include "chrome/browser/policy/cloud/cloud_policy_manager.h"
14 #include "chrome/common/chrome_notification_types.h" 17 #include "chrome/common/chrome_notification_types.h"
15 #include "chromeos/attestation/attestation_flow.h" 18 #include "chromeos/attestation/attestation_flow.h"
16 #include "chromeos/cryptohome/async_method_caller.h" 19 #include "chromeos/cryptohome/async_method_caller.h"
17 #include "chromeos/dbus/cryptohome_client.h" 20 #include "chromeos/dbus/cryptohome_client.h"
18 #include "chromeos/dbus/dbus_method_call_status.h" 21 #include "chromeos/dbus/dbus_method_call_status.h"
19 #include "chromeos/dbus/dbus_thread_manager.h" 22 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/notification_details.h" 24 #include "content/public/browser/notification_details.h"
25 #include "net/cert/x509_certificate.h"
22 26
23 namespace { 27 namespace {
24 28
25 // A dbus callback which handles a boolean result. 29 // A dbus callback which handles a boolean result.
26 // 30 //
27 // Parameters 31 // Parameters
28 // on_true - Called when status=success and value=true. 32 // on_true - Called when status=success and value=true.
29 // on_false - Called when status=success and value=false. 33 // on_false - Called when status=success and value=false.
30 // status - The dbus operation status. 34 // status - The dbus operation status.
31 // value - The value returned by the dbus operation. 35 // value - The value returned by the dbus operation.
32 void DBusBoolRedirectCallback(const base::Closure& on_true, 36 void DBusBoolRedirectCallback(const base::Closure& on_true,
33 const base::Closure& on_false, 37 const base::Closure& on_false,
38 const std::string& method_name,
34 chromeos::DBusMethodCallStatus status, 39 chromeos::DBusMethodCallStatus status,
35 bool value) { 40 bool value) {
36 if (status != chromeos::DBUS_METHOD_CALL_SUCCESS) 41 if (status != chromeos::DBUS_METHOD_CALL_SUCCESS) {
42 LOG(WARNING) << "Cryptohome DBus method failed: " << method_name;
Mattias Nissler (ping if slow) 2013/04/23 10:53:01 You probably want to log |status| as well.
dkrahn 2013/04/23 21:17:09 Done.
37 return; 43 return;
44 }
38 const base::Closure& task = value ? on_true : on_false; 45 const base::Closure& task = value ? on_true : on_false;
39 if (!task.is_null()) 46 if (!task.is_null())
40 task.Run(); 47 task.Run();
41 } 48 }
42 49
43 // A dbus callback which handles a string result. 50 // A dbus callback which handles a string result.
44 // 51 //
45 // Parameters 52 // Parameters
46 // on_success - Called when status=success and result=true. 53 // on_success - Called when status=success and result=true.
47 // status - The dbus operation status. 54 // status - The dbus operation status.
48 // result - The result returned by the dbus operation. 55 // result - The result returned by the dbus operation.
49 // data - The data returned by the dbus operation. 56 // data - The data returned by the dbus operation.
50 void DBusStringCallback( 57 void DBusStringCallback(
51 const base::Callback<void(const std::string&)> on_success, 58 const base::Callback<void(const std::string&)> on_success,
59 const std::string& method_name,
52 chromeos::DBusMethodCallStatus status, 60 chromeos::DBusMethodCallStatus status,
53 bool result, 61 bool result,
54 const std::string& data) { 62 const std::string& data) {
55 if (status != chromeos::DBUS_METHOD_CALL_SUCCESS || !result) 63 if (status != chromeos::DBUS_METHOD_CALL_SUCCESS || !result) {
64 LOG(WARNING) << "Cryptohome DBus method failed: " << method_name;
56 return; 65 return;
66 }
57 on_success.Run(data); 67 on_success.Run(data);
58 } 68 }
59 69
60 } // namespace 70 } // namespace
61 71
62 namespace chromeos { 72 namespace chromeos {
63 namespace attestation { 73 namespace attestation {
64 74
65 const char AttestationPolicyObserver::kEnterpriseMachineKey[] = 75 const char AttestationPolicyObserver::kEnterpriseMachineKey[] =
66 "attest-ent-machine"; 76 "attest-ent-machine";
67 77
78 const int AttestationPolicyObserver::kExpiryThresholdInDays = 30;
79
68 AttestationPolicyObserver::AttestationPolicyObserver( 80 AttestationPolicyObserver::AttestationPolicyObserver(
69 policy::CloudPolicyClient* policy_client) 81 policy::CloudPolicyClient* policy_client)
70 : cros_settings_(CrosSettings::Get()), 82 : cros_settings_(CrosSettings::Get()),
71 policy_client_(policy_client), 83 policy_client_(policy_client),
72 cryptohome_client_(NULL), 84 cryptohome_client_(NULL),
73 attestation_flow_(NULL), 85 attestation_flow_(NULL),
74 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 86 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
75 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 87 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
76 cros_settings_->AddSettingsObserver(kDeviceAttestationEnabled, this); 88 cros_settings_->AddSettingsObserver(kDeviceAttestationEnabled, this);
77 Start(); 89 Start();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 // Start a dbus call to check if an Enterprise Machine Key already exists. 150 // Start a dbus call to check if an Enterprise Machine Key already exists.
139 base::Closure on_does_exist = 151 base::Closure on_does_exist =
140 base::Bind(&AttestationPolicyObserver::GetExistingCertificate, 152 base::Bind(&AttestationPolicyObserver::GetExistingCertificate,
141 weak_factory_.GetWeakPtr()); 153 weak_factory_.GetWeakPtr());
142 base::Closure on_does_not_exist = 154 base::Closure on_does_not_exist =
143 base::Bind(&AttestationPolicyObserver::GetNewCertificate, 155 base::Bind(&AttestationPolicyObserver::GetNewCertificate,
144 weak_factory_.GetWeakPtr()); 156 weak_factory_.GetWeakPtr());
145 cryptohome_client_->TpmAttestationDoesKeyExist( 157 cryptohome_client_->TpmAttestationDoesKeyExist(
146 CryptohomeClient::DEVICE_KEY, 158 CryptohomeClient::DEVICE_KEY,
147 kEnterpriseMachineKey, 159 kEnterpriseMachineKey,
148 base::Bind(DBusBoolRedirectCallback, on_does_exist, on_does_not_exist)); 160 base::Bind(DBusBoolRedirectCallback,
161 on_does_exist,
162 on_does_not_exist,
163 "TpmAttestationDoesKeyExist"));
149 } 164 }
150 165
151 void AttestationPolicyObserver::GetNewCertificate() { 166 void AttestationPolicyObserver::GetNewCertificate() {
152 // We can reuse the dbus callback handler logic. 167 // We can reuse the dbus callback handler logic.
153 attestation_flow_->GetCertificate( 168 attestation_flow_->GetCertificate(
154 kEnterpriseMachineKey, 169 kEnterpriseMachineKey,
155 base::Bind(DBusStringCallback, 170 base::Bind(DBusStringCallback,
156 base::Bind(&AttestationPolicyObserver::UploadCertificate, 171 base::Bind(&AttestationPolicyObserver::UploadCertificate,
157 weak_factory_.GetWeakPtr()), 172 weak_factory_.GetWeakPtr()),
158 DBUS_METHOD_CALL_SUCCESS)); 173 "", DBUS_METHOD_CALL_SUCCESS));
Mattias Nissler (ping if slow) 2013/04/23 10:53:01 Should have a proper identifying name? FWIW, you c
dkrahn 2013/04/23 21:17:09 Good idea, changed to use FROM_HERE.
159 } 174 }
160 175
161 void AttestationPolicyObserver::GetExistingCertificate() { 176 void AttestationPolicyObserver::GetExistingCertificate() {
162 cryptohome_client_->TpmAttestationGetCertificate( 177 cryptohome_client_->TpmAttestationGetCertificate(
163 CryptohomeClient::DEVICE_KEY, 178 CryptohomeClient::DEVICE_KEY,
164 kEnterpriseMachineKey, 179 kEnterpriseMachineKey,
165 base::Bind(DBusStringCallback, 180 base::Bind(DBusStringCallback,
166 base::Bind(&AttestationPolicyObserver::CheckCertificateExpiry, 181 base::Bind(&AttestationPolicyObserver::CheckCertificateExpiry,
167 weak_factory_.GetWeakPtr()))); 182 weak_factory_.GetWeakPtr()),
183 "TpmAttestationGetCertificate"));
168 } 184 }
169 185
170 void AttestationPolicyObserver::CheckCertificateExpiry( 186 void AttestationPolicyObserver::CheckCertificateExpiry(
171 const std::string& certificate) { 187 const std::string& certificate) {
172 // TODO(dkrahn): Check if the certificate will expire soon, for now assume no. 188 scoped_refptr<net::X509Certificate> x509(
173 CheckIfUploaded(certificate); 189 net::X509Certificate::CreateFromBytes(certificate.data(),
190 certificate.length()));
191 if (!x509.get() || x509->valid_expiry().is_null()) {
192 LOG(WARNING) << "Failed to parse certificate, cannot check expiry.";
193 } else {
194 const base::TimeDelta threshold =
195 base::TimeDelta::FromDays(kExpiryThresholdInDays);
196 if ((base::Time::Now() + threshold) > x509->valid_expiry()) {
197 // The certificate has expired or will soon, replace it.
198 GetNewCertificate();
199 return;
200 }
201 }
202
203 // Get the payload and check if the certificate has already been uploaded.
204 GetKeyPayload(base::Bind(&AttestationPolicyObserver::CheckIfUploaded,
205 weak_factory_.GetWeakPtr(),
206 certificate));
174 } 207 }
175 208
176 void AttestationPolicyObserver::UploadCertificate( 209 void AttestationPolicyObserver::UploadCertificate(
177 const std::string& certificate) { 210 const std::string& certificate) {
178 // TODO(dkrahn): Upload the certificate. 211 policy_client_->UploadCertificate(
212 certificate,
213 base::Bind(&AttestationPolicyObserver::OnUploadComplete,
214 weak_factory_.GetWeakPtr()));
179 } 215 }
180 216
181 void AttestationPolicyObserver::CheckIfUploaded( 217 void AttestationPolicyObserver::CheckIfUploaded(
182 const std::string& certificate) { 218 const std::string& certificate,
183 // TODO(dkrahn): Check if we've already uploaded the certificate. 219 const std::string& key_payload) {
220 AttestationKeyPayload payload_pb;
221 if (!key_payload.empty() &&
222 payload_pb.ParseFromString(key_payload) &&
223 payload_pb.is_certificate_uploaded()) {
224 // Already uploaded... nothing more to do.
225 return;
226 }
227 UploadCertificate(certificate);
228 }
229
230 void AttestationPolicyObserver::GetKeyPayload(
231 base::Callback<void(const std::string&)> callback) {
232 cryptohome_client_->TpmAttestationGetKeyPayload(
233 CryptohomeClient::DEVICE_KEY,
234 kEnterpriseMachineKey,
235 base::Bind(DBusStringCallback, callback, "TpmAttestationGetKeyPayload"));
236 }
237
238 void AttestationPolicyObserver::OnUploadComplete(bool status) {
239 if (!status)
240 return;
241 GetKeyPayload(base::Bind(&AttestationPolicyObserver::MarkAsUploaded,
242 weak_factory_.GetWeakPtr()));
243 }
244
245 void AttestationPolicyObserver::MarkAsUploaded(const std::string& key_payload) {
246 AttestationKeyPayload payload_pb;
247 if (!key_payload.empty())
248 payload_pb.ParseFromString(key_payload);
249 payload_pb.set_is_certificate_uploaded(true);
250 std::string new_payload;
251 if (!payload_pb.SerializeToString(&new_payload)) {
252 LOG(WARNING) << "Failed to serialize key payload.";
253 return;
254 }
255 cryptohome_client_->TpmAttestationSetKeyPayload(
256 CryptohomeClient::DEVICE_KEY,
257 kEnterpriseMachineKey,
258 new_payload,
259 base::Bind(DBusBoolRedirectCallback,
260 base::Closure(),
261 base::Closure(),
262 "TpmAttestationSetKeyPayload"));
184 } 263 }
185 264
186 } // namespace attestation 265 } // namespace attestation
187 } // namespace chromeos 266 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698