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