OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 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 "chromeos/attestation/attestation_flow.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "chromeos/cryptohome/async_method_caller.h" | |
9 #include "chromeos/dbus/cryptohome_client.h" | |
10 | |
11 namespace chromeos { | |
12 namespace attestation { | |
13 | |
14 namespace { | |
15 | |
16 // Redirects to one of three callbacks based on a boolean value and dbus call | |
17 // status. | |
18 // | |
19 // Parameters | |
20 // on_true - Called when status=succes and value=true. | |
21 // on_false - Called when status=success and value=false. | |
22 // on_fail - Called when status=failure. | |
23 // status - The D-Bus operation status. | |
24 // value - The value returned by the D-Bus operation. | |
25 void DBusBoolRedirectCallback(const base::Closure& on_true, | |
26 const base::Closure& on_false, | |
27 const base::Closure& on_fail, | |
28 DBusMethodCallStatus status, | |
29 bool value) { | |
30 if (status != DBUS_METHOD_CALL_SUCCESS) { | |
31 LOG(ERROR) << "Attestation: Failed to query enrollment state."; | |
32 on_fail.Run(); | |
Mattias Nissler (ping if slow)
2013/01/18 13:38:46
IIRC base::Callback implementors generally advise
dkrahn
2013/01/22 22:50:11
Done.
| |
33 return; | |
34 } | |
35 const base::Closure& task = value ? on_true : on_false; | |
36 task.Run(); | |
37 } | |
38 | |
39 } // namespace | |
40 | |
41 const char AttestationFlow::kEnterpriseMachineKey[] = "attest-ent-machine"; | |
42 | |
43 AttestationFlow::AttestationFlow(cryptohome::AsyncMethodCaller* async_caller, | |
44 CryptohomeClient* cryptohome_client, | |
45 ServerProxy* server_proxy) | |
46 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | |
47 async_caller_(async_caller), | |
48 cryptohome_client_(cryptohome_client), | |
49 server_proxy_(server_proxy) { | |
50 } | |
51 | |
52 AttestationFlow::~AttestationFlow() { | |
53 } | |
54 | |
55 void AttestationFlow::GetCertificate(const std::string& name, | |
56 const CertificateCallback& callback) { | |
57 // If this device has not enrolled with the Privacy CA, we need to do that | |
58 // first. Once enrolled we can proceed with the certificate request. | |
59 base::Closure do_cert_request = base::Bind( | |
60 &AttestationFlow::StartCertificateRequest, | |
61 weak_factory_.GetWeakPtr(), | |
62 name, | |
63 callback); | |
64 base::Closure on_enroll_failure = base::Bind(callback, false, ""); | |
65 base::Closure do_enroll = base::Bind(&AttestationFlow::StartEnroll, | |
66 weak_factory_.GetWeakPtr(), | |
67 on_enroll_failure, | |
68 do_cert_request); | |
69 cryptohome_client_->TpmAttestationIsEnrolled(base::Bind( | |
70 &DBusBoolRedirectCallback, | |
71 do_cert_request, // If enrolled, proceed with cert request. | |
72 do_enroll, // If not enrolled, initiate enrollment. | |
73 on_enroll_failure)); | |
74 } | |
75 | |
76 void AttestationFlow::StartEnroll(const base::Closure& on_failure, | |
77 const base::Closure& next_task) { | |
78 // Get the attestation service to create a Privacy CA enrollment request. | |
79 async_caller_->AsyncTpmAttestationCreateEnrollRequest(base::Bind( | |
80 &AttestationFlow::SendEnrollRequestToPCA, | |
81 weak_factory_.GetWeakPtr(), | |
82 on_failure, | |
83 next_task)); | |
84 } | |
85 | |
86 void AttestationFlow::SendEnrollRequestToPCA(const base::Closure& on_failure, | |
87 const base::Closure& next_task, | |
88 bool success, | |
89 const std::string& data) { | |
90 if (!success) { | |
91 LOG(ERROR) << "Attestation: Failed to create enroll request."; | |
92 on_failure.Run(); | |
93 return; | |
94 } | |
95 | |
96 // Send the request to the Privacy CA. | |
97 server_proxy_->SendEnrollRequest( | |
98 data, | |
99 base::Bind(&AttestationFlow::OnEnrollResponse, | |
100 weak_factory_.GetWeakPtr(), | |
101 on_failure, | |
102 next_task)); | |
103 } | |
104 | |
105 void AttestationFlow::OnEnrollResponse(const base::Closure& on_failure, | |
106 const base::Closure& next_task, | |
107 bool success, | |
108 const std::string& data) { | |
109 if (!success) { | |
110 LOG(ERROR) << "Attestation: Enroll request failed."; | |
111 on_failure.Run(); | |
112 return; | |
113 } | |
114 | |
115 // Forward the response to the attestation service to complete enrollment. | |
116 async_caller_->AsyncTpmAttestationEnroll( | |
117 data, | |
118 base::Bind(&AttestationFlow::OnEnrollComplete, | |
119 weak_factory_.GetWeakPtr(), | |
120 on_failure, | |
121 next_task)); | |
122 } | |
123 | |
124 void AttestationFlow::OnEnrollComplete(const base::Closure& on_failure, | |
125 const base::Closure& next_task, | |
126 bool success, | |
127 cryptohome::MountError /*not_used*/) { | |
128 if (!success) { | |
129 LOG(ERROR) << "Attestation: Failed to complete enrollment."; | |
130 on_failure.Run(); | |
131 return; | |
132 } | |
133 | |
134 // Enrollment has successfully completed, we can move on to whatever is next. | |
135 next_task.Run(); | |
136 } | |
137 | |
138 void AttestationFlow::StartCertificateRequest( | |
139 const std::string& name, | |
140 const CertificateCallback& callback) { | |
141 // Get the attestation service to create a Privacy CA certificate request. | |
142 async_caller_->AsyncTpmAttestationCreateCertRequest( | |
143 (name == kEnterpriseMachineKey), | |
144 base::Bind(&AttestationFlow::SendCertificateRequestToPCA, | |
145 weak_factory_.GetWeakPtr(), | |
146 callback)); | |
147 } | |
148 | |
149 void AttestationFlow::SendCertificateRequestToPCA( | |
150 const CertificateCallback& callback, | |
151 bool success, | |
152 const std::string& data) { | |
153 if (!success) { | |
154 LOG(ERROR) << "Attestation: Failed to create certificate request."; | |
155 callback.Run(false, ""); | |
156 return; | |
157 } | |
158 | |
159 // Send the request to the Privacy CA. | |
160 server_proxy_->SendCertificateRequest( | |
161 data, | |
162 base::Bind(&AttestationFlow::OnCertificateResponse, | |
163 weak_factory_.GetWeakPtr(), | |
164 callback)); | |
165 } | |
166 | |
167 void AttestationFlow::OnCertificateResponse(const CertificateCallback& callback, | |
168 bool success, | |
169 const std::string& data) { | |
170 if (!success) { | |
171 LOG(ERROR) << "Attestation: Certificate request failed."; | |
172 callback.Run(false, ""); | |
173 return; | |
174 } | |
175 | |
176 // Forward the response to the attestation service to complete the operation. | |
177 async_caller_->AsyncTpmAttestationFinishCertRequest(data, | |
178 base::Bind(callback)); | |
179 } | |
180 | |
181 } // namespace attestation | |
182 } // namespace chromeos | |
OLD | NEW |