1 /*
2 * Copyright (c) 2023-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 "disc_coap_parser.h"
17
18 #include "anonymizer.h"
19 #include "disc_log.h"
20 #include "securec.h"
21
22 #include "softbus_adapter_crypto.h"
23 #include "softbus_error_code.h"
24 #include "softbus_utils.h"
25
26 #define JSON_WLAN_IP "wifiIpAddr"
27 #define JSON_HW_ACCOUNT "hwAccountHashVal"
28 #define JSON_KEY_CAST_PLUS "castPlus"
29
30 #define HEX_HASH_LEN 16
31
DiscCoapParseDeviceUdid(const char * raw,DeviceInfo * device)32 int32_t DiscCoapParseDeviceUdid(const char *raw, DeviceInfo *device)
33 {
34 DISC_CHECK_AND_RETURN_RET_LOGE(raw != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "raw string is NULL");
35 DISC_CHECK_AND_RETURN_RET_LOGE(device != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "device info is NULL");
36
37 cJSON *udidJson = cJSON_Parse(raw);
38 DISC_CHECK_AND_RETURN_RET_LOGE(udidJson != NULL, SOFTBUS_PARSE_JSON_ERR, DISC_COAP, "parse udid json failed");
39 char tmpUdid[DISC_MAX_DEVICE_ID_LEN] = {0};
40 if (!GetJsonObjectStringItem(udidJson, DEVICE_UDID, tmpUdid, DISC_MAX_DEVICE_ID_LEN)) {
41 cJSON_Delete(udidJson);
42 DISC_LOGE(DISC_COAP, "parse remote udid failed");
43 return SOFTBUS_PARSE_JSON_ERR;
44 }
45 char *anonymizedStr;
46 Anonymize(tmpUdid, &anonymizedStr);
47 DISC_LOGI(DISC_COAP, "devId=%{public}s", AnonymizeWrapper(anonymizedStr));
48 AnonymizeFree(anonymizedStr);
49 cJSON_Delete(udidJson);
50
51 int32_t ret = GenerateStrHashAndConvertToHexString((const unsigned char *)tmpUdid, HEX_HASH_LEN,
52 (unsigned char *)device->devId, HEX_HASH_LEN + 1);
53 DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP,
54 "generate udid hex hash failed, ret=%{public}d", ret);
55 return SOFTBUS_OK;
56 }
57
DiscCoapParseWifiIpAddr(const cJSON * data,DeviceInfo * device)58 void DiscCoapParseWifiIpAddr(const cJSON *data, DeviceInfo *device)
59 {
60 DISC_CHECK_AND_RETURN_LOGE(data != NULL, DISC_COAP, "json data is NULL");
61 DISC_CHECK_AND_RETURN_LOGE(device != NULL, DISC_COAP, "device info is NULL");
62 if (!GetJsonObjectStringItem(data, JSON_WLAN_IP, device->addr[0].info.ip.ip, sizeof(device->addr[0].info.ip.ip))) {
63 DISC_LOGE(DISC_COAP, "parse wifi ip address failed.");
64 return;
65 }
66 device->addrNum = 1;
67 char *anonymizedStr;
68 Anonymize(device->addr[0].info.ip.ip, &anonymizedStr);
69 DISC_LOGD(DISC_COAP, "ip=%{public}s", AnonymizeWrapper(anonymizedStr));
70 AnonymizeFree(anonymizedStr);
71 }
72
DiscCoapParseKeyValueStr(const char * src,const char * key,char * outValue,uint32_t outLen)73 int32_t DiscCoapParseKeyValueStr(const char *src, const char *key, char *outValue, uint32_t outLen)
74 {
75 DISC_CHECK_AND_RETURN_RET_LOGE(src != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "src is NULL");
76 DISC_CHECK_AND_RETURN_RET_LOGE(key != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "key is NULL");
77 DISC_CHECK_AND_RETURN_RET_LOGE(outValue != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "outValue is NULL");
78 DISC_CHECK_AND_RETURN_RET_LOGE(strlen(src) < DISC_MAX_CUST_DATA_LEN, SOFTBUS_INVALID_PARAM, DISC_COAP,
79 "src len >= max len. srcLen=%{public}zu, maxLen=%{public}u", strlen(src), DISC_MAX_CUST_DATA_LEN);
80
81 char tmpSrc[DISC_MAX_CUST_DATA_LEN] = {0};
82 if (memcpy_s(tmpSrc, DISC_MAX_CUST_DATA_LEN, src, strlen(src)) != EOK) {
83 DISC_LOGE(DISC_COAP, "copy src failed");
84 return SOFTBUS_MEM_ERR;
85 }
86
87 const char *delimiter = ",";
88 char *curValue = NULL;
89 char *remainStr = NULL;
90 char *curStr = strtok_s(tmpSrc, delimiter, &remainStr);
91 while (curStr != NULL) {
92 curValue = strchr(curStr, ':');
93 if (curValue == NULL) {
94 DISC_LOGW(DISC_COAP, "invalid kvStr item: curStr=%{public}s", curStr);
95 curStr = strtok_s(NULL, delimiter, &remainStr);
96 continue;
97 }
98
99 *curValue = '\0';
100 curValue++;
101 if (strcmp((const char *)curStr, key) != 0) {
102 curStr = strtok_s(NULL, delimiter, &remainStr);
103 continue;
104 }
105 if (strcpy_s(outValue, outLen, curValue) != EOK) {
106 DISC_LOGE(DISC_COAP, "copy value failed");
107 return SOFTBUS_STRCPY_ERR;
108 }
109 return SOFTBUS_OK;
110 }
111 DISC_LOGE(DISC_COAP, "cannot find the key: key=%{public}s", key);
112 return SOFTBUS_DISCOVER_COAP_PARSE_DATA_FAIL;
113 }
114
DiscCoapParseServiceData(const cJSON * data,DeviceInfo * device)115 int32_t DiscCoapParseServiceData(const cJSON *data, DeviceInfo *device)
116 {
117 DISC_CHECK_AND_RETURN_RET_LOGE(data != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "json data is NULL");
118 DISC_CHECK_AND_RETURN_RET_LOGE(device != NULL, SOFTBUS_INVALID_PARAM, DISC_COAP, "device info is NULL");
119 char serviceData[MAX_SERVICE_DATA_LEN] = {0};
120 if (!GetJsonObjectStringItem(data, JSON_SERVICE_DATA, serviceData, sizeof(serviceData))) {
121 DISC_LOGD(DISC_COAP, "parse service data failed.");
122 return SOFTBUS_PARSE_JSON_ERR;
123 }
124 char port[MAX_PORT_STR_LEN] = {0};
125 int32_t ret = DiscCoapParseKeyValueStr(serviceData, SERVICE_DATA_PORT, port, MAX_PORT_STR_LEN);
126 DISC_CHECK_AND_RETURN_RET_LOGE(ret == SOFTBUS_OK, ret, DISC_COAP, "parse service data failed");
127 int32_t authPort = atoi(port);
128 if (authPort <= 0 || authPort > UINT16_MAX) {
129 DISC_LOGE(DISC_COAP, "the auth port is invalid. authPort=%{public}d", authPort);
130 return SOFTBUS_DISCOVER_COAP_PARSE_DATA_FAIL;
131 }
132 device->addr[0].info.ip.port = (uint16_t)authPort;
133 return SOFTBUS_OK;
134 }
135
DiscCoapParseHwAccountHash(const cJSON * data,DeviceInfo * device)136 void DiscCoapParseHwAccountHash(const cJSON *data, DeviceInfo *device)
137 {
138 DISC_CHECK_AND_RETURN_LOGE(data != NULL, DISC_COAP, "json data is NULL");
139 DISC_CHECK_AND_RETURN_LOGE(device != NULL, DISC_COAP, "device info is NULL");
140 char tmpAccount[MAX_ACCOUNT_HASH_LEN] = {0};
141 if (!GetJsonObjectStringItem(data, JSON_HW_ACCOUNT, tmpAccount, MAX_ACCOUNT_HASH_LEN)) {
142 DISC_LOGE(DISC_COAP, "parse accountId failed");
143 return;
144 }
145
146 int32_t ret = SoftBusGenerateStrHash((const unsigned char *)tmpAccount, strlen(tmpAccount),
147 (unsigned char *)device->accountHash);
148 DISC_CHECK_AND_RETURN_LOGE(ret == SOFTBUS_OK, DISC_COAP, "generate account hash failed, ret=%{public}d", ret);
149 }
150