15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/cryptohome/async_method_caller.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/cryptohome_client.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using chromeos::DBusThreadManager;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace cryptohome {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AsyncMethodCaller* g_async_method_caller = NULL;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The implementation of AsyncMethodCaller
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AsyncMethodCallerImpl : public AsyncMethodCaller {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AsyncMethodCallerImpl() : weak_ptr_factory_(this) {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->SetAsyncCallStatusHandlers(
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AsyncMethodCallerImpl::HandleAsyncResponse,
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()),
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(&AsyncMethodCallerImpl::HandleAsyncDataResponse,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   weak_ptr_factory_.GetWeakPtr()));
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AsyncMethodCallerImpl() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ResetAsyncCallStatusHandlers();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AsyncCheckKey(const std::string& user_email,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::string& passhash,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             Callback callback) OVERRIDE {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AsyncCheckKey(user_email, passhash, base::Bind(
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &AsyncMethodCallerImpl::RegisterAsyncCallback,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            callback,
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "Couldn't initiate async check of user's key."));
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AsyncMigrateKey(const std::string& user_email,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const std::string& old_hash,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const std::string& new_hash,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               Callback callback) OVERRIDE {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AsyncMigrateKey(user_email, old_hash, new_hash, base::Bind(
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &AsyncMethodCallerImpl::RegisterAsyncCallback,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            callback,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "Couldn't initiate aync migration of user's key"));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AsyncMount(const std::string& user_email,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const std::string& passhash,
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                          int flags,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          Callback callback) OVERRIDE {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        AsyncMount(user_email, passhash, flags, base::Bind(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &AsyncMethodCallerImpl::RegisterAsyncCallback,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            callback,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "Couldn't initiate async mount of cryptohome."));
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual void AsyncAddKey(const std::string& user_email,
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                           const std::string& passhash,
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                           const std::string& new_passhash,
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                           Callback callback) OVERRIDE {
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DBusThreadManager::Get()->GetCryptohomeClient()->
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        AsyncAddKey(user_email, passhash, new_passhash, base::Bind(
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            &AsyncMethodCallerImpl::RegisterAsyncCallback,
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            weak_ptr_factory_.GetWeakPtr(),
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            callback,
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch            "Couldn't initiate async key addition."));
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AsyncMountGuest(Callback callback) OVERRIDE {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AsyncMountGuest(base::Bind(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &AsyncMethodCallerImpl::RegisterAsyncCallback,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            callback,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "Couldn't initiate async mount of cryptohome."));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual void AsyncMountPublic(const std::string& public_mount_id,
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                int flags,
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                Callback callback) OVERRIDE {
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        AsyncMountPublic(public_mount_id, flags, base::Bind(
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            &AsyncMethodCallerImpl::RegisterAsyncCallback,
100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            callback,
102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)            "Couldn't initiate async mount public of cryptohome."));
103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void AsyncRemove(const std::string& user_email,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           Callback callback) OVERRIDE {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AsyncRemove(user_email, base::Bind(
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &AsyncMethodCallerImpl::RegisterAsyncCallback,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            callback,
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "Couldn't initiate async removal of cryptohome."));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AsyncTpmAttestationCreateEnrollRequest(
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      chromeos::attestation::PrivacyCAType pca_type,
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const DataCallback& callback) OVERRIDE {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        AsyncTpmAttestationCreateEnrollRequest(pca_type, base::Bind(
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            &AsyncMethodCallerImpl::RegisterAsyncDataCallback,
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            callback,
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            "Couldn't initiate async attestation enroll request."));
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void AsyncTpmAttestationEnroll(
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      chromeos::attestation::PrivacyCAType pca_type,
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const std::string& pca_response,
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      const Callback& callback) OVERRIDE {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        AsyncTpmAttestationEnroll(pca_type, pca_response, base::Bind(
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            &AsyncMethodCallerImpl::RegisterAsyncCallback,
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            callback,
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            "Couldn't initiate async attestation enroll."));
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AsyncTpmAttestationCreateCertRequest(
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      chromeos::attestation::PrivacyCAType pca_type,
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      chromeos::attestation::AttestationCertificateProfile certificate_profile,
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& user_id,
1423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const std::string& request_origin,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const DataCallback& callback) OVERRIDE {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        AsyncTpmAttestationCreateCertRequest(
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            pca_type,
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            certificate_profile,
1488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            user_id,
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)            request_origin,
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            base::Bind(&AsyncMethodCallerImpl::RegisterAsyncDataCallback,
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       weak_ptr_factory_.GetWeakPtr(),
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       callback,
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       "Couldn't initiate async attestation cert request."));
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AsyncTpmAttestationFinishCertRequest(
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& pca_response,
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chromeos::attestation::AttestationKeyType key_type,
1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& user_id,
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& key_name,
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const DataCallback& callback) OVERRIDE {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        AsyncTpmAttestationFinishCertRequest(
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            pca_response,
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            key_type,
1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            user_id,
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            key_name,
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            base::Bind(
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                &AsyncMethodCallerImpl::RegisterAsyncDataCallback,
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                weak_ptr_factory_.GetWeakPtr(),
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                callback,
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                "Couldn't initiate async attestation finish cert request."));
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void TpmAttestationRegisterKey(
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chromeos::attestation::AttestationKeyType key_type,
1778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& user_id,
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& key_name,
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const Callback& callback) OVERRIDE {
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        TpmAttestationRegisterKey(
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            key_type,
1838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            user_id,
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            key_name,
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            base::Bind(
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                &AsyncMethodCallerImpl::RegisterAsyncCallback,
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                weak_ptr_factory_.GetWeakPtr(),
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                callback,
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                "Couldn't initiate async attestation register key."));
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void TpmAttestationSignEnterpriseChallenge(
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chromeos::attestation::AttestationKeyType key_type,
1948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& user_id,
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& key_name,
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& domain,
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& device_id,
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chromeos::attestation::AttestationChallengeOptions options,
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& challenge,
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const DataCallback& callback) OVERRIDE {
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        TpmAttestationSignEnterpriseChallenge(
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            key_type,
2048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            user_id,
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            key_name,
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            domain,
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            device_id,
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            options,
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            challenge,
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            base::Bind(
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                &AsyncMethodCallerImpl::RegisterAsyncDataCallback,
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                weak_ptr_factory_.GetWeakPtr(),
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                callback,
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                "Couldn't initiate async attestation enterprise challenge."));
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void TpmAttestationSignSimpleChallenge(
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      chromeos::attestation::AttestationKeyType key_type,
2198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      const std::string& user_id,
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& key_name,
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& challenge,
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const DataCallback& callback) OVERRIDE {
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        TpmAttestationSignSimpleChallenge(
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            key_type,
2268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            user_id,
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            key_name,
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            challenge,
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            base::Bind(
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                &AsyncMethodCallerImpl::RegisterAsyncDataCallback,
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                weak_ptr_factory_.GetWeakPtr(),
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                callback,
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                "Couldn't initiate async attestation simple challenge."));
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AsyncGetSanitizedUsername(
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& user,
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const DataCallback& callback) OVERRIDE {
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        GetSanitizedUsername(user,
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            &AsyncMethodCallerImpl::GetSanitizedUsernameCallback,
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            weak_ptr_factory_.GetWeakPtr(),
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            callback));
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void GetSanitizedUsernameCallback(
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const DataCallback& callback,
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const chromeos::DBusMethodCallStatus call_status,
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& result) {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    callback.Run(true, result);
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct CallbackElement {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CallbackElement() {}
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    explicit CallbackElement(const AsyncMethodCaller::Callback& callback)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : callback(callback),
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          proxy(base::MessageLoopProxy::current()) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AsyncMethodCaller::Callback callback;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<base::MessageLoopProxy> proxy;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct DataCallbackElement {
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DataCallbackElement() {}
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    explicit DataCallbackElement(
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        const AsyncMethodCaller::DataCallback& callback)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        : data_callback(callback),
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          proxy(base::MessageLoopProxy::current()) {
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AsyncMethodCaller::DataCallback data_callback;
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_refptr<base::MessageLoopProxy> proxy;
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::hash_map<int, CallbackElement> CallbackMap;
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::hash_map<int, DataCallbackElement> DataCallbackMap;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Handles the response for async calls.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Below is described how async calls work.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 1. CryptohomeClient::AsyncXXX returns "async ID".
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 2. RegisterAsyncCallback registers the "async ID" with the user-provided
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    callback.
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 3. Cryptohome will return the result asynchronously as a signal with
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    "async ID"
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 4. "HandleAsyncResponse" handles the result signal and call the registered
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    callback associated with the "async ID".
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleAsyncResponse(int async_id, bool return_status, int return_code) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CallbackMap::iterator it = callback_map_.find(async_id);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it == callback_map_.end()) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Received signal for unknown async_id " << async_id;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    it->second.proxy->PostTask(FROM_HERE,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(it->second.callback,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   return_status,
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   static_cast<MountError>(return_code)));
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_map_.erase(it);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Similar to HandleAsyncResponse but for signals with a raw data payload.
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void HandleAsyncDataResponse(int async_id,
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               bool return_status,
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const std::string& return_data) {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const DataCallbackMap::iterator it = data_callback_map_.find(async_id);
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (it == data_callback_map_.end()) {
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << "Received signal for unknown async_id " << async_id;
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    it->second.proxy->PostTask(FROM_HERE,
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::Bind(it->second.data_callback, return_status, return_data));
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_callback_map_.erase(it);
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Registers a callback which is called when the result for AsyncXXX is ready.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterAsyncCallback(
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Callback callback, const char* error, int async_id) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (async_id == 0) {
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << error;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    VLOG(1) << "Adding handler for " << async_id;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK_EQ(callback_map_.count(async_id), 0U);
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_EQ(data_callback_map_.count(async_id), 0U);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    callback_map_[async_id] = CallbackElement(callback);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Registers a callback which is called when the result for AsyncXXX is ready.
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void RegisterAsyncDataCallback(
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DataCallback callback, const char* error, int async_id) {
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (async_id == 0) {
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << error;
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    VLOG(1) << "Adding handler for " << async_id;
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_EQ(callback_map_.count(async_id), 0U);
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK_EQ(data_callback_map_.count(async_id), 0U);
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    data_callback_map_[async_id] = DataCallbackElement(callback);
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<AsyncMethodCallerImpl> weak_ptr_factory_;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CallbackMap callback_map_;
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DataCallbackMap data_callback_map_;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AsyncMethodCallerImpl);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AsyncMethodCaller::Initialize() {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_async_method_caller) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "AsyncMethodCaller was already initialized";
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_async_method_caller = new AsyncMethodCallerImpl();
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "AsyncMethodCaller initialized";
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AsyncMethodCaller::InitializeForTesting(
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AsyncMethodCaller* async_method_caller) {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (g_async_method_caller) {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "AsyncMethodCaller was already initialized";
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_async_method_caller = async_method_caller;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "AsyncMethodCaller initialized";
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AsyncMethodCaller::Shutdown() {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_async_method_caller) {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "AsyncMethodCaller::Shutdown() called with NULL manager";
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete g_async_method_caller;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_async_method_caller = NULL;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "AsyncMethodCaller Shutdown completed";
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AsyncMethodCaller* AsyncMethodCaller::GetInstance() {
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_async_method_caller;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace cryptohome
388