1 /*
2  * Copyright (C) 2023 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 "save_trusted_info.h"
17 
18 #include "common_defs.h"
19 #include "data_manager.h"
20 #include "device_auth_defines.h"
21 #include "hc_dev_info.h"
22 #include "hc_log.h"
23 #include "hc_types.h"
24 
25 #define PEER_TO_PEER_GROUP 256
26 #define DEFAULT_EXPIRE_TIME 90
27 #define SELF_CREATED 0
28 
29 #define START_CMD_EVENT_NAME "StartCmd"
30 #define FAIL_EVENT_NAME "CmdFail"
31 
32 #define FIELD_GROUP_NAME "groupName"
33 #define FIELD_USER_TYPE_CLIENT "userTypeC"
34 #define FIELD_USER_TYPE_SERVER "userTypeS"
35 #define FIELD_AUTH_ID_CLIENT "authIdC"
36 #define FIELD_AUTH_ID_SERVER "authIdS"
37 #define FIELD_UDID_CLIENT "udidC"
38 #define FIELD_UDID_SERVER "udidS"
39 #define FIELD_USER_ID_CLIENT "userIdC"
40 #define FIELD_USER_ID_SERVER "userIdS"
41 
42 #define FIELD_EVENT "event"
43 #define FIELD_ERR_CODE "errCode"
44 #define FIELD_ERR_MSG "errMsg"
45 
46 typedef struct {
47     bool isGroupExistSelf;
48     bool isGroupExistPeer;
49     bool isBind;
50     int32_t osAccountId;
51     int32_t credType;
52     int32_t userTypeSelf;
53     int32_t userTypePeer;
54     int32_t visibility;
55     char *groupId;
56     char *groupName;
57     char *appId;
58     char *authIdSelf;
59     char *authIdPeer;
60     char *udidSelf;
61     char *udidPeer;
62     char *userIdSelf;
63     char *userIdPeer;
64 } CmdParams;
65 
66 typedef struct {
67     BaseCmd base;
68     CmdParams params;
69 } SaveTrustedInfoCmd;
70 
71 typedef enum {
72     START_EVENT = 0,
73     CLIENT_SEND_INFO_EVENT,
74     SERVER_SEND_INFO_EVENT,
75     FAIL_EVENT,
76     UNKNOWN_EVENT,
77 } EventEnum;
78 
79 typedef enum {
80     CREATE_AS_CLIENT_STATE = 0,
81     CREATE_AS_SERVER_STATE,
82     CLIENT_START_REQ_STATE,
83     /* FINISH STATE */
84     CLIENT_FINISH_STATE,
85     SERVER_FINISH_STATE,
86     /* FAIL STATE */
87     FAIL_STATE
88 } StateEnum;
89 
90 typedef struct {
91     int32_t curState;
92     int32_t eventType;
93     int32_t (*stateProcessFunc)(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent);
94     void (*exceptionHandleFunc)(int32_t errorCode, CJson **outputEvent);
95     int32_t nextState;
96 } CmdStateNode;
97 
GetGroupEntryById(int32_t osAccountId,const char * groupId)98 static TrustedGroupEntry *GetGroupEntryById(int32_t osAccountId, const char *groupId)
99 {
100     GroupEntryVec groupEntryVec = CreateGroupEntryVec();
101     QueryGroupParams params = InitQueryGroupParams();
102     params.groupId = groupId;
103     if (QueryGroups(osAccountId, &params, &groupEntryVec) != HC_SUCCESS) {
104         LOGE("Failed to query groups!");
105         ClearGroupEntryVec(&groupEntryVec);
106         return NULL;
107     }
108     uint32_t index;
109     TrustedGroupEntry **entry;
110     FOR_EACH_HC_VECTOR(groupEntryVec, index, entry) {
111         TrustedGroupEntry *returnEntry = DeepCopyGroupEntry(*entry);
112         ClearGroupEntryVec(&groupEntryVec);
113         return returnEntry;
114     }
115     ClearGroupEntryVec(&groupEntryVec);
116     return NULL;
117 }
118 
CheckGroupValidity(const CmdParams * params)119 static int32_t CheckGroupValidity(const CmdParams *params)
120 {
121 #ifdef DEV_AUTH_SAVE_TRUST_INFO_TEST
122     (void)params;
123     return HC_SUCCESS;
124 #else
125     if (params->isBind) {
126         return HC_SUCCESS;
127     }
128     TrustedGroupEntry *entry = GetGroupEntryById(params->osAccountId, params->groupId);
129     if (entry == NULL) {
130         LOGE("Auth expand process, group not exist!");
131         return HC_ERR_GROUP_NOT_EXIST;
132     }
133     DestroyGroupEntry(entry);
134     return HC_SUCCESS;
135 #endif
136 }
137 
ClientSendTrustedInfoProcEvent(CmdParams * params)138 static int32_t ClientSendTrustedInfoProcEvent(CmdParams *params)
139 {
140     char udid[INPUT_UDID_LEN] = { 0 };
141     int32_t res = HcGetUdid((uint8_t *)udid, INPUT_UDID_LEN);
142     if (res != HC_SUCCESS) {
143         LOGE("Failed to get local udid! res: %d", res);
144         return res;
145     }
146     if (DeepCopyString(udid, &params->udidSelf) != HC_SUCCESS) {
147         LOGE("copy udid fail.");
148         return HC_ERR_ALLOC_MEMORY;
149     }
150     res = CheckGroupValidity(params);
151     if (res != HC_SUCCESS) {
152         return res;
153     }
154     TrustedGroupEntry *entry = GetGroupEntryById(params->osAccountId, params->groupId);
155     if (entry == NULL) {
156         params->isGroupExistSelf = false;
157         return HC_SUCCESS;
158     }
159     params->isGroupExistSelf = true;
160     if (DeepCopyString(StringGet(&entry->name), &params->groupName) != HC_SUCCESS) {
161         LOGE("copy groupName fail.");
162         DestroyGroupEntry(entry);
163         return HC_ERR_ALLOC_MEMORY;
164     }
165     if ((entry->type != PEER_TO_PEER_GROUP) &&
166         (DeepCopyString(StringGet(&entry->userId), &params->userIdSelf) != HC_SUCCESS)) {
167         LOGE("copy userIdSelf fail.");
168         DestroyGroupEntry(entry);
169         return HC_ERR_ALLOC_MEMORY;
170     }
171     DestroyGroupEntry(entry);
172     return HC_SUCCESS;
173 }
174 
ClientSendTrustedInfoBuildEvent(const CmdParams * params,CJson ** outputEvent)175 static int32_t ClientSendTrustedInfoBuildEvent(const CmdParams *params, CJson **outputEvent)
176 {
177     CJson *json = CreateJson();
178     if (json == NULL) {
179         LOGE("create json failed.");
180         return HC_ERR_JSON_CREATE;
181     }
182     if (AddIntToJson(json, FIELD_EVENT, CLIENT_SEND_INFO_EVENT) != HC_SUCCESS) {
183         LOGE("add eventName to json fail.");
184         FreeJson(json);
185         return HC_ERR_JSON_ADD;
186     }
187     if (AddStringToJson(json, FIELD_AUTH_ID_CLIENT, params->authIdSelf) != HC_SUCCESS) {
188         LOGE("add authIdC to json fail.");
189         FreeJson(json);
190         return HC_ERR_JSON_ADD;
191     }
192     if (AddStringToJson(json, FIELD_UDID_CLIENT, params->udidSelf) != HC_SUCCESS) {
193         LOGE("add udidC to json fail.");
194         FreeJson(json);
195         return HC_ERR_JSON_ADD;
196     }
197     if (AddIntToJson(json, FIELD_USER_TYPE_CLIENT, params->userTypeSelf) != HC_SUCCESS) {
198         LOGE("add userTypeC to json fail.");
199         FreeJson(json);
200         return HC_ERR_JSON_ADD;
201     }
202     if (params->isGroupExistSelf) {
203         if (AddStringToJson(json, FIELD_GROUP_NAME, params->groupName) != HC_SUCCESS) {
204             LOGE("add groupName to json fail.");
205             FreeJson(json);
206             return HC_ERR_JSON_ADD;
207         }
208     }
209     if (params->userIdSelf != NULL) {
210         if (AddStringToJson(json, FIELD_USER_ID_CLIENT, params->userIdSelf) != HC_SUCCESS) {
211             LOGE("add userIdC to json fail.");
212             FreeJson(json);
213             return HC_ERR_JSON_ADD;
214         }
215     }
216     *outputEvent = json;
217     return HC_SUCCESS;
218 }
219 
ServerSendTrustedInfoParseEvent(const CJson * inputEvent,CmdParams * params)220 static int32_t ServerSendTrustedInfoParseEvent(const CJson *inputEvent, CmdParams *params)
221 {
222     const char *authId = GetStringFromJson(inputEvent, FIELD_AUTH_ID_CLIENT);
223     if (authId == NULL) {
224         LOGE("get authIdC from json fail.");
225         return HC_ERR_JSON_GET;
226     }
227     const char *udid = GetStringFromJson(inputEvent, FIELD_UDID_CLIENT);
228     if (udid == NULL) {
229         LOGE("get udidC from json fail.");
230         return HC_ERR_JSON_GET;
231     }
232     int32_t userTypeC;
233     if (GetIntFromJson(inputEvent, FIELD_USER_TYPE_CLIENT, &userTypeC) != HC_SUCCESS) {
234         LOGE("get userTypeC from json fail.");
235         return HC_ERR_JSON_GET;
236     }
237     if (DeepCopyString(authId, &(params->authIdPeer)) != HC_SUCCESS) {
238         LOGE("copy groupId fail.");
239         return HC_ERR_MEMORY_COPY;
240     }
241     if (DeepCopyString(udid, &(params->udidPeer)) != HC_SUCCESS) {
242         LOGE("copy groupId fail.");
243         return HC_ERR_MEMORY_COPY;
244     }
245     const char *groupName = GetStringFromJson(inputEvent, FIELD_GROUP_NAME);
246     if (groupName != NULL) {
247         if (DeepCopyString(groupName, &(params->groupName)) != HC_SUCCESS) {
248             LOGE("copy groupName fail.");
249             return HC_ERR_MEMORY_COPY;
250         }
251         params->isGroupExistPeer = true;
252     } else {
253         params->isGroupExistPeer = false;
254     }
255     const char *userId = GetStringFromJson(inputEvent, FIELD_USER_ID_CLIENT);
256     if (userId != NULL) {
257         if (DeepCopyString(userId, &(params->userIdPeer)) != HC_SUCCESS) {
258             LOGE("copy userId fail.");
259             return HC_ERR_MEMORY_COPY;
260         }
261     }
262     params->userTypePeer = userTypeC;
263     return HC_SUCCESS;
264 }
265 
GenerateGroupParams(const CmdParams * params,TrustedGroupEntry * groupParams)266 static int32_t GenerateGroupParams(const CmdParams *params, TrustedGroupEntry *groupParams)
267 {
268     if (!StringSetPointer(&groupParams->name, params->groupName)) {
269         LOGE("Failed to copy groupName!");
270         return HC_ERR_MEMORY_COPY;
271     }
272     if (!StringSetPointer(&groupParams->id, params->groupId)) {
273         LOGE("Failed to copy groupId!");
274         return HC_ERR_MEMORY_COPY;
275     }
276     HcString ownerName = CreateString();
277     if (!StringSetPointer(&ownerName, params->appId)) {
278         LOGE("Failed to copy groupOwner!");
279         DeleteString(&ownerName);
280         return HC_ERR_MEMORY_COPY;
281     }
282     if (groupParams->managers.pushBackT(&groupParams->managers, ownerName) == NULL) {
283         LOGE("Failed to push owner to vec!");
284         DeleteString(&ownerName);
285         return HC_ERR_MEMORY_COPY;
286     }
287     groupParams->visibility = params->visibility;
288     groupParams->type = PEER_TO_PEER_GROUP;
289     groupParams->expireTime = DEFAULT_EXPIRE_TIME;
290     return HC_SUCCESS;
291 }
292 
GeneratePeerDevParams(const CmdParams * params,TrustedDeviceEntry * devParams)293 static int32_t GeneratePeerDevParams(const CmdParams *params, TrustedDeviceEntry *devParams)
294 {
295     if (!StringSetPointer(&devParams->groupId, params->groupId)) {
296         LOGE("Failed to copy groupId!");
297         return HC_ERR_MEMORY_COPY;
298     }
299     if (!StringSetPointer(&devParams->udid, params->udidPeer)) {
300         LOGE("Failed to copy udid!");
301         return HC_ERR_MEMORY_COPY;
302     }
303     if (!StringSetPointer(&devParams->authId, params->authIdPeer)) {
304         LOGE("Failed to copy authId!");
305         return HC_ERR_MEMORY_COPY;
306     }
307     if (params->userIdPeer != NULL && !StringSetPointer(&devParams->userId, params->userIdPeer)) {
308         LOGE("Failed to copy serviceType!");
309         return HC_ERR_MEMORY_COPY;
310     }
311     if (!StringSetPointer(&devParams->serviceType, params->groupId)) {
312         LOGE("Failed to copy serviceType!");
313         return HC_ERR_MEMORY_COPY;
314     }
315     devParams->credential = params->credType;
316     devParams->devType = params->userTypePeer;
317     devParams->source = SELF_CREATED;
318     return HC_SUCCESS;
319 }
320 
GenerateSelfDevParams(const CmdParams * params,TrustedDeviceEntry * devParams)321 static int32_t GenerateSelfDevParams(const CmdParams *params, TrustedDeviceEntry *devParams)
322 {
323     if (!StringSetPointer(&devParams->udid, params->udidSelf)) {
324         LOGE("Failed to copy udid!");
325         return HC_ERR_MEMORY_COPY;
326     }
327     if (!StringSetPointer(&devParams->authId, params->authIdSelf)) {
328         LOGE("Failed to copy authId!");
329         return HC_ERR_MEMORY_COPY;
330     }
331     if (!StringSetPointer(&devParams->groupId, params->groupId)) {
332         LOGE("Failed to copy groupId!");
333         return HC_ERR_MEMORY_COPY;
334     }
335     if (!StringSetPointer(&devParams->serviceType, params->groupId)) {
336         LOGE("Failed to copy serviceType!");
337         return HC_ERR_MEMORY_COPY;
338     }
339     devParams->devType = params->userTypeSelf;
340     devParams->source = SELF_CREATED;
341     devParams->credential = params->credType;
342     return HC_SUCCESS;
343 }
344 
AddTrustedGroup(const CmdParams * params)345 static int32_t AddTrustedGroup(const CmdParams *params)
346 {
347     TrustedGroupEntry *groupParams = CreateGroupEntry();
348     if (groupParams == NULL) {
349         LOGE("Failed to allocate groupParams memory!");
350         return HC_ERR_ALLOC_MEMORY;
351     }
352     int32_t res = GenerateGroupParams(params, groupParams);
353     if (res != HC_SUCCESS) {
354         DestroyGroupEntry(groupParams);
355         return res;
356     }
357     res = AddGroup(params->osAccountId, groupParams);
358     DestroyGroupEntry(groupParams);
359     if (res != HC_SUCCESS) {
360         LOGE("Failed to add the group to the database!");
361     }
362     return res;
363 }
364 
IsAcrossAccount(const CmdParams * params)365 static bool IsAcrossAccount(const CmdParams *params)
366 {
367     if (params->userIdSelf == NULL || params->userIdPeer == NULL) {
368         LOGW("userIdSelf or userIdPeer is null");
369         return false;
370     }
371     if (!params->isBind && strcmp(params->userIdSelf, params->userIdPeer) != 0) {
372         LOGI("No peer-to-peer binding and SelfUserId is not equal to PeerUserId, don't need to add peerDevice!");
373         return true;
374     }
375     return false;
376 }
377 
AddPeerTrustedDevice(const CmdParams * params)378 static int32_t AddPeerTrustedDevice(const CmdParams *params)
379 {
380     if (IsAcrossAccount(params)) {
381         return HC_SUCCESS;
382     }
383     TrustedDeviceEntry *devParams = CreateDeviceEntry();
384     if (devParams == NULL) {
385         LOGE("Failed to allocate devParams memory!");
386         return HC_ERR_ALLOC_MEMORY;
387     }
388     int32_t res = GeneratePeerDevParams(params, devParams);
389     if (res != HC_SUCCESS) {
390         DestroyDeviceEntry(devParams);
391         return res;
392     }
393     res = AddTrustedDevice(params->osAccountId, devParams);
394     DestroyDeviceEntry(devParams);
395     if (res != HC_SUCCESS) {
396         LOGE("Failed to add the peer trust device to the database!");
397     } else {
398         LOGI("add trusted device success.");
399         PRINT_SENSITIVE_DATA("GroupId", params->groupId);
400         PRINT_SENSITIVE_DATA("PeerAuthId", params->authIdPeer);
401         PRINT_SENSITIVE_DATA("PeerUdid", params->udidPeer);
402     }
403     return res;
404 }
405 
AddSelfTrustedDevice(const CmdParams * params)406 static int32_t AddSelfTrustedDevice(const CmdParams *params)
407 {
408     TrustedDeviceEntry *devParams = CreateDeviceEntry();
409     if (devParams == NULL) {
410         LOGE("Failed to allocate devParams memory!");
411         return HC_ERR_ALLOC_MEMORY;
412     }
413     int32_t res = GenerateSelfDevParams(params, devParams);
414     if (res != HC_SUCCESS) {
415         DestroyDeviceEntry(devParams);
416         return res;
417     }
418     res = AddTrustedDevice(params->osAccountId, devParams);
419     DestroyDeviceEntry(devParams);
420     if (res != HC_SUCCESS) {
421         LOGE("Failed to add the self trust device to the database!");
422     }
423     return res;
424 }
425 
CreatePeerToPeerGroup(const CmdParams * params)426 static int32_t CreatePeerToPeerGroup(const CmdParams *params)
427 {
428     int32_t res = AddTrustedGroup(params);
429     if (res != HC_SUCCESS) {
430         return res;
431     }
432     return AddSelfTrustedDevice(params);
433 }
434 
GetTrustedDeviceEntryById(int32_t osAccountId,const char * udid,const char * groupId)435 static TrustedDeviceEntry *GetTrustedDeviceEntryById(int32_t osAccountId, const char *udid, const char *groupId)
436 {
437     DeviceEntryVec deviceEntryVec = CreateDeviceEntryVec();
438     QueryDeviceParams params = InitQueryDeviceParams();
439     params.groupId = groupId;
440     params.udid = udid;
441     if (QueryDevices(osAccountId, &params, &deviceEntryVec) != HC_SUCCESS) {
442         LOGE("Failed to query trusted devices!");
443         ClearDeviceEntryVec(&deviceEntryVec);
444         return NULL;
445     }
446     uint32_t index;
447     TrustedDeviceEntry **deviceEntry;
448     FOR_EACH_HC_VECTOR(deviceEntryVec, index, deviceEntry) {
449         TrustedDeviceEntry *returnEntry = DeepCopyDeviceEntry(*deviceEntry);
450         ClearDeviceEntryVec(&deviceEntryVec);
451         return returnEntry;
452     }
453     ClearDeviceEntryVec(&deviceEntryVec);
454     return NULL;
455 }
456 
IsDeviceImportedByCloud(const CmdParams * params)457 static bool IsDeviceImportedByCloud(const CmdParams *params)
458 {
459     TrustedDeviceEntry *peerDeviceEntry = GetTrustedDeviceEntryById(params->osAccountId, params->udidPeer,
460         params->groupId);
461     if (peerDeviceEntry == NULL) {
462         return false;
463     }
464     uint8_t source = peerDeviceEntry->source;
465     DestroyDeviceEntry(peerDeviceEntry);
466     return source == IMPORTED_FROM_CLOUD;
467 }
468 
ServerSendTrustedInfoProcEvent(CmdParams * params)469 static int32_t ServerSendTrustedInfoProcEvent(CmdParams *params)
470 {
471     char udid[INPUT_UDID_LEN] = { 0 };
472     int32_t res = HcGetUdid((uint8_t *)udid, INPUT_UDID_LEN);
473     if (res != HC_SUCCESS) {
474         LOGE("Failed to get local udid! res: %d", res);
475         return res;
476     }
477     if (DeepCopyString(udid, &params->udidSelf) != HC_SUCCESS) {
478         LOGE("copy udid fail.");
479         return HC_ERR_ALLOC_MEMORY;
480     }
481     res = CheckGroupValidity(params);
482     if (res != HC_SUCCESS) {
483         return res;
484     }
485     TrustedGroupEntry *entry = GetGroupEntryById(params->osAccountId, params->groupId);
486     if (entry == NULL) {
487         params->isGroupExistSelf = false;
488         res = CreatePeerToPeerGroup(params);
489         if (res != HC_SUCCESS) {
490             LOGE("Failed to add the group to the database!");
491             return res;
492         }
493     } else {
494         params->isGroupExistSelf = true;
495         if ((params->groupName == NULL) &&
496             (DeepCopyString(StringGet(&entry->name), &params->groupName) != HC_SUCCESS)) {
497             LOGE("copy groupName fail.");
498             DestroyGroupEntry(entry);
499             return HC_ERR_ALLOC_MEMORY;
500         }
501         if ((entry->type != PEER_TO_PEER_GROUP) &&
502             (DeepCopyString(StringGet(&entry->userId), &params->userIdSelf) != HC_SUCCESS)) {
503             LOGE("copy userIdSelf fail.");
504             DestroyGroupEntry(entry);
505             return HC_ERR_ALLOC_MEMORY;
506         }
507         DestroyGroupEntry(entry);
508     }
509     if (!IsDeviceImportedByCloud(params)) {
510         res = AddPeerTrustedDevice(params);
511         if (res != HC_SUCCESS) {
512             return res;
513         }
514     } else {
515         LOGI("Peer trusted device is imported from cloud, so there is no need to add it again.");
516     }
517     return SaveOsAccountDb(params->osAccountId);
518 }
519 
ServerSendTrustedInfoBuildEvent(const CmdParams * params,CJson ** outputEvent)520 static int32_t ServerSendTrustedInfoBuildEvent(const CmdParams *params, CJson **outputEvent)
521 {
522     CJson *json = CreateJson();
523     if (json == NULL) {
524         LOGE("create json failed.");
525         return HC_ERR_JSON_CREATE;
526     }
527     if (AddIntToJson(json, FIELD_EVENT, SERVER_SEND_INFO_EVENT) != HC_SUCCESS) {
528         LOGE("add eventName to json fail.");
529         FreeJson(json);
530         return HC_ERR_JSON_ADD;
531     }
532     if (AddStringToJson(json, FIELD_AUTH_ID_SERVER, params->authIdSelf) != HC_SUCCESS) {
533         LOGE("add authIdS to json fail.");
534         FreeJson(json);
535         return HC_ERR_JSON_ADD;
536     }
537     if (AddStringToJson(json, FIELD_UDID_SERVER, params->udidSelf) != HC_SUCCESS) {
538         LOGE("add udidS to json fail.");
539         FreeJson(json);
540         return HC_ERR_JSON_ADD;
541     }
542     if (AddIntToJson(json, FIELD_USER_TYPE_SERVER, params->userTypeSelf) != HC_SUCCESS) {
543         LOGE("add userTypeS to json fail.");
544         FreeJson(json);
545         return HC_ERR_JSON_ADD;
546     }
547     if (!params->isGroupExistPeer) {
548         if (AddStringToJson(json, FIELD_GROUP_NAME, params->groupName) != HC_SUCCESS) {
549             LOGE("add groupName to json fail.");
550             FreeJson(json);
551             return HC_ERR_JSON_ADD;
552         }
553     }
554     if (params->userIdSelf != NULL) {
555         if (AddStringToJson(json, FIELD_USER_ID_SERVER, params->userIdSelf) != HC_SUCCESS) {
556             LOGE("add userIdS to json fail.");
557             FreeJson(json);
558             return HC_ERR_JSON_ADD;
559         }
560     }
561     *outputEvent = json;
562     return HC_SUCCESS;
563 }
564 
ClientFinishProcParseEvent(const CJson * inputEvent,CmdParams * params)565 static int32_t ClientFinishProcParseEvent(const CJson *inputEvent, CmdParams *params)
566 {
567     if (!params->isGroupExistSelf) {
568         const char *groupName = GetStringFromJson(inputEvent, FIELD_GROUP_NAME);
569         if (groupName == NULL) {
570             LOGE("get groupName from json fail.");
571             return HC_ERR_JSON_GET;
572         }
573         if (DeepCopyString(groupName, &(params->groupName)) != HC_SUCCESS) {
574             LOGE("copy groupName fail.");
575             return HC_ERR_MEMORY_COPY;
576         }
577     }
578     const char *authId = GetStringFromJson(inputEvent, FIELD_AUTH_ID_SERVER);
579     if (authId == NULL) {
580         LOGE("get authIdS from json fail.");
581         return HC_ERR_JSON_GET;
582     }
583     const char *udid = GetStringFromJson(inputEvent, FIELD_UDID_SERVER);
584     if (udid == NULL) {
585         LOGE("get udidS from json fail.");
586         return HC_ERR_JSON_GET;
587     }
588     int32_t userTypeS;
589     if (GetIntFromJson(inputEvent, FIELD_USER_TYPE_SERVER, &userTypeS) != HC_SUCCESS) {
590         LOGE("get userTypeS from json fail.");
591         return HC_ERR_JSON_GET;
592     }
593     if (DeepCopyString(authId, &(params->authIdPeer)) != HC_SUCCESS) {
594         LOGE("copy groupId fail.");
595         return HC_ERR_MEMORY_COPY;
596     }
597     if (DeepCopyString(udid, &(params->udidPeer)) != HC_SUCCESS) {
598         LOGE("copy groupId fail.");
599         return HC_ERR_MEMORY_COPY;
600     }
601     const char *userId = GetStringFromJson(inputEvent, FIELD_USER_ID_SERVER);
602     if (userId != NULL) {
603         if (DeepCopyString(userId, &(params->userIdPeer)) != HC_SUCCESS) {
604             LOGE("copy userId fail.");
605             return HC_ERR_MEMORY_COPY;
606         }
607     }
608     params->userTypePeer = userTypeS;
609     return HC_SUCCESS;
610 }
611 
ClientFinishProcProcEvent(const CmdParams * params)612 static int32_t ClientFinishProcProcEvent(const CmdParams *params)
613 {
614     int32_t res;
615     if (!params->isGroupExistSelf) {
616         res = CreatePeerToPeerGroup(params);
617         if (res != HC_SUCCESS) {
618             LOGE("Failed to add the group to the database!");
619             return res;
620         }
621     }
622     if (!IsDeviceImportedByCloud(params)) {
623         res = AddPeerTrustedDevice(params);
624         if (res != HC_SUCCESS) {
625             return res;
626         }
627     }
628     return SaveOsAccountDb(params->osAccountId);
629 }
630 
ReturnError(int32_t errorCode,CJson ** outputEvent)631 static void ReturnError(int32_t errorCode, CJson **outputEvent)
632 {
633     (void)errorCode;
634     (void)outputEvent;
635     return;
636 }
637 
NotifyPeerError(int32_t errorCode,CJson ** outputEvent)638 static void NotifyPeerError(int32_t errorCode, CJson **outputEvent)
639 {
640     CJson *json = CreateJson();
641     if (json == NULL) {
642         LOGE("create json failed.");
643         return;
644     }
645     if (AddIntToJson(json, FIELD_EVENT, FAIL_EVENT) != HC_SUCCESS) {
646         LOGE("add eventName to json fail.");
647         FreeJson(json);
648         return;
649     }
650     if (AddIntToJson(json, FIELD_ERR_CODE, errorCode) != HC_SUCCESS) {
651         LOGE("add errorCode to json fail.");
652         FreeJson(json);
653         return;
654     }
655     *outputEvent = json;
656     return;
657 }
658 
ThrowException(BaseCmd * self,const CJson * baseEvent,CJson ** outputEvent)659 static int32_t ThrowException(BaseCmd *self, const CJson *baseEvent, CJson **outputEvent)
660 {
661     (void)self;
662     (void)outputEvent;
663     int32_t peerErrorCode = HC_ERR_PEER_ERROR;
664     (void)GetIntFromJson(baseEvent, FIELD_ERR_CODE, &peerErrorCode);
665     LOGE("An exception occurred in the peer cmd. [Code]: %d", peerErrorCode);
666     return peerErrorCode;
667 }
668 
ClientSendTrustedInfo(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)669 static int32_t ClientSendTrustedInfo(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
670 {
671     (void)inputEvent;
672     SaveTrustedInfoCmd *impl = (SaveTrustedInfoCmd *)self;
673     int32_t res = ClientSendTrustedInfoProcEvent(&impl->params);
674     if (res != HC_SUCCESS) {
675         return res;
676     }
677     return ClientSendTrustedInfoBuildEvent(&impl->params, outputEvent);
678 }
679 
ServerSendTrustedInfo(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)680 static int32_t ServerSendTrustedInfo(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
681 {
682     SaveTrustedInfoCmd *impl = (SaveTrustedInfoCmd *)self;
683     int32_t res = ServerSendTrustedInfoParseEvent(inputEvent, &impl->params);
684     if (res != HC_SUCCESS) {
685         return res;
686     }
687     res = ServerSendTrustedInfoProcEvent(&impl->params);
688     if (res != HC_SUCCESS) {
689         return res;
690     }
691     return ServerSendTrustedInfoBuildEvent(&impl->params, outputEvent);
692 }
693 
ClientFinishProc(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)694 static int32_t ClientFinishProc(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
695 {
696     (void)outputEvent;
697     SaveTrustedInfoCmd *impl = (SaveTrustedInfoCmd *)self;
698     int32_t res = ClientFinishProcParseEvent(inputEvent, &impl->params);
699     if (res != HC_SUCCESS) {
700         return res;
701     }
702     return ClientFinishProcProcEvent(&impl->params);
703 }
704 
705 static const CmdStateNode STATE_MACHINE[] = {
706     { CREATE_AS_CLIENT_STATE, START_EVENT, ClientSendTrustedInfo, NotifyPeerError, CLIENT_START_REQ_STATE },
707     { CREATE_AS_SERVER_STATE, CLIENT_SEND_INFO_EVENT, ServerSendTrustedInfo, NotifyPeerError, SERVER_FINISH_STATE },
708     { CREATE_AS_SERVER_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
709     { CLIENT_START_REQ_STATE, SERVER_SEND_INFO_EVENT, ClientFinishProc, ReturnError, CLIENT_FINISH_STATE },
710     { CLIENT_START_REQ_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
711 };
712 
DecodeEvent(const CJson * receviedMsg)713 static int32_t DecodeEvent(const CJson *receviedMsg)
714 {
715     if (receviedMsg == NULL) {
716         return START_EVENT;
717     }
718     int32_t event;
719     if (GetIntFromJson(receviedMsg, FIELD_EVENT, &event) != HC_SUCCESS) {
720         LOGE("get event from receviedMsg fail.");
721         return UNKNOWN_EVENT;
722     }
723     if (START_EVENT <= event && event <= UNKNOWN_EVENT) {
724         return event;
725     }
726     LOGE("unknown event.");
727     return UNKNOWN_EVENT;
728 }
729 
SwitchState(BaseCmd * self,const CJson * receviedMsg,CJson ** returnSendMsg,CmdState * returnState)730 static int32_t SwitchState(BaseCmd *self, const CJson *receviedMsg, CJson **returnSendMsg, CmdState *returnState)
731 {
732     int32_t eventType = DecodeEvent(receviedMsg);
733     for (uint32_t i = 0; i < sizeof(STATE_MACHINE) / sizeof(STATE_MACHINE[0]); i++) {
734         if ((STATE_MACHINE[i].curState == self->curState) && (STATE_MACHINE[i].eventType == eventType)) {
735             int32_t res = STATE_MACHINE[i].stateProcessFunc(self, receviedMsg, returnSendMsg);
736             if (res != HC_SUCCESS) {
737                 STATE_MACHINE[i].exceptionHandleFunc(res, returnSendMsg);
738                 self->curState = self->failState;
739                 return res;
740             }
741             LOGI("event: %d, curState: %d, nextState: %d", eventType, self->curState, STATE_MACHINE[i].nextState);
742             self->curState = STATE_MACHINE[i].nextState;
743             *returnState = (self->curState == self->finishState) ? CMD_STATE_FINISH : CMD_STATE_CONTINUE;
744             return HC_SUCCESS;
745         }
746     }
747     LOGI("Unsupported event type. Ignore process. [Event]: %d, [CurState]: %d", eventType, self->curState);
748     return HC_SUCCESS;
749 }
750 
StartSaveTrustedInfoCmd(BaseCmd * self,CJson ** returnSendMsg)751 static int32_t StartSaveTrustedInfoCmd(BaseCmd *self, CJson **returnSendMsg)
752 {
753     if ((self == NULL) || (returnSendMsg == NULL)) {
754         LOGE("invalid params.");
755         return HC_ERR_INVALID_PARAMS;
756     }
757     if (self->curState != self->beginState) {
758         LOGE("The protocol has ended, and the state switch cannot continue!");
759         return HC_ERR_UNSUPPORTED_OPCODE;
760     }
761     CmdState state;
762     return SwitchState(self, NULL, returnSendMsg, &state);
763 }
764 
ProcessSaveTrustedInfoCmd(BaseCmd * self,const CJson * receviedMsg,CJson ** returnSendMsg,CmdState * returnState)765 static int32_t ProcessSaveTrustedInfoCmd(BaseCmd *self, const CJson *receviedMsg,
766     CJson **returnSendMsg, CmdState *returnState)
767 {
768     if ((self == NULL) || (receviedMsg == NULL) || (returnSendMsg == NULL) || (returnState == NULL)) {
769         LOGE("invalid params.");
770         return HC_ERR_INVALID_PARAMS;
771     }
772     if ((self->curState == self->finishState) || (self->curState == self->failState)) {
773         LOGE("The protocol has ended, and the state switch cannot continue!");
774         return HC_ERR_UNSUPPORTED_OPCODE;
775     }
776     return SwitchState(self, receviedMsg, returnSendMsg, returnState);
777 }
778 
DestroySaveTrustedInfoCmd(BaseCmd * self)779 static void DestroySaveTrustedInfoCmd(BaseCmd *self)
780 {
781     if (self == NULL) {
782         LOGD("self is null.");
783         return;
784     }
785     SaveTrustedInfoCmd *impl = (SaveTrustedInfoCmd *)self;
786     HcFree(impl->params.groupId);
787     impl->params.groupId = NULL;
788     HcFree(impl->params.groupName);
789     impl->params.groupName = NULL;
790     HcFree(impl->params.appId);
791     impl->params.appId = NULL;
792     HcFree(impl->params.authIdSelf);
793     impl->params.authIdSelf = NULL;
794     HcFree(impl->params.authIdPeer);
795     impl->params.authIdPeer = NULL;
796     HcFree(impl->params.udidSelf);
797     impl->params.udidSelf = NULL;
798     HcFree(impl->params.udidPeer);
799     impl->params.udidPeer = NULL;
800     HcFree(impl->params.userIdSelf);
801     impl->params.userIdSelf = NULL;
802     HcFree(impl->params.userIdPeer);
803     impl->params.userIdPeer = NULL;
804     HcFree(impl);
805 }
806 
IsSaveTrustedInfoParamsValid(const SaveTrustedInfoParams * params)807 static inline bool IsSaveTrustedInfoParamsValid(const SaveTrustedInfoParams *params)
808 {
809     return ((params != NULL) && (params->appId != NULL) && (params->authId != NULL) && (params->groupId != NULL));
810 }
811 
InitSaveTrustedInfoCmd(SaveTrustedInfoCmd * instance,const SaveTrustedInfoParams * params,bool isCaller,int32_t strategy)812 static int32_t InitSaveTrustedInfoCmd(SaveTrustedInfoCmd *instance, const SaveTrustedInfoParams *params,
813     bool isCaller, int32_t strategy)
814 {
815     if (DeepCopyString(params->appId, &(instance->params.appId)) != HC_SUCCESS) {
816         LOGE("copy appId fail.");
817         return HC_ERR_ALLOC_MEMORY;
818     }
819     if (DeepCopyString(params->authId, &(instance->params.authIdSelf)) != HC_SUCCESS) {
820         LOGE("copy authId fail.");
821         return HC_ERR_ALLOC_MEMORY;
822     }
823     if (DeepCopyString(params->groupId, &(instance->params.groupId)) != HC_SUCCESS) {
824         LOGE("copy groupId fail.");
825         return HC_ERR_ALLOC_MEMORY;
826     }
827     instance->params.isGroupExistSelf = false;
828     instance->params.isGroupExistPeer = false;
829     instance->params.isBind = params->isBind;
830     instance->params.osAccountId = params->osAccountId;
831     instance->params.credType = params->credType;
832     instance->params.userTypeSelf = params->userType;
833     instance->params.visibility = params->visibility;
834     instance->base.type = SAVE_TRUSTED_INFO_CMD_TYPE;
835     instance->base.strategy = strategy;
836     instance->base.isCaller = isCaller;
837     instance->base.beginState = isCaller ? CREATE_AS_CLIENT_STATE : CREATE_AS_SERVER_STATE;
838     instance->base.finishState = isCaller ? CLIENT_FINISH_STATE : SERVER_FINISH_STATE;
839     instance->base.failState = FAIL_STATE;
840     instance->base.curState = instance->base.beginState;
841     instance->base.start = StartSaveTrustedInfoCmd;
842     instance->base.process = ProcessSaveTrustedInfoCmd;
843     instance->base.destroy = DestroySaveTrustedInfoCmd;
844     return HC_SUCCESS;
845 }
846 
CreateSaveTrustedInfoCmd(const void * baseParams,bool isCaller,int32_t strategy)847 BaseCmd *CreateSaveTrustedInfoCmd(const void *baseParams, bool isCaller, int32_t strategy)
848 {
849     const SaveTrustedInfoParams *params = (const SaveTrustedInfoParams *)baseParams;
850     if (!IsSaveTrustedInfoParamsValid(params)) {
851         LOGE("invalid params.");
852         return NULL;
853     }
854     SaveTrustedInfoCmd *instance = (SaveTrustedInfoCmd *)HcMalloc(sizeof(SaveTrustedInfoCmd), 0);
855     if (instance == NULL) {
856         LOGE("allocate instance memory fail.");
857         return NULL;
858     }
859     int32_t res = InitSaveTrustedInfoCmd(instance, params, isCaller, strategy);
860     if (res != HC_SUCCESS) {
861         DestroySaveTrustedInfoCmd((BaseCmd *)instance);
862         return NULL;
863     }
864     return (BaseCmd *)instance;
865 }
866