Chromium Code Reviews| 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 |