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 if (!on_fail.is_null()) |
| 33 on_fail.Run(); |
| 34 return; |
| 35 } |
| 36 const base::Closure& task = value ? on_true : on_false; |
| 37 if (!task.is_null()) |
| 38 task.Run(); |
| 39 } |
| 40 |
| 41 } // namespace |
| 42 |
| 43 const char AttestationFlow::kEnterpriseMachineKey[] = "attest-ent-machine"; |
| 44 |
| 45 AttestationFlow::AttestationFlow(cryptohome::AsyncMethodCaller* async_caller, |
| 46 CryptohomeClient* cryptohome_client, |
| 47 ServerProxy* server_proxy) |
| 48 : ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), |
| 49 async_caller_(async_caller), |
| 50 cryptohome_client_(cryptohome_client), |
| 51 server_proxy_(server_proxy) { |
| 52 } |
| 53 |
| 54 AttestationFlow::~AttestationFlow() { |
| 55 } |
| 56 |
| 57 void AttestationFlow::GetCertificate(const std::string& name, |
| 58 const CertificateCallback& callback) { |
| 59 // 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. |
| 61 base::Closure do_cert_request = base::Bind( |
| 62 &AttestationFlow::StartCertificateRequest, |
| 63 weak_factory_.GetWeakPtr(), |
| 64 name, |
| 65 callback); |
| 66 base::Closure on_enroll_failure = base::Bind(callback, false, ""); |
| 67 base::Closure do_enroll = base::Bind(&AttestationFlow::StartEnroll, |
| 68 weak_factory_.GetWeakPtr(), |
| 69 on_enroll_failure, |
| 70 do_cert_request); |
| 71 cryptohome_client_->TpmAttestationIsEnrolled(base::Bind( |
| 72 &DBusBoolRedirectCallback, |
| 73 do_cert_request, // If enrolled, proceed with cert request. |
| 74 do_enroll, // If not enrolled, initiate enrollment. |
| 75 on_enroll_failure)); |
| 76 } |
| 77 |
| 78 void AttestationFlow::StartEnroll(const base::Closure& on_failure, |
| 79 const base::Closure& next_task) { |
| 80 // Get the attestation service to create a Privacy CA enrollment request. |
| 81 async_caller_->AsyncTpmAttestationCreateEnrollRequest(base::Bind( |
| 82 &AttestationFlow::SendEnrollRequestToPCA, |
| 83 weak_factory_.GetWeakPtr(), |
| 84 on_failure, |
| 85 next_task)); |
| 86 } |
| 87 |
| 88 void AttestationFlow::SendEnrollRequestToPCA(const base::Closure& on_failure, |
| 89 const base::Closure& next_task, |
| 90 bool success, |
| 91 const std::string& data) { |
| 92 if (!success) { |
| 93 LOG(ERROR) << "Attestation: Failed to create enroll request."; |
| 94 if (!on_failure.is_null()) |
| 95 on_failure.Run(); |
| 96 return; |
| 97 } |
| 98 |
| 99 // Send the request to the Privacy CA. |
| 100 server_proxy_->SendEnrollRequest( |
| 101 data, |
| 102 base::Bind(&AttestationFlow::SendEnrollResponseToDaemon, |
| 103 weak_factory_.GetWeakPtr(), |
| 104 on_failure, |
| 105 next_task)); |
| 106 } |
| 107 |
| 108 void AttestationFlow::SendEnrollResponseToDaemon( |
| 109 const base::Closure& on_failure, |
| 110 const base::Closure& next_task, |
| 111 bool success, |
| 112 const std::string& data) { |
| 113 if (!success) { |
| 114 LOG(ERROR) << "Attestation: Enroll request failed."; |
| 115 if (!on_failure.is_null()) |
| 116 on_failure.Run(); |
| 117 return; |
| 118 } |
| 119 |
| 120 // Forward the response to the attestation service to complete enrollment. |
| 121 async_caller_->AsyncTpmAttestationEnroll( |
| 122 data, |
| 123 base::Bind(&AttestationFlow::OnEnrollComplete, |
| 124 weak_factory_.GetWeakPtr(), |
| 125 on_failure, |
| 126 next_task)); |
| 127 } |
| 128 |
| 129 void AttestationFlow::OnEnrollComplete(const base::Closure& on_failure, |
| 130 const base::Closure& next_task, |
| 131 bool success, |
| 132 cryptohome::MountError /*not_used*/) { |
| 133 if (!success) { |
| 134 LOG(ERROR) << "Attestation: Failed to complete enrollment."; |
| 135 if (!on_failure.is_null()) |
| 136 on_failure.Run(); |
| 137 return; |
| 138 } |
| 139 |
| 140 // Enrollment has successfully completed, we can move on to whatever is next. |
| 141 if (!next_task.is_null()) |
| 142 next_task.Run(); |
| 143 } |
| 144 |
| 145 void AttestationFlow::StartCertificateRequest( |
| 146 const std::string& name, |
| 147 const CertificateCallback& callback) { |
| 148 // Get the attestation service to create a Privacy CA certificate request. |
| 149 async_caller_->AsyncTpmAttestationCreateCertRequest( |
| 150 (name == kEnterpriseMachineKey), |
| 151 base::Bind(&AttestationFlow::SendCertificateRequestToPCA, |
| 152 weak_factory_.GetWeakPtr(), |
| 153 callback)); |
| 154 } |
| 155 |
| 156 void AttestationFlow::SendCertificateRequestToPCA( |
| 157 const CertificateCallback& callback, |
| 158 bool success, |
| 159 const std::string& data) { |
| 160 if (!success) { |
| 161 LOG(ERROR) << "Attestation: Failed to create certificate request."; |
| 162 if (!callback.is_null()) |
| 163 callback.Run(false, ""); |
| 164 return; |
| 165 } |
| 166 |
| 167 // Send the request to the Privacy CA. |
| 168 server_proxy_->SendCertificateRequest( |
| 169 data, |
| 170 base::Bind(&AttestationFlow::SendCertificateResponseToDaemon, |
| 171 weak_factory_.GetWeakPtr(), |
| 172 callback)); |
| 173 } |
| 174 |
| 175 void AttestationFlow::SendCertificateResponseToDaemon( |
| 176 const CertificateCallback& callback, |
| 177 bool success, |
| 178 const std::string& data) { |
| 179 if (!success) { |
| 180 LOG(ERROR) << "Attestation: Certificate request failed."; |
| 181 if (!callback.is_null()) |
| 182 callback.Run(false, ""); |
| 183 return; |
| 184 } |
| 185 |
| 186 // Forward the response to the attestation service to complete the operation. |
| 187 async_caller_->AsyncTpmAttestationFinishCertRequest(data, |
| 188 base::Bind(callback)); |
| 189 } |
| 190 |
| 191 } // namespace attestation |
| 192 } // namespace chromeos |
OLD | NEW |