• 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 
20 #include "auth_common.h"
21 #include "auth_session_fsm.h"
22 #include "device_auth.h"
23 #include "device_auth_defines.h"
24 #include "softbus_json_utils.h"
25 
26 #define AUTH_APPID "softbus_auth"
27 #define GROUPID_BUF_LEN 65
28 #define RETRY_TIMES 16
29 #define RETRY_MILLSECONDS 500
30 
31 typedef struct {
32     char groupId[GROUPID_BUF_LEN];
33     GroupType groupType;
34     GroupVisibility groupVisibility;
35 } GroupInfo;
36 
37 static const GroupAuthManager *g_hichain = NULL;
38 static TrustDataChangeListener g_dataChangeListener = {0};
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         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "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_CLIENT, isClient) ||
50         !AddNumberToJsonObject(msg, FIELD_KEY_LENGTH, SESSION_KEY_LENGTH)) {
51         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "add json object fail.");
52         cJSON_Delete(msg);
53         return NULL;
54     }
55 #ifdef AUTH_ACCOUNT
56     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "in account auth mode");
57     if (!AddStringToJsonObject(msg, FIELD_UID_HASH, uid)) {
58         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "add uid into json fail.");
59         cJSON_Delete(msg);
60         return NULL;
61     }
62 #endif
63     char *data = cJSON_PrintUnformatted(msg);
64     if (data == NULL) {
65         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "cJSON_PrintUnformatted fail.");
66     }
67     cJSON_Delete(msg);
68     return data;
69 }
70 
OnTransmit(int64_t authSeq,const uint8_t * data,uint32_t len)71 static bool OnTransmit(int64_t authSeq, const uint8_t *data, uint32_t len)
72 {
73     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO,
74         "hichain OnTransmit: authSeq=%" PRId64 ", len=%u.", authSeq, len);
75     if (AuthSessionPostAuthData(authSeq, data, len) != SOFTBUS_OK) {
76         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain OnTransmit fail: authSeq=%" PRId64, authSeq);
77         return false;
78     }
79     return true;
80 }
81 
OnSessionKeyReturned(int64_t authSeq,const uint8_t * sessionKey,uint32_t sessionKeyLen)82 static void OnSessionKeyReturned(int64_t authSeq, const uint8_t *sessionKey, uint32_t sessionKeyLen)
83 {
84     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO,
85         "hichain OnSessionKeyReturned: authSeq=%" PRId64 ", len=%u.", authSeq, sessionKeyLen);
86     if (sessionKey == NULL || sessionKeyLen > SESSION_KEY_LENGTH) {
87         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid sessionKey.");
88         return;
89     }
90     (void)AuthSessionSaveSessionKey(authSeq, sessionKey, sessionKeyLen);
91 }
92 
OnFinish(int64_t authSeq,int operationCode,const char * returnData)93 static void OnFinish(int64_t authSeq, int operationCode, const char *returnData)
94 {
95     (void)operationCode;
96     (void)returnData;
97     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO,
98         "hichain OnFinish: authSeq=%" PRId64 ".", authSeq);
99     (void)AuthSessionHandleAuthResult(authSeq, SOFTBUS_OK);
100 }
101 
OnError(int64_t authSeq,int operationCode,int errCode,const char * errorReturn)102 static void OnError(int64_t authSeq, int operationCode, int errCode, const char *errorReturn)
103 {
104     (void)operationCode;
105     (void)errorReturn;
106     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR,
107         "hichain OnError: authSeq=%" PRId64 ", errCode=%d.", authSeq, errCode);
108     (void)AuthSessionHandleAuthResult(authSeq, SOFTBUS_AUTH_HICHAIN_AUTH_ERROR);
109 }
110 
OnRequest(int64_t authSeq,int operationCode,const char * reqParams)111 static char *OnRequest(int64_t authSeq, int operationCode, const char *reqParams)
112 {
113     (void)reqParams;
114     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO,
115         "hichain OnRequest: authSeq=%" PRId64 ", operationCode=%d.", authSeq, operationCode);
116     char udid[UDID_BUF_LEN] = {0};
117     if (AuthSessionGetUdid(authSeq, udid, sizeof(udid)) != SOFTBUS_OK) {
118         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "get udid fail.");
119         return NULL;
120     }
121     cJSON *msg = cJSON_CreateObject();
122     if (msg == NULL) {
123         return NULL;
124     }
125     if (!AddNumberToJsonObject(msg, FIELD_CONFIRMATION, REQUEST_ACCEPTED) ||
126         !AddStringToJsonObject(msg, FIELD_SERVICE_PKG_NAME, AUTH_APPID) ||
127         !AddStringToJsonObject(msg, FIELD_PEER_CONN_DEVICE_ID, udid)) {
128         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "pack request msg fail.");
129         cJSON_Delete(msg);
130         return NULL;
131     }
132     char *msgStr = cJSON_PrintUnformatted(msg);
133     if (msgStr == NULL) {
134         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "cJSON_PrintUnformatted fail.");
135         cJSON_Delete(msg);
136         return NULL;
137     }
138     cJSON_Delete(msg);
139     return msgStr;
140 }
141 
142 static DeviceAuthCallback g_hichainCallback = {
143     .onTransmit = OnTransmit,
144     .onSessionKeyReturned = OnSessionKeyReturned,
145     .onFinish = OnFinish,
146     .onError = OnError,
147     .onRequest = OnRequest
148 };
149 
ParseGroupInfo(const char * groupInfoStr,GroupInfo * groupInfo)150 static int32_t ParseGroupInfo(const char *groupInfoStr, GroupInfo *groupInfo)
151 {
152     cJSON *msg = cJSON_Parse(groupInfoStr);
153     if (msg == NULL) {
154         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "parse json fail.");
155         return SOFTBUS_ERR;
156     }
157     if (!GetJsonObjectStringItem(msg, FIELD_GROUP_ID, groupInfo->groupId, GROUPID_BUF_LEN)) {
158         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "get FIELD_GROUP_ID fail.");
159         cJSON_Delete(msg);
160         return SOFTBUS_ERR;
161     }
162     int32_t groupType = 0;
163     if (!GetJsonObjectNumberItem(msg, FIELD_GROUP_TYPE, &groupType)) {
164         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "get FIELD_GROUP_TYPE fail.");
165         cJSON_Delete(msg);
166         return SOFTBUS_ERR;
167     }
168     groupInfo->groupType = (GroupType)groupType;
169     cJSON_Delete(msg);
170     return SOFTBUS_OK;
171 }
172 
OnGroupCreated(const char * groupInfo)173 static void OnGroupCreated(const char *groupInfo)
174 {
175     if (groupInfo == NULL) {
176         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid group info.");
177         return;
178     }
179     GroupInfo info;
180     if (ParseGroupInfo(groupInfo, &info) != SOFTBUS_OK) {
181         return;
182     }
183     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "hichain OnGroupCreated, type=%d", info.groupType);
184     if (g_dataChangeListener.onGroupCreated != NULL) {
185         g_dataChangeListener.onGroupCreated(info.groupId);
186     }
187 }
188 
OnGroupDeleted(const char * groupInfo)189 static void OnGroupDeleted(const char *groupInfo)
190 {
191     if (groupInfo == NULL) {
192         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid group info.");
193         return;
194     }
195     GroupInfo info;
196     if (ParseGroupInfo(groupInfo, &info) != SOFTBUS_OK) {
197         return;
198     }
199     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "hichain OnGroupDeleted, type=%d", info.groupType);
200     if (g_dataChangeListener.onGroupDeleted != NULL) {
201         g_dataChangeListener.onGroupDeleted(info.groupId);
202     }
203 }
204 
OnDeviceNotTrusted(const char * udid)205 static void OnDeviceNotTrusted(const char *udid)
206 {
207     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "hichain OnDeviceNotTrusted.");
208     if (udid == NULL) {
209         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "invalid udid.");
210         return;
211     }
212     if (g_dataChangeListener.onDeviceNotTrusted != NULL) {
213         g_dataChangeListener.onDeviceNotTrusted(udid);
214     }
215 }
216 
InitHichain(void)217 static const GroupAuthManager *InitHichain(void)
218 {
219     int32_t ret = InitDeviceAuthService();
220     if (ret != 0) {
221         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain InitDeviceAuthService fail(err = %d).", ret);
222         return NULL;
223     }
224     const GroupAuthManager *gaIns = GetGaInstance();
225     if (gaIns == NULL) {
226         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain GetGaInstance fail.");
227         DestroyDeviceAuthService();
228         return NULL;
229     }
230     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "hichain init succ.");
231     return gaIns;
232 }
233 
RegTrustDataChangeListener(const TrustDataChangeListener * listener)234 int32_t RegTrustDataChangeListener(const TrustDataChangeListener *listener)
235 {
236     if (listener == NULL) {
237         return SOFTBUS_INVALID_PARAM;
238     }
239 
240     if (g_hichain == NULL) {
241         g_hichain = InitHichain();
242     }
243     if (g_hichain == NULL) {
244         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain not initialized.");
245         return SOFTBUS_ERR;
246     }
247 
248     if (memcpy_s(&g_dataChangeListener, sizeof(g_dataChangeListener),
249         listener, sizeof(TrustDataChangeListener)) != EOK) {
250         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "copy data change listener fail.");
251         return SOFTBUS_MEM_ERR;
252     }
253 
254     DataChangeListener hichainListener;
255     (void)memset_s(&hichainListener, sizeof(DataChangeListener), 0, sizeof(DataChangeListener));
256     hichainListener.onGroupCreated = OnGroupCreated;
257     hichainListener.onGroupDeleted = OnGroupDeleted;
258     hichainListener.onDeviceNotTrusted = OnDeviceNotTrusted;
259     const DeviceGroupManager *gmInstance = GetGmInstance();
260     if (gmInstance == NULL) {
261         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain GetGmInstance fail.");
262         return SOFTBUS_ERR;
263     }
264     if (gmInstance->regDataChangeListener(AUTH_APPID, &hichainListener) != 0) {
265         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain regDataChangeListener fail.");
266         return SOFTBUS_ERR;
267     }
268     return SOFTBUS_OK;
269 }
270 
UnregTrustDataChangeListener(void)271 void UnregTrustDataChangeListener(void)
272 {
273     const DeviceGroupManager *gmInstance = GetGmInstance();
274     if (gmInstance == NULL) {
275         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain GetGmInstance fail.");
276         (void)memset_s(&g_dataChangeListener, sizeof(TrustDataChangeListener), 0,
277             sizeof(TrustDataChangeListener));
278         return;
279     }
280     int32_t ret = gmInstance->unRegDataChangeListener(AUTH_APPID);
281     if (ret != 0) {
282         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain unRegDataChangeListener fail(err=%d).", ret);
283     }
284     (void)memset_s(&g_dataChangeListener, sizeof(TrustDataChangeListener), 0, sizeof(TrustDataChangeListener));
285 }
286 
HichainStartAuth(int64_t authSeq,const char * udid,const char * uid)287 int32_t HichainStartAuth(int64_t authSeq, const char *udid, const char *uid)
288 {
289     if (udid == NULL || uid == NULL) {
290         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "udid/uid is invalid.");
291         return SOFTBUS_INVALID_PARAM;
292     }
293     if (g_hichain == NULL) {
294         g_hichain = InitHichain();
295     }
296     if (g_hichain == NULL) {
297         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain not initialized.");
298         return SOFTBUS_ERR;
299     }
300     char *authParams = GenDeviceLevelParam(udid, uid, true);
301     if (authParams == NULL) {
302         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "generate auth param fail.");
303         return SOFTBUS_ERR;
304     }
305     int32_t ret;
306     for (int i = 0; i < RETRY_TIMES; i++) {
307         ret = g_hichain->authDevice(ANY_OS_ACCOUNT, authSeq, authParams, &g_hichainCallback);
308         if (ret == HC_SUCCESS) {
309             SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "hichain authDevice sucess, time = %d", i + 1);
310             cJSON_free(authParams);
311             return SOFTBUS_OK;
312         }
313         if (ret == HC_ERR_INVALID_PARAMS) {
314             SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR,
315                 "hichain authDevice need to retry, current retry time = %d, err = %d", i + 1, ret);
316             (void)SoftBusSleepMs(RETRY_MILLSECONDS);
317         } else {
318             break;
319         }
320     }
321     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain authDevice fail, err = %d", ret);
322     cJSON_free(authParams);
323     return SOFTBUS_ERR;
324 }
325 
HichainProcessData(int64_t authSeq,const uint8_t * data,uint32_t len)326 int32_t HichainProcessData(int64_t authSeq, const uint8_t *data, uint32_t len)
327 {
328     if (data == NULL) {
329         return SOFTBUS_INVALID_PARAM;
330     }
331     if (g_hichain == NULL) {
332         g_hichain = InitHichain();
333     }
334     if (g_hichain == NULL) {
335         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain not initialized.");
336         return SOFTBUS_ERR;
337     }
338     int32_t ret = g_hichain->processData(authSeq, data, len, &g_hichainCallback);
339     if (ret != 0) {
340         SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_ERROR, "hichain processData fail(err = %d).", ret);
341         return SOFTBUS_ERR;
342     }
343     return SOFTBUS_OK;
344 }
345 
HichainDestroy(void)346 void HichainDestroy(void)
347 {
348     UnregTrustDataChangeListener();
349     DestroyDeviceAuthService();
350     g_hichain = NULL;
351     SoftBusLog(SOFTBUS_LOG_AUTH, SOFTBUS_LOG_INFO, "hichain destroy succ.");
352 }
353