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