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