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 
GetKeyTypePair(KeyAliasType keyAliasType)95 static uint8_t *GetKeyTypePair(KeyAliasType keyAliasType)
96 {
97     return (uint8_t *)KEY_TYPE_PAIRS[keyAliasType];
98 }
99 
BuildKeyAliasMsg(const Uint8Buff * serviceId,const Uint8Buff * keyType,const Uint8Buff * authId,Uint8Buff * keyAliasMsg)100 static int32_t BuildKeyAliasMsg(const Uint8Buff *serviceId, const Uint8Buff *keyType,
101     const Uint8Buff *authId, Uint8Buff *keyAliasMsg)
102 {
103     uint32_t usedLen = 0;
104     if (memcpy_s(keyAliasMsg->val, keyAliasMsg->length, serviceId->val, serviceId->length) != EOK) {
105         LOGE("Copy serviceId failed.");
106         return HC_ERR_MEMORY_COPY;
107     }
108     usedLen = usedLen + serviceId->length;
109     if (memcpy_s(keyAliasMsg->val + usedLen, keyAliasMsg->length - usedLen, keyType->val, keyType->length) != EOK) {
110         LOGE("Copy keyType failed.");
111         return HC_ERR_MEMORY_COPY;
112     }
113     usedLen = usedLen + keyType->length;
114     if (memcpy_s(keyAliasMsg->val + usedLen, keyAliasMsg->length - usedLen, authId->val, authId->length) != EOK) {
115         LOGE("Copy authId failed.");
116         return HC_ERR_MEMORY_COPY;
117     }
118     return HC_SUCCESS;
119 }
120 
CalKeyAlias(const Uint8Buff * serviceId,const Uint8Buff * keyType,const Uint8Buff * authId,Uint8Buff * keyAlias)121 static int32_t CalKeyAlias(const Uint8Buff *serviceId, const Uint8Buff *keyType,
122     const Uint8Buff *authId, Uint8Buff *keyAlias)
123 {
124     Uint8Buff keyAliasMsg = { NULL, 0 };
125     keyAliasMsg.length = serviceId->length + authId->length + keyType->length;
126     keyAliasMsg.val = (uint8_t *)HcMalloc(keyAliasMsg.length, 0);
127     if (keyAliasMsg.val == NULL) {
128         LOGE("Malloc mem failed.");
129         return HC_ERR_ALLOC_MEMORY;
130     }
131     int32_t res = BuildKeyAliasMsg(serviceId, keyType, authId, &keyAliasMsg);
132     if (res != HC_SUCCESS) {
133         HcFree(keyAliasMsg.val);
134         return res;
135     }
136     res = GetLoaderInstance()->sha256(&keyAliasMsg, keyAlias);
137     HcFree(keyAliasMsg.val);
138     if (res != HC_SUCCESS) {
139         LOGE("Sha256 failed.");
140         return res;
141     }
142     return HC_SUCCESS;
143 }
144 
CalServiceId(const char * appId,const char * groupId,Uint8Buff * serviceId)145 static int32_t CalServiceId(const char *appId, const char *groupId, Uint8Buff *serviceId)
146 {
147     uint32_t groupIdLen = HcStrlen(groupId);
148     uint32_t appIdLen = HcStrlen(appId);
149     Uint8Buff serviceIdPlain = { NULL, 0 };
150     serviceIdPlain.length = appIdLen + groupIdLen;
151     serviceIdPlain.val = (uint8_t *)HcMalloc(serviceIdPlain.length, 0);
152     if (serviceIdPlain.val == NULL) {
153         LOGE("malloc serviceIdPlain.val failed.");
154         return HC_ERR_ALLOC_MEMORY;
155     }
156     if (memcpy_s(serviceIdPlain.val, serviceIdPlain.length, appId, appIdLen) != EOK) {
157         LOGE("Copy service id: pkgName failed.");
158         HcFree(serviceIdPlain.val);
159         return HC_ERR_MEMORY_COPY;
160     }
161     if (memcpy_s(serviceIdPlain.val + appIdLen,  serviceIdPlain.length - appIdLen, groupId, groupIdLen) != EOK) {
162         LOGE("Copy service id: groupId failed.");
163         HcFree(serviceIdPlain.val);
164         return HC_ERR_MEMORY_COPY;
165     }
166     int32_t res = GetLoaderInstance()->sha256(&serviceIdPlain, serviceId);
167     HcFree(serviceIdPlain.val);
168     if (res != HC_SUCCESS) {
169         LOGE("Service id Sha256 failed.");
170         return res;
171     }
172     return HC_SUCCESS;
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: %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 fail.");
221         return HC_ERR_JSON_GET;
222     }
223     uint32_t authIdPeerStrLen = HcStrlen(authIdPeerStr) / BYTE_TO_HEX_OPER_LENGTH;
224     if (authIdPeerStrLen == 0) {
225         LOGE("Invalid authIdPeerStrLen: %u.", authIdPeerStrLen);
226         return HC_ERR_CONVERT_FAILED;
227     }
228     if (InitUint8Buff(&params->authIdPeer, authIdPeerStrLen) != HC_SUCCESS) {
229         LOGE("allocate authIdPeer memory fail.");
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:%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:%d", res);
272         return res;
273     }
274     LOGI("AuthCode alias(HEX): %x %x %x %x****.", keyAliasVal[DEV_AUTH_ZERO], keyAliasVal[DEV_AUTH_ONE],
275         keyAliasVal[DEV_AUTH_TWO], keyAliasVal[DEV_AUTH_THREE]);
276     ExtraInfo exInfo = { params->authIdPeer, params->userTypePeer, PAIR_TYPE_BIND };
277     KeyParams keyParams = { { keyAlias.val, keyAlias.length, true }, false, params->osAccountId };
278     res = GetLoaderInstance()->importSymmetricKey(&keyParams, &authCode, KEY_PURPOSE_MAC, &exInfo);
279     if (res != HC_SUCCESS) {
280         LOGE("import sym key fail.");
281         return res;
282     }
283     return HC_SUCCESS;
284 }
285 
ServerSendAuthCodeBuildEvent(const CmdParams * params,CJson ** outputEvent)286 static int32_t ServerSendAuthCodeBuildEvent(const CmdParams *params, CJson **outputEvent)
287 {
288     CJson *json = CreateJson();
289     if (json == NULL) {
290         LOGE("create json failed.");
291         return HC_ERR_JSON_CREATE;
292     }
293     if (AddIntToJson(json, FIELD_EVENT, SERVER_SEND_AUTH_CODE_EVENT) != HC_SUCCESS) {
294         LOGE("add eventName to json fail.");
295         FreeJson(json);
296         return HC_ERR_JSON_ADD;
297     }
298     if (AddByteToJson(json, FIELD_AUTH_ID_SERVER, params->authIdSelf.val,
299         params->authIdSelf.length) != HC_SUCCESS) {
300         LOGE("add authIdS to json fail.");
301         FreeJson(json);
302         return HC_ERR_JSON_ADD;
303     }
304     if (AddIntToJson(json, FIELD_USER_TYPE_SERVER, params->userTypeSelf) != HC_SUCCESS) {
305         LOGE("add userTypeS to json fail.");
306         FreeJson(json);
307         return HC_ERR_JSON_ADD;
308     }
309     if (AddByteToJson(json, FIELD_AUTH_CODE, params->authCode.val, params->authCode.length) != HC_SUCCESS) {
310         LOGE("add authCode to json fail.");
311         FreeJson(json);
312         return HC_ERR_JSON_ADD;
313     }
314     *outputEvent = json;
315     return HC_SUCCESS;
316 }
317 
ClientImportAuthCodeParseEvent(const CJson * inputEvent,CmdParams * params)318 static int32_t ClientImportAuthCodeParseEvent(const CJson *inputEvent, CmdParams *params)
319 {
320     int32_t userTypeS;
321     if (GetIntFromJson(inputEvent, FIELD_USER_TYPE_SERVER, &userTypeS) != HC_SUCCESS) {
322         LOGE("get userTypeS from json fail.");
323         return HC_ERR_JSON_GET;
324     }
325     int32_t res = GetAuthIdPeerFromInput(inputEvent, params, true);
326     if (res != HC_SUCCESS) {
327         return res;
328     }
329     uint8_t authCodeVal[AUTH_CODE_LEN] = { 0 };
330     Uint8Buff authCode = { authCodeVal, AUTH_CODE_LEN };
331     if (GetByteFromJson(inputEvent, FIELD_AUTH_CODE, authCode.val, authCode.length) != HC_SUCCESS) {
332         LOGE("get authCode from json fail.");
333         return HC_ERR_JSON_GET;
334     }
335     if (DeepCopyUint8Buff(&authCode, &params->authCode) != HC_SUCCESS) {
336         LOGE("copy authCode fail.");
337         (void)memset_s(authCodeVal, AUTH_CODE_LEN, 0, AUTH_CODE_LEN);
338         return HC_ERR_MEMORY_COPY;
339     }
340     params->userTypePeer = userTypeS;
341     return HC_SUCCESS;
342 }
343 
ClientImportAuthCodeProcEvent(const CmdParams * params)344 static int32_t ClientImportAuthCodeProcEvent(const CmdParams *params)
345 {
346     uint8_t keyAliasVal[KEY_ALIAS_LEN] = { 0 };
347     Uint8Buff keyAlias = { keyAliasVal, KEY_ALIAS_LEN };
348     int32_t res = GenerateKeyAlias(params, &keyAlias);
349     if (res != HC_SUCCESS) {
350         LOGE("GenerateKeyAliasInIso failed, res:%d", res);
351         return res;
352     }
353 
354     LOGI("AuthCode alias(HEX): %x %x %x %x****.", keyAliasVal[DEV_AUTH_ZERO], keyAliasVal[DEV_AUTH_ONE],
355         keyAliasVal[DEV_AUTH_TWO], keyAliasVal[DEV_AUTH_THREE]);
356     ExtraInfo exInfo = { params->authIdPeer, params->userTypePeer, PAIR_TYPE_BIND };
357     KeyParams keyParams = { { keyAlias.val, keyAlias.length, true }, false, params->osAccountId };
358     res = GetLoaderInstance()->importSymmetricKey(&keyParams, &(params->authCode), KEY_PURPOSE_MAC, &exInfo);
359     if (res != HC_SUCCESS) {
360         LOGE("import sym key fail.");
361         return res;
362     }
363     return HC_SUCCESS;
364 }
365 
ReturnError(int32_t errorCode,CJson ** outputEvent)366 static void ReturnError(int32_t errorCode, CJson **outputEvent)
367 {
368     (void)errorCode;
369     (void)outputEvent;
370     return;
371 }
372 
NotifyPeerError(int32_t errorCode,CJson ** outputEvent)373 static void NotifyPeerError(int32_t errorCode, CJson **outputEvent)
374 {
375     CJson *json = CreateJson();
376     if (json == NULL) {
377         LOGE("create json failed.");
378         return;
379     }
380     if (AddIntToJson(json, FIELD_EVENT, FAIL_EVENT) != HC_SUCCESS) {
381         LOGE("add eventName to json fail.");
382         FreeJson(json);
383         return;
384     }
385     if (AddIntToJson(json, FIELD_ERR_CODE, errorCode) != HC_SUCCESS) {
386         LOGE("add errorCode to json fail.");
387         FreeJson(json);
388         return;
389     }
390     *outputEvent = json;
391     return;
392 }
393 
ThrowException(BaseCmd * self,const CJson * baseEvent,CJson ** outputEvent)394 static int32_t ThrowException(BaseCmd *self, const CJson *baseEvent, CJson **outputEvent)
395 {
396     (void)self;
397     (void)outputEvent;
398     int32_t peerErrorCode = HC_ERR_PEER_ERROR;
399     (void)GetIntFromJson(baseEvent, FIELD_ERR_CODE, &peerErrorCode);
400     LOGE("An exception occurred in the peer cmd. [Code]: %d", peerErrorCode);
401     return peerErrorCode;
402 }
403 
ClientSendDevInfo(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)404 static int32_t ClientSendDevInfo(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
405 {
406     (void)inputEvent;
407     AuthCodeImportCmd *impl = (AuthCodeImportCmd *)self;
408     return ClientSendDevInfoBuildEvent(&impl->params, outputEvent);
409 }
410 
ServerGenAuthCode(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)411 static int32_t ServerGenAuthCode(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
412 {
413     AuthCodeImportCmd *impl = (AuthCodeImportCmd *)self;
414     int32_t res = ServerGenAuthCodeParseEvent(inputEvent, &impl->params);
415     if (res != HC_SUCCESS) {
416         return res;
417     }
418     res = ServerGenAuthCodeProcEvent(&impl->params);
419     if (res != HC_SUCCESS) {
420         return res;
421     }
422     return ServerSendAuthCodeBuildEvent(&impl->params, outputEvent);
423 }
424 
ClientImportAuthCode(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)425 static int32_t ClientImportAuthCode(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
426 {
427     (void)outputEvent;
428     AuthCodeImportCmd *impl = (AuthCodeImportCmd *)self;
429     int32_t res = ClientImportAuthCodeParseEvent(inputEvent, &impl->params);
430     if (res != HC_SUCCESS) {
431         return res;
432     }
433     return ClientImportAuthCodeProcEvent(&impl->params);
434 }
435 
436 static const CmdStateNode STATE_MACHINE[] = {
437     { CREATE_AS_CLIENT_STATE, START_EVENT, ClientSendDevInfo, NotifyPeerError, CLIENT_START_REQ_STATE },
438     { CREATE_AS_SERVER_STATE, CLIENT_SEND_DEV_IFNO_EVENT, ServerGenAuthCode, NotifyPeerError, SERVER_FINISH_STATE },
439     { CREATE_AS_SERVER_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
440     { CLIENT_START_REQ_STATE, SERVER_SEND_AUTH_CODE_EVENT, ClientImportAuthCode, ReturnError, CLIENT_FINISH_STATE },
441     { CLIENT_START_REQ_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
442 };
443 
DecodeEvent(const CJson * receviedMsg)444 static int32_t DecodeEvent(const CJson *receviedMsg)
445 {
446     if (receviedMsg == NULL) {
447         return START_EVENT;
448     }
449     int32_t event;
450     if (GetIntFromJson(receviedMsg, FIELD_EVENT, &event) != HC_SUCCESS) {
451         LOGE("get event from receviedMsg fail.");
452         return UNKNOWN_EVENT;
453     }
454     if (START_EVENT <= event && event <= UNKNOWN_EVENT) {
455         return event;
456     }
457     LOGE("unknown event.");
458     return UNKNOWN_EVENT;
459 }
460 
SwitchState(BaseCmd * self,const CJson * receviedMsg,CJson ** returnSendMsg,CmdState * returnState)461 static int32_t SwitchState(BaseCmd *self, const CJson *receviedMsg, CJson **returnSendMsg, CmdState *returnState)
462 {
463     int32_t eventType = DecodeEvent(receviedMsg);
464     for (uint32_t i = 0; i < sizeof(STATE_MACHINE) / sizeof(STATE_MACHINE[0]); i++) {
465         if ((STATE_MACHINE[i].curState == self->curState) && (STATE_MACHINE[i].eventType == eventType)) {
466             int32_t res = STATE_MACHINE[i].stateProcessFunc(self, receviedMsg, returnSendMsg);
467             if (res != HC_SUCCESS) {
468                 STATE_MACHINE[i].exceptionHandleFunc(res, returnSendMsg);
469                 self->curState = self->failState;
470                 return res;
471             }
472             LOGI("event: %d, curState: %d, nextState: %d", eventType, self->curState, STATE_MACHINE[i].nextState);
473             self->curState = STATE_MACHINE[i].nextState;
474             *returnState = (self->curState == self->finishState) ? CMD_STATE_FINISH : CMD_STATE_CONTINUE;
475             return HC_SUCCESS;
476         }
477     }
478     LOGI("Unsupported event type. Ignore process. [Event]: %d, [CurState]: %d", eventType, self->curState);
479     return HC_SUCCESS;
480 }
481 
StartAuthCodeImportCmd(BaseCmd * self,CJson ** returnSendMsg)482 static int32_t StartAuthCodeImportCmd(BaseCmd *self, CJson **returnSendMsg)
483 {
484     if ((self == NULL) || (returnSendMsg == NULL)) {
485         LOGE("invalid params.");
486         return HC_ERR_INVALID_PARAMS;
487     }
488     if (self->curState != self->beginState) {
489         LOGE("The protocol has ended, and the state switch cannot continue!");
490         return HC_ERR_UNSUPPORTED_OPCODE;
491     }
492     CmdState state;
493     return SwitchState(self, NULL, returnSendMsg, &state);
494 }
495 
ProcessAuthCodeImportCmd(BaseCmd * self,const CJson * receviedMsg,CJson ** returnSendMsg,CmdState * returnState)496 static int32_t ProcessAuthCodeImportCmd(BaseCmd *self, const CJson *receviedMsg,
497     CJson **returnSendMsg, CmdState *returnState)
498 {
499     if ((self == NULL) || (receviedMsg == NULL) || (returnSendMsg == NULL) || (returnState == NULL)) {
500         LOGE("invalid params.");
501         return HC_ERR_INVALID_PARAMS;
502     }
503     if ((self->curState == self->finishState) || (self->curState == self->failState)) {
504         LOGE("The protocol has ended, and the state switch cannot continue!");
505         return HC_ERR_UNSUPPORTED_OPCODE;
506     }
507     return SwitchState(self, receviedMsg, returnSendMsg, returnState);
508 }
509 
DestroyAuthCodeImportCmd(BaseCmd * self)510 static void DestroyAuthCodeImportCmd(BaseCmd *self)
511 {
512     if (self == NULL) {
513         LOGD("self is null.");
514         return;
515     }
516     AuthCodeImportCmd *impl = (AuthCodeImportCmd *)self;
517     ClearFreeUint8Buff(&impl->params.authCode);
518     ClearFreeUint8Buff(&impl->params.authIdSelf);
519     ClearFreeUint8Buff(&impl->params.authIdPeer);
520     HcFree(impl->params.groupId);
521     HcFree(impl->params.appId);
522     HcFree(impl);
523 }
524 
IsAuthCodeImportParamsValid(const AuthCodeImportParams * params)525 static bool IsAuthCodeImportParamsValid(const AuthCodeImportParams *params)
526 {
527     if ((params == NULL) || (params->appId == NULL) || (params->authId.val == NULL) ||
528         (params->authId.length == 0) || (params->groupId == NULL)) {
529         return false;
530     }
531     return true;
532 }
533 
InitAuthCodeImportCmd(AuthCodeImportCmd * instance,const AuthCodeImportParams * params,bool isCaller,int32_t strategy)534 static int32_t InitAuthCodeImportCmd(AuthCodeImportCmd *instance, const AuthCodeImportParams *params,
535     bool isCaller, int32_t strategy)
536 {
537     if (DeepCopyUint8Buff(&params->authId, &(instance->params.authIdSelf)) != HC_SUCCESS) {
538         LOGE("copy authIdSelf fail.");
539         return HC_ERR_ALLOC_MEMORY;
540     }
541     if (DeepCopyString(params->appId, &(instance->params.appId)) != HC_SUCCESS) {
542         LOGE("copy appId fail.");
543         return HC_ERR_ALLOC_MEMORY;
544     }
545     if (DeepCopyString(params->groupId, &(instance->params.groupId)) != HC_SUCCESS) {
546         LOGE("copy groupId fail.");
547         return HC_ERR_ALLOC_MEMORY;
548     }
549     instance->params.osAccountId = params->osAccountId;
550     instance->params.userTypeSelf = params->userType;
551     instance->base.type = AUTH_CODE_IMPORT_CMD_TYPE;
552     instance->base.strategy = strategy;
553     instance->base.isCaller = isCaller;
554     instance->base.beginState = isCaller ? CREATE_AS_CLIENT_STATE : CREATE_AS_SERVER_STATE;
555     instance->base.finishState = isCaller ? CLIENT_FINISH_STATE : SERVER_FINISH_STATE;
556     instance->base.failState = FAIL_STATE;
557     instance->base.curState = instance->base.beginState;
558     instance->base.start = StartAuthCodeImportCmd;
559     instance->base.process = ProcessAuthCodeImportCmd;
560     instance->base.destroy = DestroyAuthCodeImportCmd;
561     return HC_SUCCESS;
562 }
563 
CreateAuthCodeImportCmd(const void * baseParams,bool isCaller,int32_t strategy)564 BaseCmd *CreateAuthCodeImportCmd(const void *baseParams, bool isCaller, int32_t strategy)
565 {
566     const AuthCodeImportParams *params = (const AuthCodeImportParams *)baseParams;
567     if (!IsAuthCodeImportParamsValid(params)) {
568         LOGE("invalid params.");
569         return NULL;
570     }
571     AuthCodeImportCmd *instance = (AuthCodeImportCmd *)HcMalloc(sizeof(AuthCodeImportCmd), 0);
572     if (instance == NULL) {
573         LOGE("allocate instance memory fail.");
574         return NULL;
575     }
576     int32_t res = InitAuthCodeImportCmd(instance, params, isCaller, strategy);
577     if (res != HC_SUCCESS) {
578         DestroyAuthCodeImportCmd((BaseCmd *)instance);
579         return NULL;
580     }
581     return (BaseCmd *)instance;
582 }
583