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

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: Added NET_EXPORT_PRIVATE for unit tests 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/location.h"
12 #include "base/time.h"
10 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h" 13 #include "chrome/browser/chromeos/attestation/attestation_ca_client.h"
14 #include "chrome/browser/chromeos/attestation/attestation_key_payload.pb.h"
11 #include "chrome/browser/chromeos/settings/cros_settings.h" 15 #include "chrome/browser/chromeos/settings/cros_settings.h"
12 #include "chrome/browser/policy/cloud/cloud_policy_client.h" 16 #include "chrome/browser/policy/cloud/cloud_policy_client.h"
13 #include "chrome/browser/policy/cloud/cloud_policy_manager.h" 17 #include "chrome/browser/policy/cloud/cloud_policy_manager.h"
14 #include "chrome/common/chrome_notification_types.h" 18 #include "chrome/common/chrome_notification_types.h"
15 #include "chromeos/attestation/attestation_flow.h" 19 #include "chromeos/attestation/attestation_flow.h"
16 #include "chromeos/cryptohome/async_method_caller.h" 20 #include "chromeos/cryptohome/async_method_caller.h"
17 #include "chromeos/dbus/cryptohome_client.h" 21 #include "chromeos/dbus/cryptohome_client.h"
18 #include "chromeos/dbus/dbus_method_call_status.h" 22 #include "chromeos/dbus/dbus_method_call_status.h"
19 #include "chromeos/dbus/dbus_thread_manager.h" 23 #include "chromeos/dbus/dbus_thread_manager.h"
20 #include "content/public/browser/browser_thread.h" 24 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/notification_details.h" 25 #include "content/public/browser/notification_details.h"
26 #include "net/cert/x509_certificate.h"
22 27
23 namespace { 28 namespace {
24 29
30 const char kEnterpriseMachineKey[] = "attest-ent-machine";
31
32 // The number of days before a certificate expires during which it is
33 // considered 'expiring soon' and replacement is initiated. The Chrome OS CA
34 // issues certificates with an expiry of at least two years. This value has
35 // been set large enough so that the majority of users will have gone through
36 // a full sign-in during the period.
37 const int kExpiryThresholdInDays = 30;
38
25 // A dbus callback which handles a boolean result. 39 // A dbus callback which handles a boolean result.
26 // 40 //
27 // Parameters 41 // Parameters
28 // on_true - Called when status=success and value=true. 42 // on_true - Called when status=success and value=true.
29 // on_false - Called when status=success and value=false. 43 // on_false - Called when status=success and value=false.
30 // status - The dbus operation status. 44 // status - The dbus operation status.
31 // value - The value returned by the dbus operation. 45 // value - The value returned by the dbus operation.
32 void DBusBoolRedirectCallback(const base::Closure& on_true, 46 void DBusBoolRedirectCallback(const base::Closure& on_true,
33 const base::Closure& on_false, 47 const base::Closure& on_false,
48 const tracked_objects::Location& from_here,
34 chromeos::DBusMethodCallStatus status, 49 chromeos::DBusMethodCallStatus status,
35 bool value) { 50 bool value) {
36 if (status != chromeos::DBUS_METHOD_CALL_SUCCESS) 51 if (status != chromeos::DBUS_METHOD_CALL_SUCCESS) {
52 LOG(ERROR) << "Cryptohome DBus method failed: " << from_here.ToString()
53 << " - " << status;
37 return; 54 return;
55 }
38 const base::Closure& task = value ? on_true : on_false; 56 const base::Closure& task = value ? on_true : on_false;
39 if (!task.is_null()) 57 if (!task.is_null())
40 task.Run(); 58 task.Run();
41 } 59 }
42 60
43 // A dbus callback which handles a string result. 61 // A dbus callback which handles a string result.
44 // 62 //
45 // Parameters 63 // Parameters
46 // on_success - Called when status=success and result=true. 64 // on_success - Called when status=success and result=true.
47 // status - The dbus operation status. 65 // status - The dbus operation status.
48 // result - The result returned by the dbus operation. 66 // result - The result returned by the dbus operation.
49 // data - The data returned by the dbus operation. 67 // data - The data returned by the dbus operation.
50 void DBusStringCallback( 68 void DBusStringCallback(
51 const base::Callback<void(const std::string&)> on_success, 69 const base::Callback<void(const std::string&)> on_success,
70 const tracked_objects::Location& from_here,
52 chromeos::DBusMethodCallStatus status, 71 chromeos::DBusMethodCallStatus status,
53 bool result, 72 bool result,
54 const std::string& data) { 73 const std::string& data) {
55 if (status != chromeos::DBUS_METHOD_CALL_SUCCESS || !result) 74 if (status != chromeos::DBUS_METHOD_CALL_SUCCESS || !result) {
75 LOG(ERROR) << "Cryptohome DBus method failed: " << from_here.ToString()
76 << " - " << status << " - " << result;
56 return; 77 return;
78 }
57 on_success.Run(data); 79 on_success.Run(data);
58 } 80 }
59 81
60 } // namespace 82 } // namespace
61 83
62 namespace chromeos { 84 namespace chromeos {
63 namespace attestation { 85 namespace attestation {
64 86
65 const char AttestationPolicyObserver::kEnterpriseMachineKey[] =
66 "attest-ent-machine";
67
68 AttestationPolicyObserver::AttestationPolicyObserver( 87 AttestationPolicyObserver::AttestationPolicyObserver(
69 policy::CloudPolicyClient* policy_client) 88 policy::CloudPolicyClient* policy_client)
70 : cros_settings_(CrosSettings::Get()), 89 : cros_settings_(CrosSettings::Get()),
71 policy_client_(policy_client), 90 policy_client_(policy_client),
72 cryptohome_client_(NULL), 91 cryptohome_client_(NULL),
73 attestation_flow_(NULL), 92 attestation_flow_(NULL),
74 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 93 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
75 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 94 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
76 cros_settings_->AddSettingsObserver(kDeviceAttestationEnabled, this); 95 cros_settings_->AddSettingsObserver(kDeviceAttestationEnabled, this);
77 Start(); 96 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. 157 // Start a dbus call to check if an Enterprise Machine Key already exists.
139 base::Closure on_does_exist = 158 base::Closure on_does_exist =
140 base::Bind(&AttestationPolicyObserver::GetExistingCertificate, 159 base::Bind(&AttestationPolicyObserver::GetExistingCertificate,
141 weak_factory_.GetWeakPtr()); 160 weak_factory_.GetWeakPtr());
142 base::Closure on_does_not_exist = 161 base::Closure on_does_not_exist =
143 base::Bind(&AttestationPolicyObserver::GetNewCertificate, 162 base::Bind(&AttestationPolicyObserver::GetNewCertificate,
144 weak_factory_.GetWeakPtr()); 163 weak_factory_.GetWeakPtr());
145 cryptohome_client_->TpmAttestationDoesKeyExist( 164 cryptohome_client_->TpmAttestationDoesKeyExist(
146 CryptohomeClient::DEVICE_KEY, 165 CryptohomeClient::DEVICE_KEY,
147 kEnterpriseMachineKey, 166 kEnterpriseMachineKey,
148 base::Bind(DBusBoolRedirectCallback, on_does_exist, on_does_not_exist)); 167 base::Bind(DBusBoolRedirectCallback,
168 on_does_exist,
169 on_does_not_exist,
170 FROM_HERE));
149 } 171 }
150 172
151 void AttestationPolicyObserver::GetNewCertificate() { 173 void AttestationPolicyObserver::GetNewCertificate() {
152 // We can reuse the dbus callback handler logic. 174 // We can reuse the dbus callback handler logic.
153 attestation_flow_->GetCertificate( 175 attestation_flow_->GetCertificate(
154 kEnterpriseMachineKey, 176 kEnterpriseMachineKey,
155 base::Bind(DBusStringCallback, 177 base::Bind(DBusStringCallback,
156 base::Bind(&AttestationPolicyObserver::UploadCertificate, 178 base::Bind(&AttestationPolicyObserver::UploadCertificate,
157 weak_factory_.GetWeakPtr()), 179 weak_factory_.GetWeakPtr()),
180 FROM_HERE,
158 DBUS_METHOD_CALL_SUCCESS)); 181 DBUS_METHOD_CALL_SUCCESS));
159 } 182 }
160 183
161 void AttestationPolicyObserver::GetExistingCertificate() { 184 void AttestationPolicyObserver::GetExistingCertificate() {
162 cryptohome_client_->TpmAttestationGetCertificate( 185 cryptohome_client_->TpmAttestationGetCertificate(
163 CryptohomeClient::DEVICE_KEY, 186 CryptohomeClient::DEVICE_KEY,
164 kEnterpriseMachineKey, 187 kEnterpriseMachineKey,
165 base::Bind(DBusStringCallback, 188 base::Bind(DBusStringCallback,
166 base::Bind(&AttestationPolicyObserver::CheckCertificateExpiry, 189 base::Bind(&AttestationPolicyObserver::CheckCertificateExpiry,
167 weak_factory_.GetWeakPtr()))); 190 weak_factory_.GetWeakPtr()),
191 FROM_HERE));
168 } 192 }
169 193
170 void AttestationPolicyObserver::CheckCertificateExpiry( 194 void AttestationPolicyObserver::CheckCertificateExpiry(
171 const std::string& certificate) { 195 const std::string& certificate) {
172 // TODO(dkrahn): Check if the certificate will expire soon, for now assume no. 196 scoped_refptr<net::X509Certificate> x509(
173 CheckIfUploaded(certificate); 197 net::X509Certificate::CreateFromBytes(certificate.data(),
198 certificate.length()));
199 if (!x509.get() || x509->valid_expiry().is_null()) {
200 LOG(WARNING) << "Failed to parse certificate, cannot check expiry.";
201 } else {
202 const base::TimeDelta threshold =
203 base::TimeDelta::FromDays(kExpiryThresholdInDays);
204 if ((base::Time::Now() + threshold) > x509->valid_expiry()) {
205 // The certificate has expired or will soon, replace it.
206 GetNewCertificate();
207 return;
208 }
209 }
210
211 // Get the payload and check if the certificate has already been uploaded.
212 GetKeyPayload(base::Bind(&AttestationPolicyObserver::CheckIfUploaded,
213 weak_factory_.GetWeakPtr(),
214 certificate));
174 } 215 }
175 216
176 void AttestationPolicyObserver::UploadCertificate( 217 void AttestationPolicyObserver::UploadCertificate(
177 const std::string& certificate) { 218 const std::string& certificate) {
178 // TODO(dkrahn): Upload the certificate. 219 policy_client_->UploadCertificate(
220 certificate,
221 base::Bind(&AttestationPolicyObserver::OnUploadComplete,
222 weak_factory_.GetWeakPtr()));
179 } 223 }
180 224
181 void AttestationPolicyObserver::CheckIfUploaded( 225 void AttestationPolicyObserver::CheckIfUploaded(
182 const std::string& certificate) { 226 const std::string& certificate,
183 // TODO(dkrahn): Check if we've already uploaded the certificate. 227 const std::string& key_payload) {
228 AttestationKeyPayload payload_pb;
229 if (!key_payload.empty() &&
230 payload_pb.ParseFromString(key_payload) &&
231 payload_pb.is_certificate_uploaded()) {
232 // Already uploaded... nothing more to do.
233 return;
234 }
235 UploadCertificate(certificate);
236 }
237
238 void AttestationPolicyObserver::GetKeyPayload(
239 base::Callback<void(const std::string&)> callback) {
240 cryptohome_client_->TpmAttestationGetKeyPayload(
241 CryptohomeClient::DEVICE_KEY,
242 kEnterpriseMachineKey,
243 base::Bind(DBusStringCallback, callback, FROM_HERE));
244 }
245
246 void AttestationPolicyObserver::OnUploadComplete(bool status) {
247 if (!status)
248 return;
249 GetKeyPayload(base::Bind(&AttestationPolicyObserver::MarkAsUploaded,
250 weak_factory_.GetWeakPtr()));
251 }
252
253 void AttestationPolicyObserver::MarkAsUploaded(const std::string& key_payload) {
254 AttestationKeyPayload payload_pb;
255 if (!key_payload.empty())
256 payload_pb.ParseFromString(key_payload);
257 payload_pb.set_is_certificate_uploaded(true);
258 std::string new_payload;
259 if (!payload_pb.SerializeToString(&new_payload)) {
260 LOG(WARNING) << "Failed to serialize key payload.";
261 return;
262 }
263 cryptohome_client_->TpmAttestationSetKeyPayload(
264 CryptohomeClient::DEVICE_KEY,
265 kEnterpriseMachineKey,
266 new_payload,
267 base::Bind(DBusBoolRedirectCallback,
268 base::Closure(),
269 base::Closure(),
270 FROM_HERE));
184 } 271 }
185 272
186 } // namespace attestation 273 } // namespace attestation
187 } // namespace chromeos 274 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698