1 // Copyright (c) 2012 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 #ifndef CHROMEOS_DBUS_CRYPTOHOME_CRYPTOHOME_CLIENT_H_
6 #define CHROMEOS_DBUS_CRYPTOHOME_CRYPTOHOME_CLIENT_H_
7 
8 #include <stdint.h>
9 
10 #include <string>
11 #include <vector>
12 
13 #include "base/callback.h"
14 #include "base/component_export.h"
15 #include "base/macros.h"
16 #include "chromeos/dbus/constants/attestation_constants.h"
17 #include "chromeos/dbus/dbus_method_call_status.h"
18 #include "third_party/cros_system_api/dbus/service_constants.h"
19 
20 namespace cryptohome {
21 
22 class AccountIdentifier;
23 class AddKeyRequest;
24 class AuthorizationRequest;
25 class BaseReply;
26 class CheckHealthRequest;
27 class CheckKeyRequest;
28 class EndFingerprintAuthSessionRequest;
29 class FlushAndSignBootAttributesRequest;
30 class GetBootAttributeRequest;
31 class GetKeyDataRequest;
32 class GetSupportedKeyPoliciesRequest;
33 class GetTpmStatusRequest;
34 class LockToSingleUserMountUntilRebootRequest;
35 class MassRemoveKeysRequest;
36 class MigrateKeyRequest;
37 class MigrateToDircryptoRequest;
38 class MountGuestRequest;
39 class MountRequest;
40 class RemoveFirmwareManagementParametersRequest;
41 class RemoveKeyRequest;
42 class SetBootAttributeRequest;
43 class SetFirmwareManagementParametersRequest;
44 class StartFingerprintAuthSessionRequest;
45 class UnmountRequest;
46 class UpdateKeyRequest;
47 
48 }  // namespace cryptohome
49 
50 namespace dbus {
51 class Bus;
52 }
53 
54 namespace chromeos {
55 
56 // CryptohomeClient is used to communicate with the Cryptohome service.
57 // All method should be called from the origin thread (UI thread) which
58 // initializes the DBusThreadManager instance.
COMPONENT_EXPORT(CRYPTOHOME_CLIENT)59 class COMPONENT_EXPORT(CRYPTOHOME_CLIENT) CryptohomeClient {
60  public:
61   class Observer {
62    public:
63     // Called when AsyncCallStatus signal is received, when results for
64     // AsyncXXX methods are returned. Cryptohome service will process the
65     // calls in a first-in-first-out manner when they are made in parallel.
66     virtual void AsyncCallStatus(int async_id,
67                                  bool return_status,
68                                  int return_code) {}
69 
70     // Called when AsyncCallStatusWithData signal is received,
71     // similar to AsyncCallStatus, but with |data|.
72     virtual void AsyncCallStatusWithData(int async_id,
73                                          bool return_status,
74                                          const std::string& data) {}
75 
76     // Called when TpmInitStatus signal is received, when the status of the TPM
77     // initialization is changed.
78     virtual void TpmInitStatusUpdated(bool ready,
79                                       bool owned,
80                                       bool was_owned_this_boot) {}
81 
82     // Called when LowDiskSpace signal is received, when the cryptohome
83     // partition is running out of disk space.
84     virtual void LowDiskSpace(uint64_t disk_free_bytes) {}
85 
86     // Called when DircryptoMigrationProgress signal is received.
87     // Typically, called periodicaly during a migration is performed by
88     // cryptohomed, as well as to notify the completion of migration.
89     virtual void DircryptoMigrationProgress(
90         cryptohome::DircryptoMigrationStatus status,
91         uint64_t current,
92         uint64_t total) {}
93 
94    protected:
95     virtual ~Observer() = default;
96   };
97 
98   // Callback for the methods initiate asynchronous operations.
99   // On success (i.e. the asynchronous operation is started), an |async_id|
100   // is returned, so the user code can identify the corresponding signal
101   // handler invocation later.
102   using AsyncMethodCallback = DBusMethodCallback<int /* async_id */>;
103 
104   // Represents the result to obtain the data related to TPM attestation.
105   struct TpmAttestationDataResult {
106     // True when it is succeeded to obtain the data.
107     bool success = false;
108 
109     // The returned content. Available iff |success| is true.
110     std::string data;
111   };
112 
113   // TPM Token Information retrieved from cryptohome.
114   // For invalid token |label| and |user_pin| will be empty, while |slot| will
115   // be set to -1.
116   struct TpmTokenInfo {
117     // Holds the PKCS #11 token label. This is not useful in practice to
118     // identify a token but may be meaningful to a user.
119     std::string label;
120 
121     // Can be used with the C_Login PKCS #11 function but is not necessary
122     // because tokens are logged in for the duration of a signed-in session.
123     std::string user_pin;
124 
125     // Corresponds to a CK_SLOT_ID for the PKCS #11 API and reliably
126     // identifies the token for the duration of the signed-in session.
127     int slot = -1;
128   };
129 
130   // Holds TPM version info. Mirrors cryptohome::Tpm::TpmVersionInfo from CrOS
131   // side.
132   struct TpmVersionInfo {
133     uint32_t family = 0;
134     uint64_t spec_level = 0;
135     uint32_t manufacturer = 0;
136     uint32_t tpm_model = 0;
137     uint64_t firmware_version = 0;
138     std::string vendor_specific;
139   };
140 
141   // Creates and initializes the global instance. |bus| must not be null.
142   static void Initialize(dbus::Bus* bus);
143 
144   // Creates and initializes a fake global instance if not already created.
145   static void InitializeFake();
146 
147   // Destroys the global instance which must have been initialized.
148   static void Shutdown();
149 
150   // Returns the global instance if initialized. May return null.
151   static CryptohomeClient* Get();
152 
153   // Returns the sanitized |username| that the stub implementation would return.
154   static std::string GetStubSanitizedUsername(
155       const cryptohome::AccountIdentifier& id);
156 
157   // Adds an observer.
158   virtual void AddObserver(Observer* observer) = 0;
159 
160   // Removes an observer if added.
161   virtual void RemoveObserver(Observer* observer) = 0;
162 
163   // Runs the callback as soon as the service becomes available.
164   virtual void WaitForServiceToBeAvailable(
165       WaitForServiceToBeAvailableCallback callback) = 0;
166 
167   // Calls IsMounted method and returns true when the call succeeds.
168   virtual void IsMounted(DBusMethodCallback<bool> callback) = 0;
169 
170   // Calls UnmountEx method. |callback| is called after the method call
171   // succeeds.
172   virtual void UnmountEx(
173       const cryptohome::UnmountRequest& request,
174       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
175 
176   // Calls MigrateKeyEx method. |callback| is called after the method call
177   // succeeds.
178   virtual void MigrateKeyEx(
179       const cryptohome::AccountIdentifier& account,
180       const cryptohome::AuthorizationRequest& auth_request,
181       const cryptohome::MigrateKeyRequest& migrate_request,
182       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
183 
184   // Calls RemoveEx method.  |callback| is called after the method call
185   // succeeds.
186   virtual void RemoveEx(const cryptohome::AccountIdentifier& account,
187                         DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
188 
189   // Calls RenameCryptohome method. |callback| is called after the method
190   // call succeeds.
191   virtual void RenameCryptohome(
192       const cryptohome::AccountIdentifier& id_from,
193       const cryptohome::AccountIdentifier& id_to,
194       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
195 
196   // Calls GetAccountDiskUsage method. |callback| is called after the method
197   // call succeeds
198   virtual void GetAccountDiskUsage(
199       const cryptohome::AccountIdentifier& account_id,
200       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
201 
202   // Calls GetSystemSalt method.  |callback| is called after the method call
203   // succeeds.
204   virtual void GetSystemSalt(
205       DBusMethodCallback<std::vector<uint8_t>> callback) = 0;
206 
207   // Calls GetSanitizedUsername method.  |callback| is called after the method
208   // call succeeds.
209   virtual void GetSanitizedUsername(
210       const cryptohome::AccountIdentifier& id,
211       DBusMethodCallback<std::string> callback) = 0;
212 
213   // Same as GetSanitizedUsername() but blocks until a reply is received, and
214   // returns the sanitized username synchronously. Returns an empty string if
215   // the method call fails.
216   // This may only be called in situations where blocking the UI thread is
217   // considered acceptable (e.g. restarting the browser after a crash or after
218   // a flag change).
219   virtual std::string BlockingGetSanitizedUsername(
220       const cryptohome::AccountIdentifier& id) = 0;
221 
222   // Calls MountGuestEx method. |callback| is called after the method call
223   // succeeds.
224   virtual void MountGuestEx(
225       const cryptohome::MountGuestRequest& request,
226       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
227 
228   // Calls GetRsuDeviceId method. |callback| is called after the method call
229   // succeeds.
230   virtual void GetRsuDeviceId(
231       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
232 
233   // Calls TpmIsReady method.
234   virtual void TpmIsReady(DBusMethodCallback<bool> callback) = 0;
235 
236   // Calls TpmIsEnabled method.
237   virtual void TpmIsEnabled(DBusMethodCallback<bool> callback) = 0;
238 
239   // Calls TpmIsEnabled method and returns true when the call succeeds.
240   // This method blocks until the call returns.
241   // TODO(hashimoto): Remove this method. crbug.com/141006
242   virtual bool CallTpmIsEnabledAndBlock(bool* enabled) = 0;
243 
244   // Calls TpmGetPassword method.
245   virtual void TpmGetPassword(DBusMethodCallback<std::string> callback) = 0;
246 
247   // Calls TpmIsOwned method.
248   virtual void TpmIsOwned(DBusMethodCallback<bool> callback) = 0;
249 
250   // Calls TpmIsOwned method and returns true when the call succeeds.
251   // This method blocks until the call returns.
252   // TODO(hashimoto): Remove this method. crbug.com/141012
253   virtual bool CallTpmIsOwnedAndBlock(bool* owned) = 0;
254 
255   // Calls TpmIsBeingOwned method.
256   virtual void TpmIsBeingOwned(DBusMethodCallback<bool> callback) = 0;
257 
258   // Calls TpmIsBeingOwned method and returns true when the call succeeds.
259   // This method blocks until the call returns.
260   // TODO(hashimoto): Remove this method. crbug.com/141011
261   virtual bool CallTpmIsBeingOwnedAndBlock(bool* owning) = 0;
262 
263   // Calls TpmCanAttemptOwnership method.
264   // This method tells the service that it is OK to attempt ownership.
265   virtual void TpmCanAttemptOwnership(VoidDBusMethodCallback callback) = 0;
266 
267   // Calls TpmClearStoredPasswordMethod.
268   virtual void TpmClearStoredPassword(VoidDBusMethodCallback callback) = 0;
269 
270   // Calls TpmClearStoredPassword method and returns true when the call
271   // succeeds.  This method blocks until the call returns.
272   // TODO(hashimoto): Remove this method. crbug.com/141010
273   virtual bool CallTpmClearStoredPasswordAndBlock() = 0;
274 
275   // Calls Pkcs11IsTpmTokenReady method.
276   virtual void Pkcs11IsTpmTokenReady(DBusMethodCallback<bool> callback) = 0;
277 
278   // Calls Pkcs11GetTpmTokenInfo method.  This method is deprecated, you should
279   // use Pkcs11GetTpmTokenInfoForUser instead.  On success |callback| will
280   // receive PKCS #11 token information for the token associated with the user
281   // who originally signed in (i.e. PKCS #11 slot 0).
282   virtual void Pkcs11GetTpmTokenInfo(
283       DBusMethodCallback<TpmTokenInfo> callback) = 0;
284 
285   // Calls Pkcs11GetTpmTokenInfoForUser method.  On success |callback| will
286   // receive PKCS #11 token information for the user identified by |id|.
287   virtual void Pkcs11GetTpmTokenInfoForUser(
288       const cryptohome::AccountIdentifier& id,
289       DBusMethodCallback<TpmTokenInfo> callback) = 0;
290 
291   // Calls InstallAttributesGet method and returns true when the call succeeds.
292   // This method blocks until the call returns.
293   // The original content of |value| is lost.
294   virtual bool InstallAttributesGet(const std::string& name,
295                                     std::vector<uint8_t>* value,
296                                     bool* successful) = 0;
297 
298   // Calls InstallAttributesSet method and returns true when the call succeeds.
299   // This method blocks until the call returns.
300   virtual bool InstallAttributesSet(const std::string& name,
301                                     const std::vector<uint8_t>& value,
302                                     bool* successful) = 0;
303 
304   // Calls InstallAttributesFinalize method and returns true when the call
305   // succeeds.  This method blocks until the call returns.
306   virtual bool InstallAttributesFinalize(bool* successful) = 0;
307 
308   // Calls InstallAttributesIsReady method.
309   virtual void InstallAttributesIsReady(DBusMethodCallback<bool> callback) = 0;
310 
311   // Calls InstallAttributesIsInvalid method and returns true when the call
312   // succeeds.  This method blocks until the call returns.
313   virtual bool InstallAttributesIsInvalid(bool* is_invalid) = 0;
314 
315   // Calls InstallAttributesIsFirstInstall method and returns true when the call
316   // succeeds. This method blocks until the call returns.
317   virtual bool InstallAttributesIsFirstInstall(bool* is_first_install) = 0;
318 
319   // Asynchronously gets the underlying TPM version information and passes it to
320   // the given callback.
321   virtual void TpmGetVersion(DBusMethodCallback<TpmVersionInfo> callback) = 0;
322 
323   // Asynchronously calls the GetKeyDataEx method. |callback| will be invoked
324   // with the reply protobuf.
325   // GetKeyDataEx returns information about the key specified in |request|. At
326   // present, this does not include any secret information and the call should
327   // not be authenticated (|auth| should be empty).
328   virtual void GetKeyDataEx(
329       const cryptohome::AccountIdentifier& id,
330       const cryptohome::AuthorizationRequest& auth,
331       const cryptohome::GetKeyDataRequest& request,
332       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
333 
334   // Asynchronously calls CheckKeyEx method. |callback| is called after method
335   // call, and with reply protobuf.
336   // CheckKeyEx just checks if authorization information is valid.
337   virtual void CheckKeyEx(
338       const cryptohome::AccountIdentifier& id,
339       const cryptohome::AuthorizationRequest& auth,
340       const cryptohome::CheckKeyRequest& request,
341       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
342 
343   // Asynchronously calls MountEx method. Afterward, |callback| is called with
344   // the reply.
345   // MountEx attempts to mount home dir using given authorization,
346   // and can create new home dir if necessary values are specified in |request|.
347   virtual void MountEx(const cryptohome::AccountIdentifier& id,
348                        const cryptohome::AuthorizationRequest& auth,
349                        const cryptohome::MountRequest& request,
350                        DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
351 
352   // Asynchronously calls DisableLoginUntilReboot method, locking the device
353   // into a state where only the user data for provided account_id from
354   // |request| can be accessed. After reboot all other user data are accessible.
355   virtual void LockToSingleUserMountUntilReboot(
356       const cryptohome::LockToSingleUserMountUntilRebootRequest& request,
357       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
358 
359   // Asynchronously calls AddKeyEx method. |callback| is called after method
360   // call, and with reply protobuf.
361   // AddKeyEx adds another key to the given key set. |request| also defines
362   // behavior in case when key with specified label already exist.
363   virtual void AddKeyEx(const cryptohome::AccountIdentifier& id,
364                         const cryptohome::AuthorizationRequest& auth,
365                         const cryptohome::AddKeyRequest& request,
366                         DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
367 
368   // Asynchronously calls AddDataRestoreKey method. |callback| is called after
369   // method call, and with reply protobuf.
370   // AddDataRestoreKey generates data_restore_key in OS and adds it to the
371   // given key set. The reply protobuf needs to be extended to
372   // AddDataRestoreKeyReply so that caller gets raw bytes of data_restore_key
373   virtual void AddDataRestoreKey(
374       const cryptohome::AccountIdentifier& id,
375       const cryptohome::AuthorizationRequest& auth,
376       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
377 
378   // Asynchronously calls UpdateKeyEx method. |callback| is called after method
379   // call, and with reply protobuf. Reply will contain MountReply extension.
380   // UpdateKeyEx replaces key used for authorization, without affecting any
381   // other keys. If specified at home dir creation time, new key may have
382   // to be signed and/or encrypted.
383   virtual void UpdateKeyEx(
384       const cryptohome::AccountIdentifier& id,
385       const cryptohome::AuthorizationRequest& auth,
386       const cryptohome::UpdateKeyRequest& request,
387       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
388 
389   // Asynchronously calls RemoveKeyEx method. |callback| is called after method
390   // call, and with reply protobuf.
391   // RemoveKeyEx removes key from the given key set.
392   virtual void RemoveKeyEx(
393       const cryptohome::AccountIdentifier& id,
394       const cryptohome::AuthorizationRequest& auth,
395       const cryptohome::RemoveKeyRequest& request,
396       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
397 
398   // Asynchronously calls MassRemoveKeys method. |callback| is called after
399   // method call, and with reply protobuf.
400   // MassRemoveKeys removes all keys except those whose labels are exempted
401   // in MassRemoveKeysRequest.
402   virtual void MassRemoveKeys(
403       const cryptohome::AccountIdentifier& id,
404       const cryptohome::AuthorizationRequest& auth,
405       const cryptohome::MassRemoveKeysRequest& request,
406       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
407 
408   // Asynchronously calls StartFingerprintAuthSession method. |callback| is
409   // called after method call, and with reply protobuf.
410   // StartFingerprintAuthSession prepares biometrics daemon for upcoming
411   // fingerprint authentication.
412   virtual void StartFingerprintAuthSession(
413       const cryptohome::AccountIdentifier& id,
414       const cryptohome::StartFingerprintAuthSessionRequest& request,
415       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
416 
417   // Asynchronously calls EndFingerprintAuthSession method. |callback| is
418   // called after method call, and with reply protobuf.
419   // EndFingerprintAuthSession sets biometrics daemon back to normal mode.
420   // If there is a reply, it is always an empty reply with no errors.
421   virtual void EndFingerprintAuthSession(
422       const cryptohome::EndFingerprintAuthSessionRequest& request,
423       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
424 
425   // Asynchronously calls GetBootAttribute method. |callback| is called after
426   // method call, and with reply protobuf.
427   // GetBootAttribute gets the value of the specified boot attribute.
428   virtual void GetBootAttribute(
429       const cryptohome::GetBootAttributeRequest& request,
430       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
431 
432   // Asynchronously calls SetBootAttribute method. |callback| is called after
433   // method call, and with reply protobuf.
434   // SetBootAttribute sets the value of the specified boot attribute. The value
435   // won't be available unitl FlushAndSignBootAttributes() is called.
436   virtual void SetBootAttribute(
437       const cryptohome::SetBootAttributeRequest& request,
438       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
439 
440   // Asynchronously calls FlushAndSignBootAttributes method. |callback| is
441   // called after method call, and with reply protobuf.
442   // FlushAndSignBootAttributes makes all pending boot attribute settings
443   // available, and have them signed by a special TPM key. This method always
444   // fails after any user, publuc, or guest session starts.
445   virtual void FlushAndSignBootAttributes(
446       const cryptohome::FlushAndSignBootAttributesRequest& request,
447       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
448 
449   // Asynchronously gets the underlying TPM status information and passes it to
450   // the given callback with reply protobuf.
451   virtual void GetTpmStatus(
452       const cryptohome::GetTpmStatusRequest& request,
453       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
454 
455   // Asynchronously calls MigrateToDircrypto method. It tells cryptohomed to
456   // start migration, and is immediately called back by |callback|. The actual
457   // result response is done via DircryptoMigrationProgress callback with its
458   // status flag indicating the completion.
459   // MigrateToDircrypto attempts to migrate the home dir to the new "dircrypto"
460   // encryption.
461   // |request| contains additional parameters, such as specifying if a full
462   // migration or a minimal migration should be performed.
463   virtual void MigrateToDircrypto(
464       const cryptohome::AccountIdentifier& id,
465       const cryptohome::MigrateToDircryptoRequest& request,
466       VoidDBusMethodCallback callback) = 0;
467 
468   // Asynchronously calls RemoveFirmwareManagementParameters method. |callback|
469   // is called after method call, and with reply protobuf.
470   virtual void RemoveFirmwareManagementParametersFromTpm(
471       const cryptohome::RemoveFirmwareManagementParametersRequest& request,
472       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
473 
474   // Asynchronously calls SetFirmwareManagementParameters method. |callback|
475   // is called after method call, and with reply protobuf. |request| contains
476   // the flags to be set. SetFirmwareManagementParameters creates the firmware
477   // management parameters in TPM and sets flags included in the request.
478   virtual void SetFirmwareManagementParametersInTpm(
479       const cryptohome::SetFirmwareManagementParametersRequest& request,
480       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
481 
482   // Calls NeedsDircryptoMigration to find out whether the given user needs
483   // dircrypto migration.
484   virtual void NeedsDircryptoMigration(const cryptohome::AccountIdentifier& id,
485                                        DBusMethodCallback<bool> callback) = 0;
486 
487   // Calls GetSupportedKeyPolicies to determine which type of keys can be added.
488   virtual void GetSupportedKeyPolicies(
489       const cryptohome::GetSupportedKeyPoliciesRequest& request,
490       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
491 
492   // Calls IsQuotaSupported to know whether quota is supported by cryptohome.
493   virtual void IsQuotaSupported(DBusMethodCallback<bool> callback) = 0;
494 
495   // Calls GetCurrentSpaceForUid to get the current disk space for an android
496   // uid (a shifted uid).
497   virtual void GetCurrentSpaceForUid(const uid_t android_uid,
498                                      DBusMethodCallback<int64_t> callback) = 0;
499 
500   // Calls GetCurrentSpaceForGid to get the current disk space for an android
501   // gid (a shifted gid).
502   virtual void GetCurrentSpaceForGid(const gid_t android_gid,
503                                      DBusMethodCallback<int64_t> callback) = 0;
504 
505   // Calls CheckHealth to get current health state.
506   virtual void CheckHealth(
507       const cryptohome::CheckHealthRequest& request,
508       DBusMethodCallback<cryptohome::BaseReply> callback) = 0;
509 
510  protected:
511   // Initialize/Shutdown should be used instead.
512   CryptohomeClient();
513   virtual ~CryptohomeClient();
514 
515  private:
516   DISALLOW_COPY_AND_ASSIGN(CryptohomeClient);
517 };
518 
519 }  // namespace chromeos
520 
521 #endif  // CHROMEOS_DBUS_CRYPTOHOME_CRYPTOHOME_CLIENT_H_
522