1 // Copyright 2014 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 CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_KEY_MANAGER_H_
6 #define CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_KEY_MANAGER_H_
7 
8 #include <stddef.h>
9 
10 #include <map>
11 #include <memory>
12 #include <string>
13 
14 #include "base/callback.h"
15 #include "base/containers/circular_deque.h"
16 #include "base/macros.h"
17 #include "base/memory/weak_ptr.h"
18 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_get_keys_operation.h"
19 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_refresh_keys_operation.h"
20 #include "chrome/browser/chromeos/login/easy_unlock/easy_unlock_types.h"
21 
22 class AccountId;
23 
24 namespace base {
25 class DictionaryValue;
26 class ListValue;
27 }  // namespace base
28 
29 namespace chromeos {
30 
31 class UserContext;
32 
33 // A class to manage Easy unlock cryptohome keys.
34 class EasyUnlockKeyManager {
35  public:
36   typedef EasyUnlockRefreshKeysOperation::RefreshKeysCallback
37       RefreshKeysCallback;
38   typedef EasyUnlockGetKeysOperation::GetKeysCallback GetDeviceDataListCallback;
39 
40   EasyUnlockKeyManager();
41   ~EasyUnlockKeyManager();
42 
43   // Clears existing Easy unlock keys and creates new ones for the given
44   // `remote_devices` and the given `user_context`. `user_context` must have
45   // secret to allow keys to be created.
46   void RefreshKeys(const UserContext& user_context,
47                    const base::ListValue& remote_devices,
48                    const RefreshKeysCallback& callback);
49 
50   // Retrieves the remote device data from cryptohome keys for the given
51   // `user_context`.
52   void GetDeviceDataList(const UserContext& user_context,
53                          const GetDeviceDataListCallback& callback);
54 
55   // Helpers to convert between DeviceData and remote device dictionary.
56   // DeviceDataToRemoteDeviceDictionary fills the remote device dictionary and
57   // always succeeds. RemoteDeviceDictionaryToDeviceData returns false if the
58   // conversion fails (missing required propery). Note that
59   // EasyUnlockDeviceKeyData contains a sub set of the remote device dictionary.
60   static void DeviceDataToRemoteDeviceDictionary(
61       const AccountId& account_id,
62       const EasyUnlockDeviceKeyData& data,
63       base::DictionaryValue* dict);
64   static bool RemoteDeviceDictionaryToDeviceData(
65       const base::DictionaryValue& dict,
66       EasyUnlockDeviceKeyData* data);
67 
68   // Helpers to convert between EasyUnlockDeviceKeyDataList and remote devices
69   // ListValue.
70   static void DeviceDataListToRemoteDeviceList(
71       const AccountId& account_id,
72       const EasyUnlockDeviceKeyDataList& data_list,
73       base::ListValue* device_list);
74   static bool RemoteDeviceRefListToDeviceDataList(
75       const base::ListValue& device_list,
76       EasyUnlockDeviceKeyDataList* data_list);
77 
78   // Gets key label for the given key index.
79   static std::string GetKeyLabel(size_t key_index);
80 
81  private:
82   // Runs the next operation if there is one. We first run all the operations in
83   // the `write_operation_queue_` and then run all the operations in the
84   // `read_operation_queue_`.
85   void RunNextOperation();
86 
87   // Called when the TPM key is ready to be used for creating Easy Unlock key
88   // challenges.
89   void RefreshKeysWithTpmKeyPresent(const UserContext& user_context,
90                                     base::ListValue* remote_devices,
91                                     const RefreshKeysCallback& callback);
92 
93   // Callback invoked after refresh keys operation.
94   void OnKeysRefreshed(const RefreshKeysCallback& callback,
95                        bool create_success);
96 
97   // Callback invoked after get keys op.
98   void OnKeysFetched(const GetDeviceDataListCallback& callback,
99                      bool fetch_success,
100                      const EasyUnlockDeviceKeyDataList& fetched_data);
101 
102   base::circular_deque<std::unique_ptr<EasyUnlockRefreshKeysOperation>>
103       write_operation_queue_;
104   base::circular_deque<std::unique_ptr<EasyUnlockGetKeysOperation>>
105       read_operation_queue_;
106 
107   // Stores the current operation in progress. At most one of these variables
108   // can be non-null at any time.
109   std::unique_ptr<EasyUnlockRefreshKeysOperation> pending_write_operation_;
110   std::unique_ptr<EasyUnlockGetKeysOperation> pending_read_operation_;
111 
112   base::WeakPtrFactory<EasyUnlockKeyManager> weak_ptr_factory_{this};
113 
114   DISALLOW_COPY_AND_ASSIGN(EasyUnlockKeyManager);
115 };
116 
117 }  // namespace chromeos
118 
119 #endif  // CHROME_BROWSER_CHROMEOS_LOGIN_EASY_UNLOCK_EASY_UNLOCK_KEY_MANAGER_H_
120