1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* BluetoothKeystore Interface */
18 
19 #include "btif_keystore.h"
20 
21 #include <base/functional/bind.h>
22 #include <base/location.h>
23 #include <bluetooth/log.h>
24 #include <hardware/bluetooth.h>
25 
26 #include <map>
27 
28 #include "btif_common.h"
29 #include "main/shim/config.h"
30 #include "os/parameter_provider.h"
31 
32 using base::Bind;
33 using base::Unretained;
34 using bluetooth::bluetooth_keystore::BluetoothKeystoreCallbacks;
35 using bluetooth::bluetooth_keystore::BluetoothKeystoreInterface;
36 
37 namespace bluetooth {
38 namespace bluetooth_keystore {
39 class BluetoothKeystoreInterfaceImpl;
40 std::unique_ptr<BluetoothKeystoreInterface> bluetoothKeystoreInstance;
41 const int CONFIG_COMPARE_ALL_PASS = 0b11;
42 
43 class BluetoothKeystoreInterfaceImpl
44     : public bluetooth::bluetooth_keystore::BluetoothKeystoreInterface {
45   ~BluetoothKeystoreInterfaceImpl() override = default;
46 
init(BluetoothKeystoreCallbacks * callbacks)47   void init(BluetoothKeystoreCallbacks* callbacks) override {
48     log::verbose("");
49     this->callbacks = callbacks;
50 
51     bluetooth::os::ParameterProvider::SetCommonCriteriaConfigCompareResult(CONFIG_COMPARE_ALL_PASS);
52     ConvertEncryptOrDecryptKeyIfNeeded();
53   }
54 
ConvertEncryptOrDecryptKeyIfNeeded()55   void ConvertEncryptOrDecryptKeyIfNeeded() {
56     log::verbose("");
57     if (!callbacks) {
58       log::info("callback isn't ready.");
59       return;
60     }
61     do_in_jni_thread(base::BindOnce(
62             []() { shim::BtifConfigInterface::ConvertEncryptOrDecryptKeyIfNeeded(); }));
63   }
64 
set_encrypt_key_or_remove_key(std::string prefix,std::string decryptedString)65   bool set_encrypt_key_or_remove_key(std::string prefix, std::string decryptedString) override {
66     log::verbose("prefix: {}", prefix);
67 
68     if (!callbacks) {
69       log::warn("callback isn't ready. prefix: {}", prefix);
70       return false;
71     }
72 
73     // Save the value into a map.
74     key_map[prefix] = decryptedString;
75 
76     do_in_jni_thread(base::BindOnce(&bluetooth::bluetooth_keystore::BluetoothKeystoreCallbacks::
77                                             set_encrypt_key_or_remove_key,
78                                     base::Unretained(callbacks), prefix, decryptedString));
79     return true;
80   }
81 
get_key(std::string prefix)82   std::string get_key(std::string prefix) override {
83     log::verbose("prefix: {}", prefix);
84 
85     if (!callbacks) {
86       log::warn("callback isn't ready. prefix: {}", prefix);
87       return "";
88     }
89 
90     std::string decryptedString;
91     // try to find the key.
92     std::map<std::string, std::string>::iterator iter = key_map.find(prefix);
93     if (iter == key_map.end()) {
94       decryptedString = callbacks->get_key(prefix);
95       // Save the value into a map.
96       key_map[prefix] = decryptedString;
97       log::verbose("get key from bluetoothkeystore.");
98     } else {
99       decryptedString = iter->second;
100     }
101     return decryptedString;
102   }
103 
clear_map()104   void clear_map() override {
105     log::verbose("");
106 
107     std::map<std::string, std::string> empty_map;
108     key_map.swap(empty_map);
109     key_map.clear();
110   }
111 
112 private:
113   BluetoothKeystoreCallbacks* callbacks = nullptr;
114   std::map<std::string, std::string> key_map;
115 };
116 
getBluetoothKeystoreInterface()117 BluetoothKeystoreInterface* getBluetoothKeystoreInterface() {
118   if (!bluetoothKeystoreInstance) {
119     bluetoothKeystoreInstance.reset(new BluetoothKeystoreInterfaceImpl());
120   }
121 
122   return bluetoothKeystoreInstance.get();
123 }
124 
125 }  // namespace bluetooth_keystore
126 }  // namespace bluetooth
127