• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "auth_code_import.h"
17 
18 #include "alg_loader.h"
19 #include "device_auth_defines.h"
20 #include "hc_log.h"
21 #include "identity_defines.h"
22 
23 #define START_CMD_EVENT_NAME "StartCmd"
24 #define GEN_AUTH_CODE_EVENT_NAME "GenAuthCode"
25 #define IMPORT_AUTH_CODE_EVENT_NAME "ImportAuthCode"
26 #define FAIL_EVENT_NAME "CmdFail"
27 
28 #define FIELD_USER_TYPE_CLIENT "userTypeC"
29 #define FIELD_USER_TYPE_SERVER "userTypeS"
30 #define FIELD_AUTH_ID_CLIENT "authIdC"
31 #define FIELD_AUTH_ID_SERVER "authIdS"
32 #define FIELD_AUTH_CODE "authCode"
33 #define FIELD_CLIENT_RESULT "clientResult"
34 
35 #define FIELD_EVENT "event"
36 #define FIELD_ERR_CODE "errCode"
37 #define FIELD_ERR_MSG "errMsg"
38 
39 typedef struct {
40     int32_t userTypeSelf;
41     int32_t userTypePeer;
42     char *groupId;
43     char *appId;
44     Uint8Buff authIdSelf;
45     Uint8Buff authIdPeer;
46     Uint8Buff authCode;
47     int32_t osAccountId;
48 } CmdParams;
49 
50 typedef struct {
51     BaseCmd base;
52     CmdParams params;
53 } AuthCodeImportCmd;
54 
55 typedef enum {
56     START_EVENT = 0,
57     CLIENT_SEND_DEV_IFNO_EVENT,
58     SERVER_SEND_AUTH_CODE_EVENT,
59     FAIL_EVENT,
60     UNKNOWN_EVENT,
61 } EventEnum;
62 
63 typedef enum {
64     CREATE_AS_CLIENT_STATE = 0,
65     CREATE_AS_SERVER_STATE,
66     CLIENT_START_REQ_STATE,
67     /* FINISH STATE */
68     CLIENT_FINISH_STATE,
69     SERVER_FINISH_STATE,
70     /* FAIL STATE */
71     FAIL_STATE
72 } StateEnum;
73 
74 typedef struct {
75     int32_t curState;
76     int32_t eventType;
77     int32_t (*stateProcessFunc)(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent);
78     void (*exceptionHandleFunc)(int32_t errorCode, CJson **outputEvent);
79     int32_t nextState;
80 } CmdStateNode;
81 
82 /* in order to expand to uint16_t */
83 static const uint8_t KEY_TYPE_PAIRS[KEY_ALIAS_TYPE_END][KEY_TYPE_PAIR_LEN] = {
84     { 0x00, 0x00 }, /* ACCESSOR_PK */
85     { 0x00, 0x01 }, /* CONTROLLER_PK */
86     { 0x00, 0x02 }, /* ed25519 KEYPAIR */
87     { 0x00, 0x03 }, /* KEK, key encryption key, used only by DeviceAuthService */
88     { 0x00, 0x04 }, /* DEK, data encryption key, used only by upper apps */
89     { 0x00, 0x05 }, /* key tmp */
90     { 0x00, 0x06 }, /* PSK, preshared key index */
91     { 0x00, 0x07 }, /* AUTHTOKEN */
92     { 0x00, 0x08 }  /* P2P_AUTH */
93 };
94 
BuildKeyAliasMsg(const Uint8Buff * serviceId,const Uint8Buff * keyType,const Uint8Buff * authId,Uint8Buff * keyAliasMsg)95 static int32_t BuildKeyAliasMsg(const Uint8Buff *serviceId, const Uint8Buff *keyType,
96     const Uint8Buff *authId, Uint8Buff *keyAliasMsg)
97 {
98     uint32_t usedLen = 0;
99     if (memcpy_s(keyAliasMsg->val, keyAliasMsg->length, serviceId->val, serviceId->length) != EOK) {
100         LOGE("Memcopy serviceId to keyAliasMsg failed.");
101         return HC_ERR_MEMORY_COPY;
102     }
103     usedLen = usedLen + serviceId->length;
104     if (memcpy_s(keyAliasMsg->val + usedLen, keyAliasMsg->length - usedLen, keyType->val, keyType->length) != EOK) {
105         LOGE("Memcpy keyType to keyAliasMsg failed.");
106         return HC_ERR_MEMORY_COPY;
107     }
108     usedLen = usedLen + keyType->length;
109     if (memcpy_s(keyAliasMsg->val + usedLen, keyAliasMsg->length - usedLen, authId->val, authId->length) != EOK) {
110         LOGE("Memcopy authId to msg failed.");
111         return HC_ERR_MEMORY_COPY;
112     }
113     return HC_SUCCESS;
114 }
115 
CalKeyAlias(const Uint8Buff * serviceId,const Uint8Buff * keyType,const Uint8Buff * authId,Uint8Buff * keyAlias)116 static int32_t CalKeyAlias(const Uint8Buff *serviceId, const Uint8Buff *keyType,
117     const Uint8Buff *authId, Uint8Buff *keyAlias)
118 {
119     Uint8Buff keyAliasMsg = { NULL, 0 };
120     keyAliasMsg.length = serviceId->length + authId->length + keyType->length;
121     keyAliasMsg.val = (uint8_t *)HcMalloc(keyAliasMsg.length, 0);
122     if (keyAliasMsg.val == NULL) {
123         LOGE("Malloc keyAlias memory failed.");
124         return HC_ERR_ALLOC_MEMORY;
125     }
126     int32_t res = BuildKeyAliasMsg(serviceId, keyType, authId, &keyAliasMsg);
127     if (res != HC_SUCCESS) {
128         HcFree(keyAliasMsg.val);
129         return res;
130     }
131     res = GetLoaderInstance()->sha256(&keyAliasMsg, keyAlias);
132     HcFree(keyAliasMsg.val);
133     if (res != HC_SUCCESS) {
134         LOGE("KeyAlias Sha256 failed.");
135         return res;
136     }
137     return HC_SUCCESS;
138 }
139 
CalServiceId(const char * appId,const char * groupId,Uint8Buff * serviceId)140 static int32_t CalServiceId(const char *appId, const char *groupId, Uint8Buff *serviceId)
141 {
142     uint32_t groupIdLen = HcStrlen(groupId);
143     uint32_t appIdLen = HcStrlen(appId);
144     Uint8Buff serviceIdPlain = { NULL, 0 };
145     serviceIdPlain.length = appIdLen + groupIdLen;
146     serviceIdPlain.val = (uint8_t *)HcMalloc(serviceIdPlain.length, 0);
147     if (serviceIdPlain.val == NULL) {
148         LOGE("malloc serviceIdPlain.val failed.");
149         return HC_ERR_ALLOC_MEMORY;
150     }
151     if (memcpy_s(serviceIdPlain.val, serviceIdPlain.length, appId, appIdLen) != EOK) {
152         LOGE("Copy service id: pkgName failed.");
153         HcFree(serviceIdPlain.val);
154         return HC_ERR_MEMORY_COPY;
155     }
156     if (memcpy_s(serviceIdPlain.val + appIdLen,  serviceIdPlain.length - appIdLen, groupId, groupIdLen) != EOK) {
157         LOGE("Copy service id: groupId failed.");
158         HcFree(serviceIdPlain.val);
159         return HC_ERR_MEMORY_COPY;
160     }
161     int32_t res = GetLoaderInstance()->sha256(&serviceIdPlain, serviceId);
162     HcFree(serviceIdPlain.val);
163     if (res != HC_SUCCESS) {
164         LOGE("Service id Sha256 failed.");
165         return res;
166     }
167     return HC_SUCCESS;
168 }
169 
GetKeyTypePair(KeyAliasType keyAliasType)170 static uint8_t *GetKeyTypePair(KeyAliasType keyAliasType)
171 {
172     return (uint8_t *)KEY_TYPE_PAIRS[keyAliasType];
173 }
174 
GenerateKeyAlias(const CmdParams * params,Uint8Buff * keyAlias)175 static int32_t GenerateKeyAlias(const CmdParams *params, Uint8Buff *keyAlias)
176 {
177     uint8_t serviceIdVal[SHA256_LEN] = { 0 };
178     Uint8Buff serviceId = { serviceIdVal, SHA256_LEN };
179     int32_t res = CalServiceId(params->appId, params->groupId, &serviceId);
180     if (res != HC_SUCCESS) {
181         LOGE("CombineServiceId failed, res: %" LOG_PUB "x.", res);
182         return res;
183     }
184     Uint8Buff keyTypeBuff = { GetKeyTypePair(KEY_ALIAS_AUTH_TOKEN), KEY_TYPE_PAIR_LEN };
185     return CalKeyAlias(&serviceId, &keyTypeBuff, &params->authIdPeer, keyAlias);
186 }
187 
ClientSendDevInfoBuildEvent(const CmdParams * params,CJson ** outputEvent)188 static int32_t ClientSendDevInfoBuildEvent(const CmdParams *params, CJson **outputEvent)
189 {
190     CJson *json = CreateJson();
191     if (json == NULL) {
192         LOGE("create json failed.");
193         return HC_ERR_JSON_CREATE;
194     }
195     if (AddIntToJson(json, FIELD_EVENT, CLIENT_SEND_DEV_IFNO_EVENT) != HC_SUCCESS) {
196         LOGE("add eventName to json fail.");
197         FreeJson(json);
198         return HC_ERR_JSON_ADD;
199     }
200     if (AddByteToJson(json, FIELD_AUTH_ID_CLIENT, params->authIdSelf.val,
201         params->authIdSelf.length) != HC_SUCCESS) {
202         LOGE("add authIdC to json fail.");
203         FreeJson(json);
204         return HC_ERR_JSON_ADD;
205     }
206     if (AddIntToJson(json, FIELD_USER_TYPE_CLIENT, params->userTypeSelf) != HC_SUCCESS) {
207         LOGE("add userTypeC to json fail.");
208         FreeJson(json);
209         return HC_ERR_JSON_ADD;
210     }
211     *outputEvent = json;
212     return HC_SUCCESS;
213 }
214 
GetAuthIdPeerFromInput(const CJson * inputEvent,CmdParams * params,bool isClient)215 static int32_t GetAuthIdPeerFromInput(const CJson *inputEvent, CmdParams *params, bool isClient)
216 {
217     const char *authIdPeerStr = isClient ? GetStringFromJson(inputEvent, FIELD_AUTH_ID_SERVER) :
218         GetStringFromJson(inputEvent, FIELD_AUTH_ID_CLIENT);
219     if (authIdPeerStr == NULL) {
220         LOGE("get authIdPeerStr from inputEvent failed.");
221         return HC_ERR_JSON_GET;
222     }
223     uint32_t authIdPeerStrLen = HcStrlen(authIdPeerStr) / BYTE_TO_HEX_OPER_LENGTH;
224     if (authIdPeerStrLen == 0) {
225         LOGE("AuthIdPeerStrLen is zero.");
226         return HC_ERR_CONVERT_FAILED;
227     }
228     if (InitUint8Buff(&params->authIdPeer, authIdPeerStrLen) != HC_SUCCESS) {
229         LOGE("Malloc authIdPeer memory failed.");
230         return HC_ERR_ALLOC_MEMORY;
231     }
232     if (HexStringToByte(authIdPeerStr, params->authIdPeer.val, params->authIdPeer.length) != HC_SUCCESS) {
233         LOGE("HexStringToByte for authIdPeerStr failed.");
234         return HC_ERR_CONVERT_FAILED;
235     }
236     return HC_SUCCESS;
237 }
238 
ServerGenAuthCodeParseEvent(const CJson * inputEvent,CmdParams * params)239 static int32_t ServerGenAuthCodeParseEvent(const CJson *inputEvent, CmdParams *params)
240 {
241     int32_t res = GetAuthIdPeerFromInput(inputEvent, params, false);
242     if (res != HC_SUCCESS) {
243         return res;
244     }
245     int32_t userTypeC;
246     if (GetIntFromJson(inputEvent, FIELD_USER_TYPE_CLIENT, &userTypeC) != HC_SUCCESS) {
247         LOGE("get userTypeC from json fail.");
248         return HC_ERR_JSON_GET;
249     }
250     params->userTypePeer = userTypeC;
251     return HC_SUCCESS;
252 }
253 
ServerGenAuthCodeProcEvent(CmdParams * params)254 static int32_t ServerGenAuthCodeProcEvent(CmdParams *params)
255 {
256     uint8_t authCodeVal[AUTH_CODE_LEN] = { 0 };
257     Uint8Buff authCode = { authCodeVal, AUTH_CODE_LEN };
258     int32_t res = GetLoaderInstance()->generateRandom(&authCode);
259     if (res != HC_SUCCESS) {
260         LOGE("generate auth code failed, res:%" LOG_PUB "d", res);
261         return res;
262     }
263     if (DeepCopyUint8Buff(&authCode, &params->authCode) != HC_SUCCESS) {
264         LOGE("copy authcode fail.");
265         return HC_ERR_MEMORY_COPY;
266     }
267     uint8_t keyAliasVal[KEY_ALIAS_LEN] = { 0 };
268     Uint8Buff keyAlias = { keyAliasVal, KEY_ALIAS_LEN };
269     res = GenerateKeyAlias(params, &keyAlias);
270     if (res != HC_SUCCESS) {
271         LOGE("GenerateKeyAliasInIso failed, res:%" LOG_PUB "d", res);
272         return res;
273     }
274     LOGI("AuthCode alias(HEX): %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****.",
275         keyAliasVal[DEV_AUTH_ZERO], keyAliasVal[DEV_AUTH_ONE],
276         keyAliasVal[DEV_AUTH_TWO], keyAliasVal[DEV_AUTH_THREE]);
277     ExtraInfo exInfo = { params->authIdPeer, params->userTypePeer, PAIR_TYPE_BIND };
278     KeyParams keyParams = { { keyAlias.val, keyAlias.length, true }, false, params->osAccountId };
279     res = GetLoaderInstance()->importSymmetricKey(&keyParams, &authCode, KEY_PURPOSE_MAC, &exInfo);
280     if (res != HC_SUCCESS) {
281         LOGE("import sym key fail.");
282         return res;
283     }
284     return HC_SUCCESS;
285 }
286 
ServerSendAuthCodeBuildEvent(const CmdParams * params,CJson ** outputEvent)287 static int32_t ServerSendAuthCodeBuildEvent(const CmdParams *params, CJson **outputEvent)
288 {
289     CJson *json = CreateJson();
290     if (json == NULL) {
291         LOGE("create json failed.");
292         return HC_ERR_JSON_CREATE;
293     }
294     if (AddIntToJson(json, FIELD_EVENT, SERVER_SEND_AUTH_CODE_EVENT) != HC_SUCCESS) {
295         LOGE("add eventName to json fail.");
296         FreeJson(json);
297         return HC_ERR_JSON_ADD;
298     }
299     if (AddByteToJson(json, FIELD_AUTH_ID_SERVER, params->authIdSelf.val,
300         params->authIdSelf.length) != HC_SUCCESS) {
301         LOGE("add authIdS to json fail.");
302         FreeJson(json);
303         return HC_ERR_JSON_ADD;
304     }
305     if (AddIntToJson(json, FIELD_USER_TYPE_SERVER, params->userTypeSelf) != HC_SUCCESS) {
306         LOGE("add userTypeS to json fail.");
307         FreeJson(json);
308         return HC_ERR_JSON_ADD;
309     }
310     if (AddByteToJson(json, FIELD_AUTH_CODE, params->authCode.val, params->authCode.length) != HC_SUCCESS) {
311         LOGE("add authCode to json fail.");
312         FreeJson(json);
313         return HC_ERR_JSON_ADD;
314     }
315     *outputEvent = json;
316     return HC_SUCCESS;
317 }
318 
ClientImportAuthCodeParseEvent(const CJson * inputEvent,CmdParams * params)319 static int32_t ClientImportAuthCodeParseEvent(const CJson *inputEvent, CmdParams *params)
320 {
321     int32_t userTypeS;
322     if (GetIntFromJson(inputEvent, FIELD_USER_TYPE_SERVER, &userTypeS) != HC_SUCCESS) {
323         LOGE("get userTypeS from json fail.");
324         return HC_ERR_JSON_GET;
325     }
326     int32_t res = GetAuthIdPeerFromInput(inputEvent, params, true);
327     if (res != HC_SUCCESS) {
328         return res;
329     }
330     uint8_t authCodeVal[AUTH_CODE_LEN] = { 0 };
331     Uint8Buff authCode = { authCodeVal, AUTH_CODE_LEN };
332     if (GetByteFromJson(inputEvent, FIELD_AUTH_CODE, authCode.val, authCode.length) != HC_SUCCESS) {
333         LOGE("get authCode from json fail.");
334         return HC_ERR_JSON_GET;
335     }
336     if (DeepCopyUint8Buff(&authCode, &params->authCode) != HC_SUCCESS) {
337         LOGE("copy authCode fail.");
338         (void)memset_s(authCodeVal, AUTH_CODE_LEN, 0, AUTH_CODE_LEN);
339         return HC_ERR_MEMORY_COPY;
340     }
341     params->userTypePeer = userTypeS;
342     return HC_SUCCESS;
343 }
344 
ClientImportAuthCodeProcEvent(const CmdParams * params)345 static int32_t ClientImportAuthCodeProcEvent(const CmdParams *params)
346 {
347     uint8_t keyAliasVal[KEY_ALIAS_LEN] = { 0 };
348     Uint8Buff keyAlias = { keyAliasVal, KEY_ALIAS_LEN };
349     int32_t res = GenerateKeyAlias(params, &keyAlias);
350     if (res != HC_SUCCESS) {
351         LOGE("GenerateKeyAliasInIso failed, res:%" LOG_PUB "d", res);
352         return res;
353     }
354 
355     LOGI("AuthCode alias(HEX): %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****.",
356         keyAliasVal[DEV_AUTH_ZERO], keyAliasVal[DEV_AUTH_ONE],
357         keyAliasVal[DEV_AUTH_TWO], keyAliasVal[DEV_AUTH_THREE]);
358     ExtraInfo exInfo = { params->authIdPeer, params->userTypePeer, PAIR_TYPE_BIND };
359     KeyParams keyParams = { { keyAlias.val, keyAlias.length, true }, false, params->osAccountId };
360     res = GetLoaderInstance()->importSymmetricKey(&keyParams, &(params->authCode), KEY_PURPOSE_MAC, &exInfo);
361     if (res != HC_SUCCESS) {
362         LOGE("import sym key fail.");
363         return res;
364     }
365     return HC_SUCCESS;
366 }
367 
ReturnError(int32_t errorCode,CJson ** outputEvent)368 static void ReturnError(int32_t errorCode, CJson **outputEvent)
369 {
370     (void)outputEvent;
371     (void)errorCode;
372     return;
373 }
374 
NotifyPeerError(int32_t errorCode,CJson ** outputEvent)375 static void NotifyPeerError(int32_t errorCode, CJson **outputEvent)
376 {
377     CJson *json = CreateJson();
378     if (json == NULL) {
379         LOGE("create json failed.");
380         return;
381     }
382     if (AddIntToJson(json, FIELD_EVENT, FAIL_EVENT) != HC_SUCCESS) {
383         LOGE("add eventName to json failed.");
384         FreeJson(json);
385         return;
386     }
387     if (AddIntToJson(json, FIELD_ERR_CODE, errorCode) != HC_SUCCESS) {
388         LOGE("add errorCode to json failed.");
389         FreeJson(json);
390         return;
391     }
392     *outputEvent = json;
393     return;
394 }
395 
ThrowException(BaseCmd * self,const CJson * baseEvent,CJson ** outputEvent)396 static int32_t ThrowException(BaseCmd *self, const CJson *baseEvent, CJson **outputEvent)
397 {
398     (void)self;
399     (void)outputEvent;
400     int32_t peerErrorCode = HC_ERR_PEER_ERROR;
401     (void)GetIntFromJson(baseEvent, FIELD_ERR_CODE, &peerErrorCode);
402     LOGE("An exception occurred in the peer cmd. [Code]: %" LOG_PUB "d", peerErrorCode);
403     return peerErrorCode;
404 }
405 
ClientSendDevInfo(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)406 static int32_t ClientSendDevInfo(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
407 {
408     (void)inputEvent;
409     AuthCodeImportCmd *impl = (AuthCodeImportCmd *)self;
410     return ClientSendDevInfoBuildEvent(&impl->params, outputEvent);
411 }
412 
ServerGenAuthCode(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)413 static int32_t ServerGenAuthCode(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
414 {
415     AuthCodeImportCmd *impl = (AuthCodeImportCmd *)self;
416     int32_t res = ServerGenAuthCodeParseEvent(inputEvent, &impl->params);
417     if (res != HC_SUCCESS) {
418         return res;
419     }
420     res = ServerGenAuthCodeProcEvent(&impl->params);
421     if (res != HC_SUCCESS) {
422         return res;
423     }
424     return ServerSendAuthCodeBuildEvent(&impl->params, outputEvent);
425 }
426 
ClientImportAuthCode(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)427 static int32_t ClientImportAuthCode(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
428 {
429     (void)outputEvent;
430     AuthCodeImportCmd *impl = (AuthCodeImportCmd *)self;
431     int32_t res = ClientImportAuthCodeParseEvent(inputEvent, &impl->params);
432     if (res != HC_SUCCESS) {
433         return res;
434     }
435     return ClientImportAuthCodeProcEvent(&impl->params);
436 }
437 
438 static const CmdStateNode STATE_MACHINE[] = {
439     { CREATE_AS_CLIENT_STATE, START_EVENT, ClientSendDevInfo, NotifyPeerError, CLIENT_START_REQ_STATE },
440     { CREATE_AS_SERVER_STATE, CLIENT_SEND_DEV_IFNO_EVENT, ServerGenAuthCode, NotifyPeerError, SERVER_FINISH_STATE },
441     { CREATE_AS_SERVER_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
442     { CLIENT_START_REQ_STATE, SERVER_SEND_AUTH_CODE_EVENT, ClientImportAuthCode, ReturnError, CLIENT_FINISH_STATE },
443     { CLIENT_START_REQ_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
444 };
445 
DecodeEvent(const CJson * receviedMsg)446 static int32_t DecodeEvent(const CJson *receviedMsg)
447 {
448     if (receviedMsg == NULL) {
449         return START_EVENT;
450     }
451     int32_t event;
452     if (GetIntFromJson(receviedMsg, FIELD_EVENT, &event) != HC_SUCCESS) {
453         LOGE("get event from receviedMsg fail.");
454         return UNKNOWN_EVENT;
455     }
456     if (START_EVENT <= event && event <= UNKNOWN_EVENT) {
457         return event;
458     }
459     LOGE("unknown event.");
460     return UNKNOWN_EVENT;
461 }
462 
SwitchState(BaseCmd * self,const CJson * receviedMsg,CJson ** returnSendMsg,CmdState * returnState)463 static int32_t SwitchState(BaseCmd *self, const CJson *receviedMsg, CJson **returnSendMsg, CmdState *returnState)
464 {
465     int32_t eventType = DecodeEvent(receviedMsg);
466     for (uint32_t i = 0; i < sizeof(STATE_MACHINE) / sizeof(STATE_MACHINE[0]); i++) {
467         if ((STATE_MACHINE[i].curState == self->curState) && (STATE_MACHINE[i].eventType == eventType)) {
468             int32_t res = STATE_MACHINE[i].stateProcessFunc(self, receviedMsg, returnSendMsg);
469             if (res != HC_SUCCESS) {
470                 STATE_MACHINE[i].exceptionHandleFunc(res, returnSendMsg);
471                 self->curState = self->failState;
472                 return res;
473             }
474             LOGI("event: %" LOG_PUB "d, curState: %" LOG_PUB "d, nextState: %" LOG_PUB "d", eventType, self->curState,
475                 STATE_MACHINE[i].nextState);
476             self->curState = STATE_MACHINE[i].nextState;
477             *returnState = (self->curState == self->finishState) ? CMD_STATE_FINISH : CMD_STATE_CONTINUE;
478             return HC_SUCCESS;
479         }
480     }
481     LOGI("Unsupported event type. Ignore process. [Event]: %" LOG_PUB "d, [CurState]: %" LOG_PUB "d",
482         eventType, self->curState);
483     return HC_SUCCESS;
484 }
485 
StartAuthCodeImportCmd(BaseCmd * self,CJson ** returnSendMsg)486 static int32_t StartAuthCodeImportCmd(BaseCmd *self, CJson **returnSendMsg)
487 {
488     if ((self == NULL) || (returnSendMsg == NULL)) {
489         LOGE("invalid params.");
490         return HC_ERR_INVALID_PARAMS;
491     }
492     if (self->curState != self->beginState) {
493         LOGE("The protocol has ended, and the state switch cannot continue!");
494         return HC_ERR_UNSUPPORTED_OPCODE;
495     }
496     CmdState state;
497     return SwitchState(self, NULL, returnSendMsg, &state);
498 }
499 
ProcessAuthCodeImportCmd(BaseCmd * self,const CJson * receviedMsg,CJson ** returnSendMsg,CmdState * returnState)500 static int32_t ProcessAuthCodeImportCmd(BaseCmd *self, const CJson *receviedMsg,
501     CJson **returnSendMsg, CmdState *returnState)
502 {
503     if ((self == NULL) || (receviedMsg == NULL) || (returnSendMsg == NULL) || (returnState == NULL)) {
504         LOGE("invalid params.");
505         return HC_ERR_INVALID_PARAMS;
506     }
507     if ((self->curState == self->finishState) || (self->curState == self->failState)) {
508         LOGE("The protocol has ended, and the state switch cannot continue!");
509         return HC_ERR_UNSUPPORTED_OPCODE;
510     }
511     return SwitchState(self, receviedMsg, returnSendMsg, returnState);
512 }
513 
DestroyAuthCodeImportCmd(BaseCmd * self)514 static void DestroyAuthCodeImportCmd(BaseCmd *self)
515 {
516     if (self == NULL) {
517         LOGD("self is null.");
518         return;
519     }
520     AuthCodeImportCmd *impl = (AuthCodeImportCmd *)self;
521     ClearFreeUint8Buff(&impl->params.authCode);
522     ClearFreeUint8Buff(&impl->params.authIdSelf);
523     ClearFreeUint8Buff(&impl->params.authIdPeer);
524     HcFree(impl->params.groupId);
525     HcFree(impl->params.appId);
526     HcFree(impl);
527 }
528 
IsAuthCodeImportParamsValid(const AuthCodeImportParams * params)529 static bool IsAuthCodeImportParamsValid(const AuthCodeImportParams *params)
530 {
531     if ((params == NULL) || (params->appId == NULL) || (params->authId.val == NULL) ||
532         (params->authId.length == 0) || (params->groupId == NULL)) {
533         return false;
534     }
535     return true;
536 }
537 
InitAuthCodeImportCmd(AuthCodeImportCmd * instance,const AuthCodeImportParams * params,bool isCaller,int32_t strategy)538 static int32_t InitAuthCodeImportCmd(AuthCodeImportCmd *instance, const AuthCodeImportParams *params,
539     bool isCaller, int32_t strategy)
540 {
541     if (DeepCopyUint8Buff(&params->authId, &(instance->params.authIdSelf)) != HC_SUCCESS) {
542         LOGE("copy authIdSelf fail.");
543         return HC_ERR_ALLOC_MEMORY;
544     }
545     if (DeepCopyString(params->appId, &(instance->params.appId)) != HC_SUCCESS) {
546         LOGE("copy appId fail.");
547         return HC_ERR_ALLOC_MEMORY;
548     }
549     if (DeepCopyString(params->groupId, &(instance->params.groupId)) != HC_SUCCESS) {
550         LOGE("copy groupId fail.");
551         return HC_ERR_ALLOC_MEMORY;
552     }
553     instance->params.osAccountId = params->osAccountId;
554     instance->params.userTypeSelf = params->userType;
555     instance->base.type = AUTH_CODE_IMPORT_CMD_TYPE;
556     instance->base.strategy = strategy;
557     instance->base.isCaller = isCaller;
558     instance->base.beginState = isCaller ? CREATE_AS_CLIENT_STATE : CREATE_AS_SERVER_STATE;
559     instance->base.finishState = isCaller ? CLIENT_FINISH_STATE : SERVER_FINISH_STATE;
560     instance->base.failState = FAIL_STATE;
561     instance->base.curState = instance->base.beginState;
562     instance->base.start = StartAuthCodeImportCmd;
563     instance->base.process = ProcessAuthCodeImportCmd;
564     instance->base.destroy = DestroyAuthCodeImportCmd;
565     return HC_SUCCESS;
566 }
567 
CreateAuthCodeImportCmd(const void * baseParams,bool isCaller,int32_t strategy)568 BaseCmd *CreateAuthCodeImportCmd(const void *baseParams, bool isCaller, int32_t strategy)
569 {
570     const AuthCodeImportParams *params = (const AuthCodeImportParams *)baseParams;
571     if (!IsAuthCodeImportParamsValid(params)) {
572         LOGE("invalid params.");
573         return NULL;
574     }
575     AuthCodeImportCmd *instance = (AuthCodeImportCmd *)HcMalloc(sizeof(AuthCodeImportCmd), 0);
576     if (instance == NULL) {
577         LOGE("allocate instance memory fail.");
578         return NULL;
579     }
580     int32_t res = InitAuthCodeImportCmd(instance, params, isCaller, strategy);
581     if (res != HC_SUCCESS) {
582         DestroyAuthCodeImportCmd((BaseCmd *)instance);
583         return NULL;
584     }
585     return (BaseCmd *)instance;
586 }
587