• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "auth_hichain.h"
17 
18 #include <securec.h>
19 #include "auth_common.h"
20 #include "auth_hichain_adapter.h"
21 #include "auth_session_fsm.h"
22 #include "device_auth.h"
23 #include "bus_center_manager.h"
24 #include "device_auth_defines.h"
25 #include "softbus_adapter_mem.h"
26 #include "softbus_def.h"
27 #include "softbus_json_utils.h"
28 
29 #define AUTH_APPID "softbus_auth"
30 #define GROUPID_BUF_LEN 65
31 #define ONTRANSMIT_MAX_DATA_BUFFER_LEN 5120 /* 5 × 1024 */
32 
33 typedef struct {
34     char groupId[GROUPID_BUF_LEN];
35     GroupType groupType;
36 } GroupInfo;
37 
38 static TrustDataChangeListener g_dataChangeListener;
39 
GenDeviceLevelParam(const char * udid,const char * uid,bool isClient)40 static char *GenDeviceLevelParam(const char *udid, const char *uid, bool isClient)
41 {
42     cJSON *msg = cJSON_CreateObject();
43     if (msg == NULL) {
44         ALOGE("create json fail.");
45         return NULL;
46     }
47     if (!AddStringToJsonObject(msg, FIELD_PEER_CONN_DEVICE_ID, udid) ||
48         !AddStringToJsonObject(msg, FIELD_SERVICE_PKG_NAME, AUTH_APPID) ||
49         !AddBoolToJsonObject(msg, FIELD_IS_DEVICE_LEVEL, true) ||
50         !AddBoolToJsonObject(msg, FIELD_IS_CLIENT, isClient) ||
51         !AddBoolToJsonObject(msg, FIELD_IS_UDID_HASH, false) ||
52         !AddNumberToJsonObject(msg, FIELD_KEY_LENGTH, SESSION_KEY_LENGTH)) {
53         ALOGE("add json object fail.");
54         cJSON_Delete(msg);
55         return NULL;
56     }
57 #ifdef AUTH_ACCOUNT
58     ALOGI("in account auth mode");
59     if (!AddStringToJsonObject(msg, FIELD_UID_HASH, uid)) {
60         ALOGE("add uid into json fail.");
61         cJSON_Delete(msg);
62         return NULL;
63     }
64 #endif
65     char *data = cJSON_PrintUnformatted(msg);
66     if (data == NULL) {
67         ALOGE("cJSON_PrintUnformatted fail.");
68     }
69     cJSON_Delete(msg);
70     return data;
71 }
72 
OnTransmit(int64_t authSeq,const uint8_t * data,uint32_t len)73 NO_SANITIZE("cfi") static bool OnTransmit(int64_t authSeq, const uint8_t *data, uint32_t len)
74 {
75     ALOGI("hichain OnTransmit: authSeq=%" PRId64 ", len=%u.", authSeq, len);
76     if (len > ONTRANSMIT_MAX_DATA_BUFFER_LEN) {
77         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "data len is invalid, len=%u", len);
78         return false;
79     }
80     if (AuthSessionPostAuthData(authSeq, data, len) != SOFTBUS_OK) {
81         ALOGE("hichain OnTransmit fail: authSeq=%" PRId64, authSeq);
82         return false;
83     }
84     return true;
85 }
86 
OnSessionKeyReturned(int64_t authSeq,const uint8_t * sessionKey,uint32_t sessionKeyLen)87 NO_SANITIZE("cfi") static void OnSessionKeyReturned(int64_t authSeq, const uint8_t *sessionKey, uint32_t sessionKeyLen)
88 {
89     ALOGI("hichain OnSessionKeyReturned: authSeq=%" PRId64 ", len=%u.", authSeq, sessionKeyLen);
90     if (sessionKey == NULL || sessionKeyLen > SESSION_KEY_LENGTH) {
91         ALOGE("invalid sessionKey.");
92         return;
93     }
94     (void)AuthSessionSaveSessionKey(authSeq, sessionKey, sessionKeyLen);
95 }
96 
OnFinish(int64_t authSeq,int operationCode,const char * returnData)97 NO_SANITIZE("cfi") static void OnFinish(int64_t authSeq, int operationCode, const char *returnData)
98 {
99     (void)operationCode;
100     (void)returnData;
101     ALOGI("hichain OnFinish: authSeq=%" PRId64 ".", authSeq);
102     (void)AuthSessionHandleAuthFinish(authSeq);
103 }
104 
OnError(int64_t authSeq,int operationCode,int errCode,const char * errorReturn)105 NO_SANITIZE("cfi") static void OnError(int64_t authSeq, int operationCode, int errCode, const char *errorReturn)
106 {
107     (void)operationCode;
108     (void)errorReturn;
109     ALOGE("hichain OnError: authSeq=%" PRId64 ", errCode=%d.", authSeq, errCode);
110     (void)AuthSessionHandleAuthError(authSeq, SOFTBUS_AUTH_HICHAIN_AUTH_ERROR);
111 }
112 
OnRequest(int64_t authSeq,int operationCode,const char * reqParams)113 NO_SANITIZE("cfi") static char *OnRequest(int64_t authSeq, int operationCode, const char *reqParams)
114 {
115     (void)reqParams;
116     ALOGI("hichain OnRequest: authSeq=%" PRId64 ", operationCode=%d.", authSeq, operationCode);
117     char udid[UDID_BUF_LEN] = {0};
118     if (AuthSessionGetUdid(authSeq, udid, sizeof(udid)) != SOFTBUS_OK) {
119         ALOGE("get udid fail.");
120         return NULL;
121     }
122     cJSON *msg = cJSON_CreateObject();
123     if (msg == NULL) {
124         return NULL;
125     }
126     char localUdid[UDID_BUF_LEN] = {0};
127     LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, localUdid, UDID_BUF_LEN);
128     if (!AddNumberToJsonObject(msg, FIELD_CONFIRMATION, REQUEST_ACCEPTED) ||
129         !AddStringToJsonObject(msg, FIELD_SERVICE_PKG_NAME, AUTH_APPID) ||
130         !AddStringToJsonObject(msg, FIELD_PEER_CONN_DEVICE_ID, udid) ||
131         !AddStringToJsonObject(msg, FIELD_DEVICE_ID, localUdid) ||
132         !AddBoolToJsonObject(msg, FIELD_IS_UDID_HASH, false)) {
133         ALOGE("pack request msg fail.");
134         cJSON_Delete(msg);
135         return NULL;
136     }
137     char *msgStr = cJSON_PrintUnformatted(msg);
138     if (msgStr == NULL) {
139         ALOGE("cJSON_PrintUnformatted fail.");
140         cJSON_Delete(msg);
141         return NULL;
142     }
143     cJSON_Delete(msg);
144     return msgStr;
145 }
146 
147 static DeviceAuthCallback g_hichainCallback = {
148     .onTransmit = OnTransmit,
149     .onSessionKeyReturned = OnSessionKeyReturned,
150     .onFinish = OnFinish,
151     .onError = OnError,
152     .onRequest = OnRequest
153 };
154 
ParseGroupInfo(const char * groupInfoStr,GroupInfo * groupInfo)155 static int32_t ParseGroupInfo(const char *groupInfoStr, GroupInfo *groupInfo)
156 {
157     cJSON *msg = cJSON_Parse(groupInfoStr);
158     if (msg == NULL) {
159         ALOGE("parse json fail.");
160         return SOFTBUS_ERR;
161     }
162     if (!GetJsonObjectStringItem(msg, FIELD_GROUP_ID, groupInfo->groupId, GROUPID_BUF_LEN)) {
163         ALOGE("get FIELD_GROUP_ID fail.");
164         cJSON_Delete(msg);
165         return SOFTBUS_ERR;
166     }
167     int32_t groupType = 0;
168     if (!GetJsonObjectNumberItem(msg, FIELD_GROUP_TYPE, &groupType)) {
169         ALOGE("get FIELD_GROUP_TYPE fail.");
170         cJSON_Delete(msg);
171         return SOFTBUS_ERR;
172     }
173     groupInfo->groupType = (GroupType)groupType;
174     cJSON_Delete(msg);
175     return SOFTBUS_OK;
176 }
177 
OnGroupCreated(const char * groupInfo)178 NO_SANITIZE("cfi") static void OnGroupCreated(const char *groupInfo)
179 {
180     if (groupInfo == NULL) {
181         ALOGE("invalid group info.");
182         return;
183     }
184     GroupInfo info;
185     if (ParseGroupInfo(groupInfo, &info) != SOFTBUS_OK) {
186         return;
187     }
188     ALOGI("hichain OnGroupCreated, type=%d", info.groupType);
189     if (g_dataChangeListener.onGroupCreated != NULL) {
190         g_dataChangeListener.onGroupCreated(info.groupId, (int32_t)info.groupType);
191     }
192 }
193 
OnDeviceBound(const char * udid,const char * groupInfo)194 NO_SANITIZE("cfi") static void OnDeviceBound(const char *udid, const char *groupInfo)
195 {
196     if (udid == NULL || groupInfo == NULL) {
197         ALOGE("invalid udid");
198         return;
199     }
200     ALOGI("hichain onDeviceBound");
201     if (g_dataChangeListener.onDeviceBound != NULL) {
202         g_dataChangeListener.onDeviceBound(udid, groupInfo);
203     }
204 }
205 
OnGroupDeleted(const char * groupInfo)206 NO_SANITIZE("cfi") static void OnGroupDeleted(const char *groupInfo)
207 {
208     if (groupInfo == NULL) {
209         ALOGE("invalid group info.");
210         return;
211     }
212     GroupInfo info;
213     if (ParseGroupInfo(groupInfo, &info) != SOFTBUS_OK) {
214         return;
215     }
216     ALOGI("hichain OnGroupDeleted, type=%d", info.groupType);
217     if (g_dataChangeListener.onGroupDeleted != NULL) {
218         g_dataChangeListener.onGroupDeleted(info.groupId);
219     }
220 }
221 
OnDeviceNotTrusted(const char * udid)222 NO_SANITIZE("cfi") static void OnDeviceNotTrusted(const char *udid)
223 {
224     if (udid == NULL) {
225         ALOGE("hichain OnDeviceNotTrusted get invalid udid.");
226         return;
227     }
228     char *anoyUdid = NULL;
229     ALOGI("hichain OnDeviceNotTrusted, udid:%s", ToSecureStrDeviceID(udid, &anoyUdid));
230     SoftBusFree(anoyUdid);
231     if (g_dataChangeListener.onDeviceNotTrusted != NULL) {
232         g_dataChangeListener.onDeviceNotTrusted(udid);
233     }
234 }
235 
RegTrustDataChangeListener(const TrustDataChangeListener * listener)236 NO_SANITIZE("cfi") int32_t RegTrustDataChangeListener(const TrustDataChangeListener *listener)
237 {
238     if (listener == NULL) {
239         return SOFTBUS_INVALID_PARAM;
240     }
241     g_dataChangeListener = *listener;
242 
243     DataChangeListener hichainListener;
244     (void)memset_s(&hichainListener, sizeof(DataChangeListener), 0, sizeof(DataChangeListener));
245     hichainListener.onGroupCreated = OnGroupCreated;
246     hichainListener.onGroupDeleted = OnGroupDeleted;
247     hichainListener.onDeviceNotTrusted = OnDeviceNotTrusted;
248     hichainListener.onDeviceBound = OnDeviceBound;
249     if (RegChangeListener(AUTH_APPID, &hichainListener) != SOFTBUS_OK) {
250         ALOGE("hichain regDataChangeListener fail.");
251         return SOFTBUS_ERR;
252     }
253     return SOFTBUS_OK;
254 }
255 
UnregTrustDataChangeListener(void)256 NO_SANITIZE("cfi") void UnregTrustDataChangeListener(void)
257 {
258     int32_t ret = UnregChangeListener(AUTH_APPID);
259     if (ret != 0) {
260         ALOGE("hichain unRegDataChangeListener fail(err=%d).", ret);
261     }
262     (void)memset_s(&g_dataChangeListener, sizeof(TrustDataChangeListener), 0, sizeof(TrustDataChangeListener));
263 }
264 
HichainStartAuth(int64_t authSeq,const char * udid,const char * uid)265 NO_SANITIZE("cfi") int32_t HichainStartAuth(int64_t authSeq, const char *udid, const char *uid)
266 {
267     if (udid == NULL || uid == NULL) {
268         ALOGE("udid/uid is invalid.");
269         return SOFTBUS_INVALID_PARAM;
270     }
271     char *authParams = GenDeviceLevelParam(udid, uid, true);
272     if (authParams == NULL) {
273         ALOGE("generate auth param fail.");
274         return SOFTBUS_ERR;
275     }
276     if (AuthDevice(authSeq, authParams, &g_hichainCallback) == SOFTBUS_OK) {
277         ALOGI("hichain call authDevice succ");
278         cJSON_free(authParams);
279         return SOFTBUS_OK;
280     }
281     ALOGE("hichain call authDevice failed");
282     cJSON_free(authParams);
283     return SOFTBUS_ERR;
284 }
285 
HichainProcessData(int64_t authSeq,const uint8_t * data,uint32_t len)286 NO_SANITIZE("cfi") int32_t HichainProcessData(int64_t authSeq, const uint8_t *data, uint32_t len)
287 {
288     if (data == NULL) {
289         return SOFTBUS_INVALID_PARAM;
290     }
291     int32_t ret = ProcessAuthData(authSeq, data, len, &g_hichainCallback);
292     if (ret != SOFTBUS_OK) {
293         ALOGE("hichain processData fail(err = %d).", ret);
294         return SOFTBUS_ERR;
295     }
296     return SOFTBUS_OK;
297 }
298 
HichainDestroy(void)299 NO_SANITIZE("cfi") void HichainDestroy(void)
300 {
301     UnregTrustDataChangeListener();
302     DestroyDeviceAuth();
303     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "hichain destroy succ.");
304 }
305