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