1 /*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "dh_utils_tool.h"
17
18 #include <algorithm>
19 #include <iomanip>
20 #include <iostream>
21 #include <random>
22 #include <sstream>
23 #include <string>
24 #include <sys/time.h>
25 #include <vector>
26 #include <zlib.h>
27
28 #include "openssl/sha.h"
29 #include "parameter.h"
30
31 #include "device_manager.h"
32 #include "dm_device_info.h"
33
34 #include "constants.h"
35 #include "distributed_hardware_errno.h"
36 #include "distributed_hardware_log.h"
37
38 namespace OHOS {
39 namespace DistributedHardware {
40 namespace {
41 constexpr int32_t MS_ONE_SECOND = 1000;
42 constexpr int32_t WORD_WIDTH_8 = 8;
43 constexpr int32_t WORD_WIDTH_4 = 4;
44 constexpr int32_t WIDTH = 4;
45 constexpr unsigned char MASK = 0x0F;
46 constexpr int32_t DOUBLE_TIMES = 2;
47 constexpr int32_t COMPRESS_SLICE_SIZE = 1024;
48 const std::string PARAM_KEY_OS_TYPE = "OS_TYPE";
49 }
50
GetCurrentTime()51 int64_t GetCurrentTime()
52 {
53 struct timeval tv {
54 0
55 };
56 gettimeofday(&tv, nullptr);
57 return tv.tv_sec * MS_ONE_SECOND + tv.tv_usec / MS_ONE_SECOND;
58 }
59
GetRandomID()60 std::string GetRandomID()
61 {
62 static std::random_device rd;
63 static std::uniform_int_distribution<uint64_t> dist(0ULL, 0xFFFFFFFFFFFFFFFFULL);
64 uint64_t ab = dist(rd);
65 uint64_t cd = dist(rd);
66 uint32_t a;
67 uint32_t b;
68 uint32_t c;
69 uint32_t d;
70 std::stringstream ss;
71 ab = (ab & 0xFFFFFFFFFFFF0FFFULL) | 0x0000000000004000ULL;
72 cd = (cd & 0x3FFFFFFFFFFFFFFFULL) | 0x8000000000000000ULL;
73 a = (ab >> 32U);
74 b = (ab & 0xFFFFFFFFU);
75 c = (cd >> 32U);
76 d = (cd & 0xFFFFFFFFU);
77 ss << std::hex << std::nouppercase << std::setfill('0');
78 ss << std::setw(WORD_WIDTH_8) << (a);
79 ss << std::setw(WORD_WIDTH_4) << (b >> 16U);
80 ss << std::setw(WORD_WIDTH_4) << (b & 0xFFFFU);
81 ss << std::setw(WORD_WIDTH_4) << (c >> 16U);
82 ss << std::setw(WORD_WIDTH_4) << (c & 0xFFFFU);
83 ss << std::setw(WORD_WIDTH_8) << d;
84
85 return ss.str();
86 }
87
GetUUIDByDm(const std::string &networkId)88 std::string GetUUIDByDm(const std::string &networkId)
89 {
90 if (!IsIdLengthValid(networkId)) {
91 return "";
92 }
93 std::string uuid = "";
94 auto ret = DeviceManager::GetInstance().GetUuidByNetworkId(DH_FWK_PKG_NAME, networkId, uuid);
95 return (ret == DH_FWK_SUCCESS) ? uuid : "";
96 }
97
GetUDIDByDm(const std::string &networkId)98 std::string GetUDIDByDm(const std::string &networkId)
99 {
100 if (!IsIdLengthValid(networkId)) {
101 return "";
102 }
103 std::string udid = "";
104 auto ret = DeviceManager::GetInstance().GetUdidByNetworkId(DH_FWK_PKG_NAME, networkId, udid);
105 return (ret == DH_FWK_SUCCESS) ? udid : "";
106 }
107
GetDeviceIdByUUID(const std::string &uuid)108 std::string GetDeviceIdByUUID(const std::string &uuid)
109 {
110 if (!IsIdLengthValid(uuid)) {
111 DHLOGE("uuid is invalid!");
112 return "";
113 }
114 return Sha256(uuid);
115 }
116
Sha256(const std::string& in)117 std::string Sha256(const std::string& in)
118 {
119 unsigned char out[SHA256_DIGEST_LENGTH * DOUBLE_TIMES + 1] = {0};
120 SHA256_CTX ctx;
121 SHA256_Init(&ctx);
122 SHA256_Update(&ctx, in.data(), in.size());
123 SHA256_Final(&out[SHA256_DIGEST_LENGTH], &ctx);
124 // here we translate sha256 hash to hexadecimal. each 8-bit char will be presented by two characters([0-9a-f])
125 const char* hexCode = "0123456789abcdef";
126 for (int32_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
127 unsigned char value = out[SHA256_DIGEST_LENGTH + i];
128 // uint8_t is 2 digits in hexadecimal.
129 out[i * DOUBLE_TIMES] = hexCode[(value >> WIDTH) & MASK];
130 out[i * DOUBLE_TIMES + 1] = hexCode[value & MASK];
131 }
132 out[SHA256_DIGEST_LENGTH * DOUBLE_TIMES] = 0;
133 return std::string(reinterpret_cast<char*>(out));
134 }
135
GetLocalDeviceInfo()136 DeviceInfo GetLocalDeviceInfo()
137 {
138 DeviceInfo devInfo { "", "", "", "", "", "", 0 };
139 DmDeviceInfo info;
140 auto ret = DeviceManager::GetInstance().GetLocalDeviceInfo(DH_FWK_PKG_NAME, info);
141 if (ret != DH_FWK_SUCCESS) {
142 DHLOGE("GetLocalNodeDeviceInfo failed, errCode = %{public}d", ret);
143 return devInfo;
144 }
145 devInfo.networkId = info.networkId;
146 devInfo.uuid = GetUUIDByDm(info.networkId);
147 devInfo.deviceId = GetDeviceIdByUUID(devInfo.uuid);
148 devInfo.udid = GetUDIDByDm(info.networkId);
149 devInfo.udidHash = Sha256(devInfo.udid);
150 devInfo.deviceName = info.deviceName;
151 devInfo.deviceType = info.deviceTypeId;
152 return devInfo;
153 }
154
GetLocalNetworkId()155 std::string GetLocalNetworkId()
156 {
157 DmDeviceInfo info;
158 auto ret = DeviceManager::GetInstance().GetLocalDeviceInfo(DH_FWK_PKG_NAME, info);
159 if (ret != DH_FWK_SUCCESS) {
160 DHLOGE("GetLocalNodeDeviceInfo failed, errCode = %{public}d", ret);
161 return "";
162 }
163 return info.networkId;
164 }
165
IsUInt8(const cJSON* jsonObj, const std::string& key)166 bool IsUInt8(const cJSON* jsonObj, const std::string& key)
167 {
168 const cJSON* value = cJSON_GetObjectItem(jsonObj, key.c_str());
169 if (value == NULL || !cJSON_IsNumber(value)) {
170 return false;
171 }
172 return (value->valuedouble >= 0 && value->valuedouble <= UINT8_MAX);
173 }
174
IsUInt16(const cJSON* jsonObj, const std::string& key)175 bool IsUInt16(const cJSON* jsonObj, const std::string& key)
176 {
177 const cJSON* value = cJSON_GetObjectItem(jsonObj, key.c_str());
178 if (value == NULL || !cJSON_IsNumber(value)) {
179 return false;
180 }
181 return (value->valuedouble >= 0 && value->valuedouble <= UINT16_MAX);
182 }
183
IsInt32(const cJSON* jsonObj, const std::string& key)184 bool IsInt32(const cJSON* jsonObj, const std::string& key)
185 {
186 const cJSON* value = cJSON_GetObjectItem(jsonObj, key.c_str());
187 if (value == NULL || !cJSON_IsNumber(value)) {
188 return false;
189 }
190 return (value->valuedouble >= INT32_MIN && value->valuedouble <= INT32_MAX);
191 }
192
IsUInt32(const cJSON* jsonObj, const std::string& key)193 bool IsUInt32(const cJSON* jsonObj, const std::string& key)
194 {
195 const cJSON* value = cJSON_GetObjectItem(jsonObj, key.c_str());
196 if (value == NULL || !cJSON_IsNumber(value)) {
197 return false;
198 }
199 return (value->valuedouble >= 0 && value->valuedouble <= UINT32_MAX);
200 }
201
IsBool(const cJSON* jsonObj, const std::string& key)202 bool IsBool(const cJSON* jsonObj, const std::string& key)
203 {
204 const cJSON* value = cJSON_GetObjectItem(jsonObj, key.c_str());
205 return (value != NULL && cJSON_IsBool(value));
206 }
207
IsString(const cJSON* jsonObj, const std::string& key)208 bool IsString(const cJSON* jsonObj, const std::string& key)
209 {
210 const cJSON* value = cJSON_GetObjectItem(jsonObj, key.c_str());
211 if (value == NULL || !cJSON_IsString(value)) {
212 return false;
213 }
214 return (strlen(value->valuestring) > MIN_MESSAGE_LEN && strlen(value->valuestring) <= MAX_MESSAGE_LEN);
215 }
216
IsArray(const cJSON* jsonObj, const std::string& key)217 bool IsArray(const cJSON* jsonObj, const std::string& key)
218 {
219 const cJSON* value = cJSON_GetObjectItem(jsonObj, key.c_str());
220 if (value == NULL || !cJSON_IsArray(value)) {
221 return false;
222 }
223 return ((uint32_t)cJSON_GetArraySize(value) >= 0 && (uint32_t)cJSON_GetArraySize(value) <= MAX_ARR_SIZE);
224 }
225
Compress(const std::string& data)226 std::string Compress(const std::string& data)
227 {
228 z_stream strm;
229 strm.zalloc = Z_NULL;
230 strm.zfree = Z_NULL;
231 strm.opaque = Z_NULL;
232 deflateInit(&strm, Z_DEFAULT_COMPRESSION);
233
234 strm.next_in = reinterpret_cast<Bytef*>(const_cast<char *>(data.data()));
235 strm.avail_in = data.size();
236 std::string out;
237 std::vector<Bytef> temp_out(COMPRESS_SLICE_SIZE, 0);
238
239 do {
240 strm.next_out = temp_out.data();
241 strm.avail_out = COMPRESS_SLICE_SIZE;
242 deflate(&strm, Z_FINISH);
243 out.append(reinterpret_cast<char*>(temp_out.data()), COMPRESS_SLICE_SIZE - strm.avail_out);
244 } while (strm.avail_out == 0);
245
246 deflateEnd(&strm);
247 return out;
248 }
249
Decompress(const std::string& data)250 std::string Decompress(const std::string& data)
251 {
252 z_stream strm;
253 strm.zalloc = Z_NULL;
254 strm.zfree = Z_NULL;
255 strm.opaque = Z_NULL;
256 strm.avail_in = 0;
257 strm.next_in = Z_NULL;
258 inflateInit(&strm);
259
260 strm.next_in = reinterpret_cast<Bytef*>(const_cast<char *>(data.data()));
261 strm.avail_in = data.size();
262 std::string out;
263 std::vector<Bytef> temp_out(COMPRESS_SLICE_SIZE, 0);
264
265 do {
266 strm.next_out = temp_out.data();
267 strm.avail_out = COMPRESS_SLICE_SIZE;
268 inflate(&strm, Z_NO_FLUSH);
269 out.append(reinterpret_cast<char*>(temp_out.data()), COMPRESS_SLICE_SIZE - strm.avail_out);
270 } while (strm.avail_out == 0);
271
272 inflateEnd(&strm);
273 return out;
274 }
275
GetSysPara(const char *key, bool &value)276 bool GetSysPara(const char *key, bool &value)
277 {
278 if (key == nullptr) {
279 DHLOGE("GetSysPara: key is nullptr");
280 return false;
281 }
282 char paraValue[20] = {0}; // 20 for system parameter
283 auto res = GetParameter(key, "false", paraValue, sizeof(paraValue));
284 if (res <= 0) {
285 DHLOGD("GetSysPara fail, key:%{public}s res:%{public}d", key, res);
286 return false;
287 }
288 DHLOGI("GetSysPara: key:%{public}s value:%{public}s", key, paraValue);
289 std::stringstream valueStr;
290 valueStr << paraValue;
291 valueStr >> std::boolalpha >> value;
292 return true;
293 }
294
IsIdLengthValid(const std::string &inputID)295 bool IsIdLengthValid(const std::string &inputID)
296 {
297 if (inputID.empty() || inputID.length() > MAX_ID_LEN) {
298 DHLOGE("On parameter length error, maybe empty or beyond MAX_ID_LEN!");
299 return false;
300 }
301 return true;
302 }
303
IsMessageLengthValid(const std::string &inputMessage)304 bool IsMessageLengthValid(const std::string &inputMessage)
305 {
306 if (inputMessage.empty() || inputMessage.length() > MAX_MESSAGE_LEN) {
307 DHLOGE("On parameter error, maybe empty or beyond MAX_MESSAGE_LEN!");
308 return false;
309 }
310 return true;
311 }
312
IsJsonLengthValid(const std::string &inputJsonStr)313 bool IsJsonLengthValid(const std::string &inputJsonStr)
314 {
315 if (inputJsonStr.empty() || inputJsonStr.length() > MAX_JSON_SIZE) {
316 DHLOGE("On parameter error, maybe empty or beyond MAX_JSON_SIZE");
317 return false;
318 }
319 return true;
320 }
321
IsArrayLengthValid(const std::vector<std::string> &inputArray)322 bool IsArrayLengthValid(const std::vector<std::string> &inputArray)
323 {
324 if (inputArray.empty() || inputArray.size() > MAX_ARR_SIZE) {
325 DHLOGE("On parameter error, maybe empty or beyond MAX_ARR_SIZE");
326 return false;
327 }
328 return true;
329 }
330
IsKeySizeValid(const std::string &inputKey)331 bool IsKeySizeValid(const std::string &inputKey)
332 {
333 if (inputKey.empty() || inputKey.length() > MAX_KEY_SIZE) {
334 DHLOGE("On parameter error, maybe empty or beyond MAX_KEY_SIZE");
335 return false;
336 }
337 return true;
338 }
339
IsHashSizeValid(const std::string &inputHashValue)340 bool IsHashSizeValid(const std::string &inputHashValue)
341 {
342 if (inputHashValue.empty() || inputHashValue.length() > MAX_HASH_SIZE) {
343 DHLOGE("On parameter error, maybe empty or beyond MAX_HASH_SIZE");
344 return false;
345 }
346 return true;
347 }
348
GetDeviceSystemType(const std::string &extraData)349 int32_t GetDeviceSystemType(const std::string &extraData)
350 {
351 cJSON *jsonObj = cJSON_Parse(extraData.c_str());
352 if (jsonObj == NULL) {
353 DHLOGE("jsonStr parse failed");
354 return ERR_DH_FWK_INVALID_OSTYPE;
355 }
356 cJSON *paramKey = cJSON_GetObjectItem(jsonObj, PARAM_KEY_OS_TYPE.c_str());
357 if (paramKey == NULL || !cJSON_IsNumber(paramKey)) {
358 DHLOGE("paramKey is null or paramKey is invaild type!");
359 cJSON_Delete(jsonObj);
360 return ERR_DH_FWK_INVALID_OSTYPE;
361 }
362 int32_t osType = paramKey->valueint;
363 cJSON_Delete(jsonObj);
364 return osType;
365 }
366 } // namespace DistributedHardware
367 } // namespace OHOS
368