Roll BoringSSL.
[chromium-blink-merge.git] / chromeos / cryptohome / async_method_caller.cc
blob5d9b844d720b26af2a2af2531ca8916dc52cfaf8
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.
5 #include "chromeos/cryptohome/async_method_caller.h"
7 #include "base/bind.h"
8 #include "base/containers/hash_tables.h"
9 #include "base/location.h"
10 #include "base/message_loop/message_loop_proxy.h"
11 #include "chromeos/dbus/cryptohome_client.h"
12 #include "chromeos/dbus/dbus_thread_manager.h"
14 using chromeos::DBusThreadManager;
16 namespace cryptohome {
18 namespace {
20 AsyncMethodCaller* g_async_method_caller = NULL;
22 // The implementation of AsyncMethodCaller
23 class AsyncMethodCallerImpl : public AsyncMethodCaller {
24 public:
25 AsyncMethodCallerImpl() : weak_ptr_factory_(this) {
26 DBusThreadManager::Get()->GetCryptohomeClient()->SetAsyncCallStatusHandlers(
27 base::Bind(&AsyncMethodCallerImpl::HandleAsyncResponse,
28 weak_ptr_factory_.GetWeakPtr()),
29 base::Bind(&AsyncMethodCallerImpl::HandleAsyncDataResponse,
30 weak_ptr_factory_.GetWeakPtr()));
33 virtual ~AsyncMethodCallerImpl() {
34 DBusThreadManager::Get()->GetCryptohomeClient()->
35 ResetAsyncCallStatusHandlers();
38 virtual void AsyncCheckKey(const std::string& user_email,
39 const std::string& passhash,
40 Callback callback) OVERRIDE {
41 DBusThreadManager::Get()->GetCryptohomeClient()->
42 AsyncCheckKey(user_email, passhash, base::Bind(
43 &AsyncMethodCallerImpl::RegisterAsyncCallback,
44 weak_ptr_factory_.GetWeakPtr(),
45 callback,
46 "Couldn't initiate async check of user's key."));
49 virtual void AsyncMigrateKey(const std::string& user_email,
50 const std::string& old_hash,
51 const std::string& new_hash,
52 Callback callback) OVERRIDE {
53 DBusThreadManager::Get()->GetCryptohomeClient()->
54 AsyncMigrateKey(user_email, old_hash, new_hash, base::Bind(
55 &AsyncMethodCallerImpl::RegisterAsyncCallback,
56 weak_ptr_factory_.GetWeakPtr(),
57 callback,
58 "Couldn't initiate aync migration of user's key"));
61 virtual void AsyncMount(const std::string& user_email,
62 const std::string& passhash,
63 int flags,
64 Callback callback) OVERRIDE {
65 DBusThreadManager::Get()->GetCryptohomeClient()->
66 AsyncMount(user_email, passhash, flags, base::Bind(
67 &AsyncMethodCallerImpl::RegisterAsyncCallback,
68 weak_ptr_factory_.GetWeakPtr(),
69 callback,
70 "Couldn't initiate async mount of cryptohome."));
73 virtual void AsyncAddKey(const std::string& user_email,
74 const std::string& passhash,
75 const std::string& new_passhash,
76 Callback callback) OVERRIDE {
77 DBusThreadManager::Get()->GetCryptohomeClient()->
78 AsyncAddKey(user_email, passhash, new_passhash, base::Bind(
79 &AsyncMethodCallerImpl::RegisterAsyncCallback,
80 weak_ptr_factory_.GetWeakPtr(),
81 callback,
82 "Couldn't initiate async key addition."));
85 virtual void AsyncMountGuest(Callback callback) OVERRIDE {
86 DBusThreadManager::Get()->GetCryptohomeClient()->
87 AsyncMountGuest(base::Bind(
88 &AsyncMethodCallerImpl::RegisterAsyncCallback,
89 weak_ptr_factory_.GetWeakPtr(),
90 callback,
91 "Couldn't initiate async mount of cryptohome."));
94 virtual void AsyncMountPublic(const std::string& public_mount_id,
95 int flags,
96 Callback callback) OVERRIDE {
97 DBusThreadManager::Get()->GetCryptohomeClient()->
98 AsyncMountPublic(public_mount_id, flags, base::Bind(
99 &AsyncMethodCallerImpl::RegisterAsyncCallback,
100 weak_ptr_factory_.GetWeakPtr(),
101 callback,
102 "Couldn't initiate async mount public of cryptohome."));
105 virtual void AsyncRemove(const std::string& user_email,
106 Callback callback) OVERRIDE {
107 DBusThreadManager::Get()->GetCryptohomeClient()->
108 AsyncRemove(user_email, base::Bind(
109 &AsyncMethodCallerImpl::RegisterAsyncCallback,
110 weak_ptr_factory_.GetWeakPtr(),
111 callback,
112 "Couldn't initiate async removal of cryptohome."));
115 virtual void AsyncTpmAttestationCreateEnrollRequest(
116 chromeos::attestation::PrivacyCAType pca_type,
117 const DataCallback& callback) OVERRIDE {
118 DBusThreadManager::Get()->GetCryptohomeClient()->
119 AsyncTpmAttestationCreateEnrollRequest(pca_type, base::Bind(
120 &AsyncMethodCallerImpl::RegisterAsyncDataCallback,
121 weak_ptr_factory_.GetWeakPtr(),
122 callback,
123 "Couldn't initiate async attestation enroll request."));
126 virtual void AsyncTpmAttestationEnroll(
127 chromeos::attestation::PrivacyCAType pca_type,
128 const std::string& pca_response,
129 const Callback& callback) OVERRIDE {
130 DBusThreadManager::Get()->GetCryptohomeClient()->
131 AsyncTpmAttestationEnroll(pca_type, pca_response, base::Bind(
132 &AsyncMethodCallerImpl::RegisterAsyncCallback,
133 weak_ptr_factory_.GetWeakPtr(),
134 callback,
135 "Couldn't initiate async attestation enroll."));
138 virtual void AsyncTpmAttestationCreateCertRequest(
139 chromeos::attestation::PrivacyCAType pca_type,
140 chromeos::attestation::AttestationCertificateProfile certificate_profile,
141 const std::string& user_id,
142 const std::string& request_origin,
143 const DataCallback& callback) OVERRIDE {
144 DBusThreadManager::Get()->GetCryptohomeClient()->
145 AsyncTpmAttestationCreateCertRequest(
146 pca_type,
147 certificate_profile,
148 user_id,
149 request_origin,
150 base::Bind(&AsyncMethodCallerImpl::RegisterAsyncDataCallback,
151 weak_ptr_factory_.GetWeakPtr(),
152 callback,
153 "Couldn't initiate async attestation cert request."));
156 virtual void AsyncTpmAttestationFinishCertRequest(
157 const std::string& pca_response,
158 chromeos::attestation::AttestationKeyType key_type,
159 const std::string& user_id,
160 const std::string& key_name,
161 const DataCallback& callback) OVERRIDE {
162 DBusThreadManager::Get()->GetCryptohomeClient()->
163 AsyncTpmAttestationFinishCertRequest(
164 pca_response,
165 key_type,
166 user_id,
167 key_name,
168 base::Bind(
169 &AsyncMethodCallerImpl::RegisterAsyncDataCallback,
170 weak_ptr_factory_.GetWeakPtr(),
171 callback,
172 "Couldn't initiate async attestation finish cert request."));
175 virtual void TpmAttestationRegisterKey(
176 chromeos::attestation::AttestationKeyType key_type,
177 const std::string& user_id,
178 const std::string& key_name,
179 const Callback& callback) OVERRIDE {
180 DBusThreadManager::Get()->GetCryptohomeClient()->
181 TpmAttestationRegisterKey(
182 key_type,
183 user_id,
184 key_name,
185 base::Bind(
186 &AsyncMethodCallerImpl::RegisterAsyncCallback,
187 weak_ptr_factory_.GetWeakPtr(),
188 callback,
189 "Couldn't initiate async attestation register key."));
192 virtual void TpmAttestationSignEnterpriseChallenge(
193 chromeos::attestation::AttestationKeyType key_type,
194 const std::string& user_id,
195 const std::string& key_name,
196 const std::string& domain,
197 const std::string& device_id,
198 chromeos::attestation::AttestationChallengeOptions options,
199 const std::string& challenge,
200 const DataCallback& callback) OVERRIDE {
201 DBusThreadManager::Get()->GetCryptohomeClient()->
202 TpmAttestationSignEnterpriseChallenge(
203 key_type,
204 user_id,
205 key_name,
206 domain,
207 device_id,
208 options,
209 challenge,
210 base::Bind(
211 &AsyncMethodCallerImpl::RegisterAsyncDataCallback,
212 weak_ptr_factory_.GetWeakPtr(),
213 callback,
214 "Couldn't initiate async attestation enterprise challenge."));
217 virtual void TpmAttestationSignSimpleChallenge(
218 chromeos::attestation::AttestationKeyType key_type,
219 const std::string& user_id,
220 const std::string& key_name,
221 const std::string& challenge,
222 const DataCallback& callback) OVERRIDE {
223 DBusThreadManager::Get()->GetCryptohomeClient()->
224 TpmAttestationSignSimpleChallenge(
225 key_type,
226 user_id,
227 key_name,
228 challenge,
229 base::Bind(
230 &AsyncMethodCallerImpl::RegisterAsyncDataCallback,
231 weak_ptr_factory_.GetWeakPtr(),
232 callback,
233 "Couldn't initiate async attestation simple challenge."));
236 virtual void AsyncGetSanitizedUsername(
237 const std::string& user,
238 const DataCallback& callback) OVERRIDE {
239 DBusThreadManager::Get()->GetCryptohomeClient()->
240 GetSanitizedUsername(user,
241 base::Bind(
242 &AsyncMethodCallerImpl::GetSanitizedUsernameCallback,
243 weak_ptr_factory_.GetWeakPtr(),
244 callback));
247 virtual void GetSanitizedUsernameCallback(
248 const DataCallback& callback,
249 const chromeos::DBusMethodCallStatus call_status,
250 const std::string& result) {
251 callback.Run(true, result);
254 private:
255 struct CallbackElement {
256 CallbackElement() {}
257 explicit CallbackElement(const AsyncMethodCaller::Callback& callback)
258 : callback(callback),
259 proxy(base::MessageLoopProxy::current()) {
261 AsyncMethodCaller::Callback callback;
262 scoped_refptr<base::MessageLoopProxy> proxy;
265 struct DataCallbackElement {
266 DataCallbackElement() {}
267 explicit DataCallbackElement(
268 const AsyncMethodCaller::DataCallback& callback)
269 : data_callback(callback),
270 proxy(base::MessageLoopProxy::current()) {
272 AsyncMethodCaller::DataCallback data_callback;
273 scoped_refptr<base::MessageLoopProxy> proxy;
276 typedef base::hash_map<int, CallbackElement> CallbackMap;
277 typedef base::hash_map<int, DataCallbackElement> DataCallbackMap;
279 // Handles the response for async calls.
280 // Below is described how async calls work.
281 // 1. CryptohomeClient::AsyncXXX returns "async ID".
282 // 2. RegisterAsyncCallback registers the "async ID" with the user-provided
283 // callback.
284 // 3. Cryptohome will return the result asynchronously as a signal with
285 // "async ID"
286 // 4. "HandleAsyncResponse" handles the result signal and call the registered
287 // callback associated with the "async ID".
288 void HandleAsyncResponse(int async_id, bool return_status, int return_code) {
289 const CallbackMap::iterator it = callback_map_.find(async_id);
290 if (it == callback_map_.end()) {
291 LOG(ERROR) << "Received signal for unknown async_id " << async_id;
292 return;
294 it->second.proxy->PostTask(FROM_HERE,
295 base::Bind(it->second.callback,
296 return_status,
297 static_cast<MountError>(return_code)));
298 callback_map_.erase(it);
301 // Similar to HandleAsyncResponse but for signals with a raw data payload.
302 void HandleAsyncDataResponse(int async_id,
303 bool return_status,
304 const std::string& return_data) {
305 const DataCallbackMap::iterator it = data_callback_map_.find(async_id);
306 if (it == data_callback_map_.end()) {
307 LOG(ERROR) << "Received signal for unknown async_id " << async_id;
308 return;
310 it->second.proxy->PostTask(FROM_HERE,
311 base::Bind(it->second.data_callback, return_status, return_data));
312 data_callback_map_.erase(it);
315 // Registers a callback which is called when the result for AsyncXXX is ready.
316 void RegisterAsyncCallback(
317 Callback callback, const char* error, int async_id) {
318 if (async_id == 0) {
319 LOG(ERROR) << error;
320 return;
322 VLOG(1) << "Adding handler for " << async_id;
323 DCHECK_EQ(callback_map_.count(async_id), 0U);
324 DCHECK_EQ(data_callback_map_.count(async_id), 0U);
325 callback_map_[async_id] = CallbackElement(callback);
328 // Registers a callback which is called when the result for AsyncXXX is ready.
329 void RegisterAsyncDataCallback(
330 DataCallback callback, const char* error, int async_id) {
331 if (async_id == 0) {
332 LOG(ERROR) << error;
333 return;
335 VLOG(1) << "Adding handler for " << async_id;
336 DCHECK_EQ(callback_map_.count(async_id), 0U);
337 DCHECK_EQ(data_callback_map_.count(async_id), 0U);
338 data_callback_map_[async_id] = DataCallbackElement(callback);
341 base::WeakPtrFactory<AsyncMethodCallerImpl> weak_ptr_factory_;
342 CallbackMap callback_map_;
343 DataCallbackMap data_callback_map_;
345 DISALLOW_COPY_AND_ASSIGN(AsyncMethodCallerImpl);
348 } // namespace
350 // static
351 void AsyncMethodCaller::Initialize() {
352 if (g_async_method_caller) {
353 LOG(WARNING) << "AsyncMethodCaller was already initialized";
354 return;
356 g_async_method_caller = new AsyncMethodCallerImpl();
357 VLOG(1) << "AsyncMethodCaller initialized";
360 // static
361 void AsyncMethodCaller::InitializeForTesting(
362 AsyncMethodCaller* async_method_caller) {
363 if (g_async_method_caller) {
364 LOG(WARNING) << "AsyncMethodCaller was already initialized";
365 return;
367 g_async_method_caller = async_method_caller;
368 VLOG(1) << "AsyncMethodCaller initialized";
371 // static
372 void AsyncMethodCaller::Shutdown() {
373 if (!g_async_method_caller) {
374 LOG(WARNING) << "AsyncMethodCaller::Shutdown() called with NULL manager";
375 return;
377 delete g_async_method_caller;
378 g_async_method_caller = NULL;
379 VLOG(1) << "AsyncMethodCaller Shutdown completed";
382 // static
383 AsyncMethodCaller* AsyncMethodCaller::GetInstance() {
384 return g_async_method_caller;
387 } // namespace cryptohome