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