OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "chromeos/attestation/attestation_flow.h" | 5 #include "chromeos/attestation/attestation_flow.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "chromeos/cryptohome/async_method_caller.h" | 8 #include "chromeos/cryptohome/async_method_caller.h" |
9 #include "chromeos/dbus/cryptohome_client.h" | 9 #include "chromeos/dbus/cryptohome_client.h" |
10 | 10 |
(...skipping 20 matching lines...) Expand all Loading... | |
31 LOG(ERROR) << "Attestation: Failed to query enrollment state."; | 31 LOG(ERROR) << "Attestation: Failed to query enrollment state."; |
32 if (!on_fail.is_null()) | 32 if (!on_fail.is_null()) |
33 on_fail.Run(); | 33 on_fail.Run(); |
34 return; | 34 return; |
35 } | 35 } |
36 const base::Closure& task = value ? on_true : on_false; | 36 const base::Closure& task = value ? on_true : on_false; |
37 if (!task.is_null()) | 37 if (!task.is_null()) |
38 task.Run(); | 38 task.Run(); |
39 } | 39 } |
40 | 40 |
41 void DBusDataMethodCallback( | |
42 const chromeos::attestation::AttestationFlow::CertificateCallback& callback, | |
43 DBusMethodCallStatus status, | |
44 bool result, | |
45 const std::string& data) { | |
46 if (status != DBUS_METHOD_CALL_SUCCESS) { | |
47 LOG(ERROR) << "Attestation: DBus data operation failed."; | |
48 if (!callback.is_null()) | |
49 callback.Run(false, ""); | |
50 return; | |
51 } | |
52 if (!callback.is_null()) | |
53 callback.Run(result, data); | |
54 } | |
55 | |
41 } // namespace | 56 } // namespace |
42 | 57 |
43 const char AttestationFlow::kEnterpriseMachineKey[] = "attest-ent-machine"; | |
44 | |
45 AttestationFlow::AttestationFlow(cryptohome::AsyncMethodCaller* async_caller, | 58 AttestationFlow::AttestationFlow(cryptohome::AsyncMethodCaller* async_caller, |
46 CryptohomeClient* cryptohome_client, | 59 CryptohomeClient* cryptohome_client, |
47 scoped_ptr<ServerProxy> server_proxy) | 60 scoped_ptr<ServerProxy> server_proxy) |
48 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | 61 : async_caller_(async_caller), |
49 async_caller_(async_caller), | |
50 cryptohome_client_(cryptohome_client), | 62 cryptohome_client_(cryptohome_client), |
51 server_proxy_(server_proxy.Pass()) { | 63 server_proxy_(server_proxy.Pass()), |
64 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | |
52 } | 65 } |
53 | 66 |
54 AttestationFlow::~AttestationFlow() { | 67 AttestationFlow::~AttestationFlow() { |
55 } | 68 } |
56 | 69 |
57 void AttestationFlow::GetCertificate(const std::string& name, | 70 void AttestationFlow::GetCertificate( |
58 const CertificateCallback& callback) { | 71 AttestationCertificateProfile certificate_profile, |
72 bool force_new_key, | |
73 const CertificateCallback& callback) { | |
59 // If this device has not enrolled with the Privacy CA, we need to do that | 74 // If this device has not enrolled with the Privacy CA, we need to do that |
60 // first. Once enrolled we can proceed with the certificate request. | 75 // first. Once enrolled we can proceed with the certificate request. |
61 base::Closure do_cert_request = base::Bind( | 76 base::Closure do_cert_request = base::Bind( |
62 &AttestationFlow::StartCertificateRequest, | 77 &AttestationFlow::StartCertificateRequest, |
63 weak_factory_.GetWeakPtr(), | 78 weak_factory_.GetWeakPtr(), |
64 name, | 79 certificate_profile, |
80 force_new_key, | |
65 callback); | 81 callback); |
66 base::Closure on_enroll_failure = base::Bind(callback, false, ""); | 82 base::Closure on_enroll_failure = base::Bind(callback, false, ""); |
67 base::Closure do_enroll = base::Bind(&AttestationFlow::StartEnroll, | 83 base::Closure do_enroll = base::Bind(&AttestationFlow::StartEnroll, |
68 weak_factory_.GetWeakPtr(), | 84 weak_factory_.GetWeakPtr(), |
69 on_enroll_failure, | 85 on_enroll_failure, |
70 do_cert_request); | 86 do_cert_request); |
71 cryptohome_client_->TpmAttestationIsEnrolled(base::Bind( | 87 cryptohome_client_->TpmAttestationIsEnrolled(base::Bind( |
72 &DBusBoolRedirectCallback, | 88 &DBusBoolRedirectCallback, |
73 do_cert_request, // If enrolled, proceed with cert request. | 89 do_cert_request, // If enrolled, proceed with cert request. |
74 do_enroll, // If not enrolled, initiate enrollment. | 90 do_enroll, // If not enrolled, initiate enrollment. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 on_failure.Run(); | 152 on_failure.Run(); |
137 return; | 153 return; |
138 } | 154 } |
139 | 155 |
140 // Enrollment has successfully completed, we can move on to whatever is next. | 156 // Enrollment has successfully completed, we can move on to whatever is next. |
141 if (!next_task.is_null()) | 157 if (!next_task.is_null()) |
142 next_task.Run(); | 158 next_task.Run(); |
143 } | 159 } |
144 | 160 |
145 void AttestationFlow::StartCertificateRequest( | 161 void AttestationFlow::StartCertificateRequest( |
146 const std::string& name, | 162 AttestationCertificateProfile certificate_profile, |
163 bool generate_new_key, | |
147 const CertificateCallback& callback) { | 164 const CertificateCallback& callback) { |
148 // Get the attestation service to create a Privacy CA certificate request. | 165 AttestationKeyType key_type = GetKeyTypeForProfile(certificate_profile); |
149 int options = CryptohomeClient::INCLUDE_DEVICE_STATE; | 166 std::string key_name = GetKeyNameForProfile(certificate_profile); |
150 if (name == kEnterpriseMachineKey) | 167 if (generate_new_key) { |
151 options |= CryptohomeClient::INCLUDE_STABLE_ID; | 168 // Get the attestation service to create a Privacy CA certificate request. |
152 async_caller_->AsyncTpmAttestationCreateCertRequest( | 169 async_caller_->AsyncTpmAttestationCreateCertRequest( |
153 options, | 170 GetCertificateOptionsForProfile(certificate_profile), |
154 base::Bind(&AttestationFlow::SendCertificateRequestToPCA, | 171 base::Bind(&AttestationFlow::SendCertificateRequestToPCA, |
155 weak_factory_.GetWeakPtr(), | 172 weak_factory_.GetWeakPtr(), |
156 name, | 173 key_type, |
157 callback)); | 174 key_name, |
175 callback)); | |
176 } else { | |
177 // If the key already exists, query the existing certificate. | |
178 base::Closure on_key_exists = base::Bind( | |
179 &AttestationFlow::GetExistingCertificate, | |
180 weak_factory_.GetWeakPtr(), | |
181 key_type, | |
182 key_name, | |
183 callback); | |
184 // If the key does not exist, call this method back with |generate_new_key| | |
185 // set to true. | |
186 base::Closure on_key_not_exists = base::Bind( | |
187 &AttestationFlow::StartCertificateRequest, | |
188 weak_factory_.GetWeakPtr(), | |
189 certificate_profile, | |
190 true, | |
191 callback); | |
192 cryptohome_client_->TpmAttestationDoesKeyExist( | |
193 key_type, | |
194 key_name, | |
195 base::Bind(&DBusBoolRedirectCallback, | |
196 on_key_exists, | |
197 on_key_not_exists, | |
198 base::Bind(callback, false, ""))); | |
199 } | |
158 } | 200 } |
159 | 201 |
160 void AttestationFlow::SendCertificateRequestToPCA( | 202 void AttestationFlow::SendCertificateRequestToPCA( |
161 const std::string& name, | 203 AttestationKeyType key_type, |
204 const std::string& key_name, | |
162 const CertificateCallback& callback, | 205 const CertificateCallback& callback, |
163 bool success, | 206 bool success, |
164 const std::string& data) { | 207 const std::string& data) { |
165 if (!success) { | 208 if (!success) { |
166 LOG(ERROR) << "Attestation: Failed to create certificate request."; | 209 LOG(ERROR) << "Attestation: Failed to create certificate request."; |
167 if (!callback.is_null()) | 210 if (!callback.is_null()) |
168 callback.Run(false, ""); | 211 callback.Run(false, ""); |
169 return; | 212 return; |
170 } | 213 } |
171 | 214 |
172 // Send the request to the Privacy CA. | 215 // Send the request to the Privacy CA. |
173 server_proxy_->SendCertificateRequest( | 216 server_proxy_->SendCertificateRequest( |
174 data, | 217 data, |
175 base::Bind(&AttestationFlow::SendCertificateResponseToDaemon, | 218 base::Bind(&AttestationFlow::SendCertificateResponseToDaemon, |
176 weak_factory_.GetWeakPtr(), | 219 weak_factory_.GetWeakPtr(), |
177 name, | 220 key_type, |
221 key_name, | |
178 callback)); | 222 callback)); |
179 } | 223 } |
180 | 224 |
181 void AttestationFlow::SendCertificateResponseToDaemon( | 225 void AttestationFlow::SendCertificateResponseToDaemon( |
182 const std::string& name, | 226 AttestationKeyType key_type, |
227 const std::string& key_name, | |
183 const CertificateCallback& callback, | 228 const CertificateCallback& callback, |
184 bool success, | 229 bool success, |
185 const std::string& data) { | 230 const std::string& data) { |
186 if (!success) { | 231 if (!success) { |
187 LOG(ERROR) << "Attestation: Certificate request failed."; | 232 LOG(ERROR) << "Attestation: Certificate request failed."; |
188 if (!callback.is_null()) | 233 if (!callback.is_null()) |
189 callback.Run(false, ""); | 234 callback.Run(false, ""); |
190 return; | 235 return; |
191 } | 236 } |
192 | 237 |
193 // Forward the response to the attestation service to complete the operation. | 238 // Forward the response to the attestation service to complete the operation. |
194 CryptohomeClient::AttestationKeyType key_type = CryptohomeClient::USER_KEY; | |
195 if (name == kEnterpriseMachineKey) | |
196 key_type = CryptohomeClient::DEVICE_KEY; | |
197 async_caller_->AsyncTpmAttestationFinishCertRequest(data, | 239 async_caller_->AsyncTpmAttestationFinishCertRequest(data, |
198 key_type, | 240 key_type, |
199 name, | 241 key_name, |
200 base::Bind(callback)); | 242 base::Bind(callback)); |
201 } | 243 } |
202 | 244 |
245 void AttestationFlow::GetExistingCertificate( | |
246 AttestationKeyType key_type, | |
247 const std::string& key_name, | |
248 const CertificateCallback& callback) { | |
249 cryptohome_client_->TpmAttestationGetCertificate( | |
250 key_type, | |
251 key_name, | |
252 base::Bind(&DBusDataMethodCallback, callback)); | |
253 } | |
254 | |
255 AttestationKeyType AttestationFlow::GetKeyTypeForProfile( | |
Mattias Nissler (ping if slow)
2013/04/24 12:57:53
nit (here and below): These functions could be mov
dkrahn
2013/04/25 01:06:52
Done.
| |
256 AttestationCertificateProfile profile) { | |
257 switch (profile) { | |
258 case ENTERPRISE_MACHINE_CERTIFICATE: | |
259 return DEVICE_KEY; | |
260 case ENTERPRISE_USER_CERTIFICATE: | |
261 return USER_KEY; | |
262 default: | |
263 NOTREACHED(); | |
Mattias Nissler (ping if slow)
2013/04/24 12:57:53
Here and below: It'd be better to not have a defau
dkrahn
2013/04/25 01:06:52
Done.
| |
264 } | |
265 return USER_KEY; | |
266 } | |
267 | |
268 std::string AttestationFlow::GetKeyNameForProfile( | |
269 AttestationCertificateProfile profile) { | |
270 switch (profile) { | |
271 case ENTERPRISE_MACHINE_CERTIFICATE: | |
272 return kEnterpriseMachineKey; | |
273 case ENTERPRISE_USER_CERTIFICATE: | |
274 return kEnterpriseUserKey; | |
275 default: | |
276 NOTREACHED(); | |
277 } | |
278 return ""; | |
279 } | |
280 | |
281 int AttestationFlow::GetCertificateOptionsForProfile( | |
282 AttestationCertificateProfile profile) { | |
283 switch (profile) { | |
284 case ENTERPRISE_MACHINE_CERTIFICATE: | |
285 return INCLUDE_STABLE_ID | INCLUDE_DEVICE_STATE; | |
286 case ENTERPRISE_USER_CERTIFICATE: | |
287 return INCLUDE_DEVICE_STATE; | |
288 default: | |
289 NOTREACHED(); | |
290 } | |
291 return CERTIFICATE_OPTION_NONE; | |
292 } | |
293 | |
203 } // namespace attestation | 294 } // namespace attestation |
204 } // namespace chromeos | 295 } // namespace chromeos |
OLD | NEW |