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