fake_cryptohome_client.cc revision 8bcbed890bc3ce4d7a057a8f32cab53fa534672e
1// Copyright 2013 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/dbus/fake_cryptohome_client.h"
6
7#include "base/bind.h"
8#include "base/location.h"
9#include "base/message_loop/message_loop.h"
10#include "crypto/nss_util.h"
11#include "third_party/cros_system_api/dbus/service_constants.h"
12
13namespace chromeos {
14
15FakeCryptohomeClient::FakeCryptohomeClient()
16    : service_is_available_(true),
17      async_call_id_(1),
18      tpm_is_ready_counter_(0),
19      unmount_result_(true),
20      locked_(false),
21      weak_ptr_factory_(this) {}
22
23FakeCryptohomeClient::~FakeCryptohomeClient() {}
24
25void FakeCryptohomeClient::Init(dbus::Bus* bus) {
26}
27
28void FakeCryptohomeClient::SetAsyncCallStatusHandlers(
29    const AsyncCallStatusHandler& handler,
30    const AsyncCallStatusWithDataHandler& data_handler) {
31  async_call_status_handler_ = handler;
32  async_call_status_data_handler_ = data_handler;
33}
34
35void FakeCryptohomeClient::ResetAsyncCallStatusHandlers() {
36  async_call_status_handler_.Reset();
37  async_call_status_data_handler_.Reset();
38}
39
40void FakeCryptohomeClient::WaitForServiceToBeAvailable(
41    const WaitForServiceToBeAvailableCallback& callback) {
42  if (service_is_available_) {
43    base::MessageLoop::current()->PostTask(FROM_HERE,
44                                           base::Bind(callback, true));
45  } else {
46    pending_wait_for_service_to_be_available_callbacks_.push_back(callback);
47  }
48}
49
50void FakeCryptohomeClient::IsMounted(
51    const BoolDBusMethodCallback& callback) {
52  base::MessageLoop::current()->PostTask(
53      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
54}
55
56bool FakeCryptohomeClient::Unmount(bool* success) {
57  *success = unmount_result_;
58  return true;
59}
60
61void FakeCryptohomeClient::AsyncCheckKey(
62    const std::string& username,
63    const std::string& key,
64    const AsyncMethodCallback& callback) {
65  ReturnAsyncMethodResult(callback, false);
66}
67
68void FakeCryptohomeClient::AsyncMigrateKey(
69    const std::string& username,
70    const std::string& from_key,
71    const std::string& to_key,
72    const AsyncMethodCallback& callback) {
73  ReturnAsyncMethodResult(callback, false);
74}
75
76void FakeCryptohomeClient::AsyncRemove(
77    const std::string& username,
78    const AsyncMethodCallback& callback) {
79  ReturnAsyncMethodResult(callback, false);
80}
81
82bool FakeCryptohomeClient::GetSystemSalt(std::vector<uint8>* salt) {
83  *salt = GetStubSystemSalt();
84  return true;
85}
86
87void FakeCryptohomeClient::GetSanitizedUsername(
88    const std::string& username,
89    const StringDBusMethodCallback& callback) {
90  // Even for stub implementation we have to return different values so that
91  // multi-profiles would work.
92  std::string sanitized_username = GetStubSanitizedUsername(username);
93  base::MessageLoop::current()->PostTask(
94      FROM_HERE,
95      base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, sanitized_username));
96}
97
98std::string FakeCryptohomeClient::BlockingGetSanitizedUsername(
99    const std::string& username) {
100  return GetStubSanitizedUsername(username);
101}
102
103void FakeCryptohomeClient::AsyncMount(const std::string& username,
104                                          const std::string& key,
105                                          int flags,
106                                          const AsyncMethodCallback& callback) {
107  ReturnAsyncMethodResult(callback, false);
108}
109
110void FakeCryptohomeClient::AsyncAddKey(
111    const std::string& username,
112    const std::string& key,
113    const std::string& new_key,
114    const AsyncMethodCallback& callback) {
115  ReturnAsyncMethodResult(callback, false);
116}
117
118void FakeCryptohomeClient::AsyncMountGuest(
119    const AsyncMethodCallback& callback) {
120  ReturnAsyncMethodResult(callback, false);
121}
122
123void FakeCryptohomeClient::AsyncMountPublic(
124    const std::string& public_mount_id,
125    int flags,
126    const AsyncMethodCallback& callback) {
127  ReturnAsyncMethodResult(callback, false);
128}
129
130void FakeCryptohomeClient::TpmIsReady(
131    const BoolDBusMethodCallback& callback) {
132  base::MessageLoop::current()->PostTask(
133      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
134}
135
136void FakeCryptohomeClient::TpmIsEnabled(
137    const BoolDBusMethodCallback& callback) {
138  base::MessageLoop::current()->PostTask(
139      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
140}
141
142bool FakeCryptohomeClient::CallTpmIsEnabledAndBlock(bool* enabled) {
143  *enabled = true;
144  return true;
145}
146
147void FakeCryptohomeClient::TpmGetPassword(
148    const StringDBusMethodCallback& callback) {
149  const char kStubTpmPassword[] = "Stub-TPM-password";
150  base::MessageLoop::current()->PostTask(
151      FROM_HERE,
152      base::Bind(callback, DBUS_METHOD_CALL_SUCCESS,
153                 std::string(kStubTpmPassword)));
154}
155
156void FakeCryptohomeClient::TpmIsOwned(
157    const BoolDBusMethodCallback& callback) {
158  base::MessageLoop::current()->PostTask(
159      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
160}
161
162bool FakeCryptohomeClient::CallTpmIsOwnedAndBlock(bool* owned) {
163  *owned = true;
164  return true;
165}
166
167void FakeCryptohomeClient::TpmIsBeingOwned(
168    const BoolDBusMethodCallback& callback) {
169  base::MessageLoop::current()->PostTask(
170      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
171}
172
173bool FakeCryptohomeClient::CallTpmIsBeingOwnedAndBlock(bool* owning) {
174  *owning = true;
175  return true;
176}
177
178void FakeCryptohomeClient::TpmCanAttemptOwnership(
179    const VoidDBusMethodCallback& callback) {
180  base::MessageLoop::current()->PostTask(
181      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
182}
183
184void FakeCryptohomeClient::TpmClearStoredPassword(
185    const VoidDBusMethodCallback& callback) {
186  base::MessageLoop::current()->PostTask(
187      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS));
188}
189
190bool FakeCryptohomeClient::CallTpmClearStoredPasswordAndBlock() {
191  return true;
192}
193
194void FakeCryptohomeClient::Pkcs11IsTpmTokenReady(
195    const BoolDBusMethodCallback& callback) {
196  base::MessageLoop::current()->PostTask(
197      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
198}
199
200void FakeCryptohomeClient::Pkcs11GetTpmTokenInfo(
201    const Pkcs11GetTpmTokenInfoCallback& callback) {
202  const char kStubUserPin[] = "012345";
203  const int kStubSlot = 0;
204  base::MessageLoop::current()->PostTask(
205      FROM_HERE,
206      base::Bind(callback,
207                 DBUS_METHOD_CALL_SUCCESS,
208                 std::string(crypto::kTestTPMTokenName),
209                 std::string(kStubUserPin),
210                 kStubSlot));
211}
212
213void FakeCryptohomeClient::Pkcs11GetTpmTokenInfoForUser(
214    const std::string& username,
215    const Pkcs11GetTpmTokenInfoCallback& callback) {
216  Pkcs11GetTpmTokenInfo(callback);
217}
218
219bool FakeCryptohomeClient::InstallAttributesGet(const std::string& name,
220                                                    std::vector<uint8>* value,
221                                                    bool* successful) {
222  if (install_attrs_.find(name) != install_attrs_.end()) {
223    *value = install_attrs_[name];
224    *successful = true;
225  } else {
226    value->clear();
227    *successful = false;
228  }
229  return true;
230}
231
232bool FakeCryptohomeClient::InstallAttributesSet(
233    const std::string& name,
234    const std::vector<uint8>& value,
235    bool* successful) {
236  install_attrs_[name] = value;
237  *successful = true;
238  return true;
239}
240
241bool FakeCryptohomeClient::InstallAttributesFinalize(bool* successful) {
242  locked_ = true;
243  *successful = true;
244  return true;
245}
246
247void FakeCryptohomeClient::InstallAttributesIsReady(
248    const BoolDBusMethodCallback& callback) {
249  base::MessageLoop::current()->PostTask(
250      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
251}
252
253bool FakeCryptohomeClient::InstallAttributesIsInvalid(bool* is_invalid) {
254  *is_invalid = false;
255  return true;
256}
257
258bool FakeCryptohomeClient::InstallAttributesIsFirstInstall(
259    bool* is_first_install) {
260  *is_first_install = !locked_;
261  return true;
262}
263
264void FakeCryptohomeClient::TpmAttestationIsPrepared(
265    const BoolDBusMethodCallback& callback) {
266  base::MessageLoop::current()->PostTask(
267      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
268}
269
270void FakeCryptohomeClient::TpmAttestationIsEnrolled(
271    const BoolDBusMethodCallback& callback) {
272  base::MessageLoop::current()->PostTask(
273      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true));
274}
275
276void FakeCryptohomeClient::AsyncTpmAttestationCreateEnrollRequest(
277    const AsyncMethodCallback& callback) {
278  ReturnAsyncMethodResult(callback, true);
279}
280
281void FakeCryptohomeClient::AsyncTpmAttestationEnroll(
282    const std::string& pca_response,
283    const AsyncMethodCallback& callback) {
284  ReturnAsyncMethodResult(callback, false);
285}
286
287void FakeCryptohomeClient::AsyncTpmAttestationCreateCertRequest(
288    attestation::AttestationCertificateProfile certificate_profile,
289    const std::string& user_id,
290    const std::string& request_origin,
291    const AsyncMethodCallback& callback) {
292  ReturnAsyncMethodResult(callback, true);
293}
294
295void FakeCryptohomeClient::AsyncTpmAttestationFinishCertRequest(
296    const std::string& pca_response,
297    attestation::AttestationKeyType key_type,
298    const std::string& user_id,
299    const std::string& key_name,
300    const AsyncMethodCallback& callback) {
301  ReturnAsyncMethodResult(callback, true);
302}
303
304void FakeCryptohomeClient::TpmAttestationDoesKeyExist(
305    attestation::AttestationKeyType key_type,
306    const std::string& user_id,
307    const std::string& key_name,
308    const BoolDBusMethodCallback& callback) {
309  base::MessageLoop::current()->PostTask(
310      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
311}
312
313void FakeCryptohomeClient::TpmAttestationGetCertificate(
314    attestation::AttestationKeyType key_type,
315    const std::string& user_id,
316    const std::string& key_name,
317    const DataMethodCallback& callback) {
318  base::MessageLoop::current()->PostTask(
319      FROM_HERE,
320      base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
321}
322
323void FakeCryptohomeClient::TpmAttestationGetPublicKey(
324    attestation::AttestationKeyType key_type,
325    const std::string& user_id,
326    const std::string& key_name,
327    const DataMethodCallback& callback) {
328  base::MessageLoop::current()->PostTask(
329      FROM_HERE,
330      base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
331}
332
333void FakeCryptohomeClient::TpmAttestationRegisterKey(
334    attestation::AttestationKeyType key_type,
335    const std::string& user_id,
336    const std::string& key_name,
337    const AsyncMethodCallback& callback) {
338  ReturnAsyncMethodResult(callback, true);
339}
340
341void FakeCryptohomeClient::TpmAttestationSignEnterpriseChallenge(
342    attestation::AttestationKeyType key_type,
343    const std::string& user_id,
344    const std::string& key_name,
345    const std::string& domain,
346    const std::string& device_id,
347    attestation::AttestationChallengeOptions options,
348    const std::string& challenge,
349    const AsyncMethodCallback& callback) {
350  ReturnAsyncMethodResult(callback, true);
351}
352
353void FakeCryptohomeClient::TpmAttestationSignSimpleChallenge(
354    attestation::AttestationKeyType key_type,
355    const std::string& user_id,
356    const std::string& key_name,
357    const std::string& challenge,
358    const AsyncMethodCallback& callback) {
359  ReturnAsyncMethodResult(callback, true);
360}
361
362void FakeCryptohomeClient::TpmAttestationGetKeyPayload(
363    attestation::AttestationKeyType key_type,
364    const std::string& user_id,
365    const std::string& key_name,
366    const DataMethodCallback& callback) {
367  base::MessageLoop::current()->PostTask(
368      FROM_HERE,
369      base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false, std::string()));
370}
371
372void FakeCryptohomeClient::TpmAttestationSetKeyPayload(
373    attestation::AttestationKeyType key_type,
374    const std::string& user_id,
375    const std::string& key_name,
376    const std::string& payload,
377    const BoolDBusMethodCallback& callback) {
378  base::MessageLoop::current()->PostTask(
379      FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, false));
380}
381
382void FakeCryptohomeClient::SetServiceIsAvailable(bool is_available) {
383  service_is_available_ = is_available;
384  if (is_available) {
385    std::vector<WaitForServiceToBeAvailableCallback> callbacks;
386    callbacks.swap(pending_wait_for_service_to_be_available_callbacks_);
387    for (size_t i = 0; i < callbacks.size(); ++i)
388      callbacks[i].Run(is_available);
389  }
390}
391
392// static
393std::vector<uint8> FakeCryptohomeClient::GetStubSystemSalt() {
394  const char kStubSystemSalt[] = "stub_system_salt";
395  return std::vector<uint8>(kStubSystemSalt,
396                            kStubSystemSalt + arraysize(kStubSystemSalt) - 1);
397}
398
399void FakeCryptohomeClient::ReturnAsyncMethodResult(
400    const AsyncMethodCallback& callback,
401    bool returns_data) {
402  base::MessageLoop::current()->PostTask(
403      FROM_HERE,
404      base::Bind(&FakeCryptohomeClient::ReturnAsyncMethodResultInternal,
405                 weak_ptr_factory_.GetWeakPtr(),
406                 callback,
407                 returns_data));
408}
409
410void FakeCryptohomeClient::ReturnAsyncMethodResultInternal(
411    const AsyncMethodCallback& callback,
412    bool returns_data) {
413  callback.Run(async_call_id_);
414  if (!returns_data && !async_call_status_handler_.is_null()) {
415    base::MessageLoop::current()->PostTask(
416        FROM_HERE,
417        base::Bind(async_call_status_handler_,
418                   async_call_id_,
419                   true,
420                   cryptohome::MOUNT_ERROR_NONE));
421  } else if (returns_data && !async_call_status_data_handler_.is_null()) {
422    base::MessageLoop::current()->PostTask(
423        FROM_HERE,
424        base::Bind(async_call_status_data_handler_,
425                   async_call_id_,
426                   true,
427                   std::string()));
428  }
429  ++async_call_id_;
430}
431
432}  // namespace chromeos
433