• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2014 Google, Inc.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #define LOG_TAG "bt_btif_config"
20 
21 #include "btif_config.h"
22 
23 #include <bluetooth/log.h>
24 #include <openssl/rand.h>
25 #include <unistd.h>
26 
27 #include <cstdio>
28 #include <cstring>
29 #include <ctime>
30 #include <mutex>
31 #include <string>
32 #include <unordered_map>
33 
34 #include "btif_keystore.h"
35 #include "common/address_obfuscator.h"
36 #include "main/shim/config.h"
37 #include "main/shim/metric_id_api.h"
38 #include "main/shim/metrics_api.h"
39 #include "main/shim/shim.h"
40 #include "storage/config_keys.h"
41 #include "types/raw_address.h"
42 
43 #define TEMPORARY_SECTION_CAPACITY 10000
44 
45 #define INFO_SECTION "Info"
46 #define FILE_TIMESTAMP "TimeCreated"
47 #define FILE_SOURCE "FileSource"
48 #define TIME_STRING_LENGTH sizeof("YYYY-MM-DD HH:MM:SS")
49 #define DISABLED "disabled"
50 
51 using bluetooth::bluetooth_keystore::BluetoothKeystoreInterface;
52 using bluetooth::common::AddressObfuscator;
53 using namespace bluetooth;
54 
55 // Key attestation
56 static const std::string ENCRYPTED_STR = "encrypted";
57 static const std::string CONFIG_FILE_PREFIX = "bt_config-origin";
58 static const std::string CONFIG_FILE_HASH = "hash";
59 static const std::string encrypt_key_name_list[] = {"LinkKey",     "LE_KEY_PENC",  "LE_KEY_PID",
60                                                     "LE_KEY_LID",  "LE_KEY_PCSRK", "LE_KEY_LENC",
61                                                     "LE_KEY_LCSRK"};
62 
63 /**
64  * Read metrics salt from config file, if salt is invalid or does not exist,
65  * generate new one and save it to config
66  */
read_or_set_metrics_salt()67 static void read_or_set_metrics_salt() {
68   AddressObfuscator::Octet32 metrics_salt = {};
69   size_t metrics_salt_length = metrics_salt.size();
70   if (!btif_config_get_bin(BTIF_STORAGE_SECTION_METRICS, BTIF_STORAGE_KEY_METRICS_SALT_256BIT,
71                            metrics_salt.data(), &metrics_salt_length)) {
72     log::warn("Failed to read metrics salt from config");
73     // Invalidate salt
74     metrics_salt.fill(0);
75   }
76   if (metrics_salt_length != metrics_salt.size()) {
77     log::error("Metrics salt length incorrect, {} instead of {}", metrics_salt_length,
78                metrics_salt.size());
79     // Invalidate salt
80     metrics_salt.fill(0);
81   }
82   if (!AddressObfuscator::IsSaltValid(metrics_salt)) {
83     log::info("Metrics salt is invalid, creating new one");
84     if (RAND_bytes(metrics_salt.data(), metrics_salt.size()) != 1) {
85       log::fatal("Failed to generate salt for metrics");
86     }
87     if (!btif_config_set_bin(BTIF_STORAGE_SECTION_METRICS, BTIF_STORAGE_KEY_METRICS_SALT_256BIT,
88                              metrics_salt.data(), metrics_salt.size())) {
89       log::fatal("Failed to write metrics salt to config");
90     }
91   }
92   AddressObfuscator::GetInstance()->Initialize(metrics_salt);
93 }
94 
95 /**
96  * Initialize metric id allocator by reading metric_id from config by mac
97  * address. If there is no metric id for a mac address, then allocate it a new
98  * metric id.
99  */
init_metric_id_allocator()100 static void init_metric_id_allocator() {
101   std::unordered_map<RawAddress, int> paired_device_map;
102 
103   // When user update the system, there will be devices paired with older
104   // version of android without a metric id.
105   std::vector<RawAddress> addresses_without_id;
106 
107   for (const auto& mac_address : btif_config_get_paired_devices()) {
108     auto addr_str = mac_address.ToString();
109     // if the section name is a mac address
110     bool is_valid_id_found = false;
111     if (btif_config_exist(addr_str, BTIF_STORAGE_KEY_METRICS_ID_KEY)) {
112       // there is one metric id under this mac_address
113       int id = 0;
114       btif_config_get_int(addr_str, BTIF_STORAGE_KEY_METRICS_ID_KEY, &id);
115       if (bluetooth::shim::IsValidIdFromMetricIdAllocator(id)) {
116         paired_device_map[mac_address] = id;
117         is_valid_id_found = true;
118       }
119     }
120     if (!is_valid_id_found) {
121       addresses_without_id.push_back(mac_address);
122     }
123   }
124 
125   // Initialize MetricIdAllocator
126   auto save_device_callback = [](const RawAddress& address, const int id) {
127     return btif_config_set_int(address.ToString(), BTIF_STORAGE_KEY_METRICS_ID_KEY, id);
128   };
129   auto forget_device_callback = [](const RawAddress& address, const int /* id */) {
130     return btif_config_remove(address.ToString(), BTIF_STORAGE_KEY_METRICS_ID_KEY);
131   };
132   if (!bluetooth::shim::InitMetricIdAllocator(paired_device_map, std::move(save_device_callback),
133                                               std::move(forget_device_callback))) {
134     log::fatal("Failed to initialize MetricIdAllocator");
135   }
136 
137   // Add device_without_id
138   for (auto& address : addresses_without_id) {
139     bluetooth::shim::AllocateIdFromMetricIdAllocator(address);
140     bluetooth::shim::SaveDeviceOnMetricIdAllocator(address);
141   }
142 }
143 
144 static std::recursive_mutex config_lock;  // protects operations on |config|.
145 
146 // Module lifecycle functions
147 
init(void)148 static future_t* init(void) {
149   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
150                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
151   // TODO (b/158035889) Migrate metrics module to GD
152   read_or_set_metrics_salt();
153   init_metric_id_allocator();
154   return future_new_immediate(FUTURE_SUCCESS);
155 }
156 
shut_down(void)157 static future_t* shut_down(void) { return future_new_immediate(FUTURE_SUCCESS); }
158 
clean_up(void)159 static future_t* clean_up(void) {
160   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
161                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
162   // GD storage module cleanup by itself
163   std::unique_lock<std::recursive_mutex> lock(config_lock);
164   bluetooth::shim::CloseMetricIdAllocator();
165   return future_new_immediate(FUTURE_SUCCESS);
166 }
167 
168 EXPORT_SYMBOL module_t btif_config_module = {.name = BTIF_CONFIG_MODULE,
169                                              .init = init,
170                                              .start_up = NULL,
171                                              .shut_down = shut_down,
172                                              .clean_up = clean_up};
173 
btif_get_device_clockoffset(const RawAddress & bda,int * p_clock_offset)174 bool btif_get_device_clockoffset(const RawAddress& bda, int* p_clock_offset) {
175   if (p_clock_offset == NULL) {
176     return false;
177   }
178 
179   std::string addrstr = bda.ToString();
180   const char* bd_addr_str = addrstr.c_str();
181 
182   if (!btif_config_get_int(bd_addr_str, BTIF_STORAGE_KEY_CLOCK_OFFSET, p_clock_offset)) {
183     return false;
184   }
185 
186   log::debug("Device [{}] clock_offset {}", bda, *p_clock_offset);
187   return true;
188 }
189 
btif_set_device_clockoffset(const RawAddress & bda,int clock_offset)190 bool btif_set_device_clockoffset(const RawAddress& bda, int clock_offset) {
191   std::string addrstr = bda.ToString();
192   const char* bd_addr_str = addrstr.c_str();
193 
194   if (!btif_config_set_int(bd_addr_str, BTIF_STORAGE_KEY_CLOCK_OFFSET, clock_offset)) {
195     return false;
196   }
197 
198   log::debug("Device [{}] clock_offset {}", bda, clock_offset);
199   return true;
200 }
201 
btif_config_exist(const std::string & section,const std::string & key)202 bool btif_config_exist(const std::string& section, const std::string& key) {
203   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
204                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
205   return bluetooth::shim::BtifConfigInterface::HasProperty(section, key);
206 }
207 
btif_config_get_int(const std::string & section,const std::string & key,int * value)208 bool btif_config_get_int(const std::string& section, const std::string& key, int* value) {
209   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
210                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
211   return bluetooth::shim::BtifConfigInterface::GetInt(section, key, value);
212 }
213 
btif_config_set_int(const std::string & section,const std::string & key,int value)214 bool btif_config_set_int(const std::string& section, const std::string& key, int value) {
215   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
216                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
217   return bluetooth::shim::BtifConfigInterface::SetInt(section, key, value);
218 }
219 
btif_config_get_uint64(const std::string & section,const std::string & key,uint64_t * value)220 bool btif_config_get_uint64(const std::string& section, const std::string& key, uint64_t* value) {
221   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
222                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
223   return bluetooth::shim::BtifConfigInterface::GetUint64(section, key, value);
224 }
225 
btif_config_set_uint64(const std::string & section,const std::string & key,uint64_t value)226 bool btif_config_set_uint64(const std::string& section, const std::string& key, uint64_t value) {
227   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
228                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
229   return bluetooth::shim::BtifConfigInterface::SetUint64(section, key, value);
230 }
231 
232 /*******************************************************************************
233  *
234  * Function         btif_config_get_str
235  *
236  * Description      Get the string value associated with a particular section
237  *                  and key.
238  *
239  *                  section : The section name (i.e "Adapter")
240  *                  key : The key name (i.e "Address")
241  *                  value : A pointer to a buffer where we will store the value
242  *                  size_bytes : The size of the buffer we have available to
243  *                               write the value into. Will be updated upon
244  *                               returning to contain the number of bytes
245  *                               written.
246  *
247  * Returns          True if a value was found, False otherwise.
248  *
249  ******************************************************************************/
250 
btif_config_get_str(const std::string & section,const std::string & key,char * value,int * size_bytes)251 bool btif_config_get_str(const std::string& section, const std::string& key, char* value,
252                          int* size_bytes) {
253   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
254                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
255   return bluetooth::shim::BtifConfigInterface::GetStr(section, key, value, size_bytes);
256 }
257 
btif_config_set_str(const std::string & section,const std::string & key,const std::string & value)258 bool btif_config_set_str(const std::string& section, const std::string& key,
259                          const std::string& value) {
260   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
261                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
262   return bluetooth::shim::BtifConfigInterface::SetStr(section, key, value);
263 }
264 
btif_config_get_bin(const std::string & section,const std::string & key,uint8_t * value,size_t * length)265 bool btif_config_get_bin(const std::string& section, const std::string& key, uint8_t* value,
266                          size_t* length) {
267   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
268                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
269   return bluetooth::shim::BtifConfigInterface::GetBin(section, key, value, length);
270 }
271 
btif_config_get_bin_length(const std::string & section,const std::string & key)272 size_t btif_config_get_bin_length(const std::string& section, const std::string& key) {
273   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
274                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
275   return bluetooth::shim::BtifConfigInterface::GetBinLength(section, key);
276 }
277 
btif_config_set_bin(const std::string & section,const std::string & key,const uint8_t * value,size_t length)278 bool btif_config_set_bin(const std::string& section, const std::string& key, const uint8_t* value,
279                          size_t length) {
280   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
281                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
282   return bluetooth::shim::BtifConfigInterface::SetBin(section, key, value, length);
283 }
284 
btif_config_get_paired_devices()285 std::vector<RawAddress> btif_config_get_paired_devices() {
286   std::vector<std::string> names;
287   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
288                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
289   names = bluetooth::shim::BtifConfigInterface::GetPersistentDevices();
290 
291   std::vector<RawAddress> result;
292   result.reserve(names.size());
293   for (const auto& name : names) {
294     RawAddress addr = {};
295     // Gather up known devices from configuration section names
296     if (RawAddress::FromString(name, addr)) {
297       result.emplace_back(addr);
298     }
299   }
300   return result;
301 }
302 
btif_config_remove(const std::string & section,const std::string & key)303 bool btif_config_remove(const std::string& section, const std::string& key) {
304   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
305                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
306   return bluetooth::shim::BtifConfigInterface::RemoveProperty(section, key);
307 }
308 
btif_config_remove_device(const std::string & section)309 void btif_config_remove_device(const std::string& section) {
310   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
311                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
312   bluetooth::shim::BtifConfigInterface::RemoveSection(section);
313 }
314 
btif_config_remove_device_with_key(const std::string & key)315 void btif_config_remove_device_with_key(const std::string& key) {
316   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
317                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
318   bluetooth::shim::BtifConfigInterface::RemoveSectionWithProperty(key);
319 }
320 
btif_config_clear(void)321 bool btif_config_clear(void) {
322   log::assert_that(bluetooth::shim::is_gd_stack_started_up(),
323                    "assert failed: bluetooth::shim::is_gd_stack_started_up()");
324   bluetooth::shim::BtifConfigInterface::Clear();
325   return true;
326 }
327