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 "pub_key_exchange.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 FAIL_EVENT_NAME "CmdFail"
25 
26 #define FIELD_USER_TYPE_CLIENT "userTypeC"
27 #define FIELD_USER_TYPE_SERVER "userTypeS"
28 #define FIELD_AUTH_ID_CLIENT "authIdC"
29 #define FIELD_AUTH_ID_SERVER "authIdS"
30 #define FIELD_AUTH_PK_CLIENT "authPkC"
31 #define FIELD_AUTH_PK_SERVER "authPkS"
32 
33 #define FIELD_EVENT "event"
34 #define FIELD_ERR_CODE "errCode"
35 #define FIELD_ERR_MSG "errMsg"
36 
37 typedef struct {
38     int32_t userTypeSelf;
39     int32_t userTypePeer;
40     char *groupId;
41     char *appId;
42     Uint8Buff authIdSelf;
43     Uint8Buff authIdPeer;
44     Uint8Buff pkSelf;
45     Uint8Buff pkPeer;
46     bool isSelfFromUpgrade;
47     int32_t osAccountId;
48 } CmdParams;
49 
50 typedef struct {
51     BaseCmd base;
52     CmdParams params;
53 } PubKeyExchangeCmd;
54 
55 typedef enum {
56     START_EVENT = 0,
57     CLIENT_SEND_PK_INFO_EVENT,
58     SERVER_SEND_PK_INFO_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,bool isSelf,bool isPsk,Uint8Buff * keyAlias)175 static int32_t GenerateKeyAlias(const CmdParams *params, bool isSelf, bool isPsk, 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     const Uint8Buff *authId = isSelf ? &(params->authIdSelf) : &(params->authIdPeer);
185 #ifdef DEV_AUTH_FUNC_TEST
186     int32_t userType = isSelf ? params->userTypeSelf : KEY_ALIAS_LT_KEY_PAIR;
187 #else
188     int32_t userType = isSelf ? params->userTypeSelf : params->userTypePeer;
189 #endif
190     KeyAliasType keyAliasType = isPsk ? KEY_ALIAS_PSK : (uint32_t)userType;
191     if (isSelf && !isPsk && params->isSelfFromUpgrade) {
192         keyAliasType = KEY_ALIAS_LT_KEY_PAIR;
193     }
194     Uint8Buff keyTypeBuff = { GetKeyTypePair(keyAliasType), KEY_TYPE_PAIR_LEN };
195     uint8_t keyAliasByteVal[SHA256_LEN] = { 0 };
196     Uint8Buff keyAliasByte = { keyAliasByteVal, SHA256_LEN };
197     res = CalKeyAlias(&serviceId, &keyTypeBuff, authId, &keyAliasByte);
198     if (res != HC_SUCCESS) {
199         LOGE("cal keyalias fail.");
200         return res;
201     }
202     uint32_t keyAliasHexStrLen = SHA256_LEN * BYTE_TO_HEX_OPER_LENGTH + 1;
203     char keyAliasHexStr[SHA256_LEN * BYTE_TO_HEX_OPER_LENGTH + 1] = { 0 };
204     if (ByteToHexString(keyAliasByte.val, keyAliasByte.length, keyAliasHexStr, keyAliasHexStrLen) != HC_SUCCESS) {
205         LOGE("ByteToHexString failed");
206         return HC_ERR_MEMORY_COPY;
207     }
208     if (memcpy_s(keyAlias->val, keyAlias->length, keyAliasHexStr, HcStrlen(keyAliasHexStr)) != EOK) {
209         LOGE("memcpy keyalias failed.");
210         return HC_ERR_MEMORY_COPY;
211     }
212     return HC_SUCCESS;
213 }
214 
ExportSelfPubKey(CmdParams * params)215 static int32_t ExportSelfPubKey(CmdParams *params)
216 {
217     uint8_t keyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
218     Uint8Buff keyAlias = { keyAliasVal, PAKE_KEY_ALIAS_LEN };
219     int32_t res = GenerateKeyAlias(params, true, false, &keyAlias);
220     if (res != HC_SUCCESS) {
221         LOGE("generateKeyAlias failed");
222         return res;
223     }
224     if (params->isSelfFromUpgrade) {
225         res = ToLowerCase(&keyAlias);
226         if (res != HC_SUCCESS) {
227             LOGE("Failed to convert self key alias to lower case!");
228             return res;
229         }
230     }
231     res = GetLoaderInstance()->checkKeyExist(&keyAlias, params->isSelfFromUpgrade, params->osAccountId);
232     KeyParams keyParams = { { keyAlias.val, keyAlias.length, true }, params->isSelfFromUpgrade, params->osAccountId };
233     if (res != HC_SUCCESS) {
234         if (params->isSelfFromUpgrade) {
235             LOGE("Self device is from upgrade, key pair not exist!");
236             return res;
237         }
238         LOGI("The local identity key pair does not exist, generate it.");
239         Algorithm alg = ED25519;
240         /* UserType and pairType are not required when generating key. */
241         ExtraInfo exInfo = { params->authIdSelf, -1, -1 };
242         res = GetLoaderInstance()->generateKeyPairWithStorage(&keyParams, PAKE_ED25519_KEY_PAIR_LEN, alg,
243             KEY_PURPOSE_SIGN_VERIFY, &exInfo);
244         if (res != HC_SUCCESS) {
245             LOGE("generate self auth keyPair failed.");
246             return res;
247         }
248         LOGI("generate self auth keyPair success.");
249     }
250     if (InitUint8Buff(&params->pkSelf, PAKE_ED25519_KEY_PAIR_LEN) != HC_SUCCESS) {
251         LOGE("allocate pkSelf memory fail.");
252         return HC_ERR_ALLOC_MEMORY;
253     }
254     res = GetLoaderInstance()->exportPublicKey(&keyParams, &params->pkSelf);
255     if (res != HC_SUCCESS) {
256         LOGE("exportPublicKey failed");
257         return res;
258     }
259     return HC_SUCCESS;
260 }
261 
ClientSendPkInfoProcEvent(CmdParams * params)262 static int32_t ClientSendPkInfoProcEvent(CmdParams *params)
263 {
264     return ExportSelfPubKey(params);
265 }
266 
ClientSendPkInfoBuildEvent(const CmdParams * params,CJson ** outputEvent)267 static int32_t ClientSendPkInfoBuildEvent(const CmdParams *params, CJson **outputEvent)
268 {
269     CJson *json = CreateJson();
270     if (json == NULL) {
271         LOGE("create json failed.");
272         return HC_ERR_JSON_CREATE;
273     }
274     if (AddIntToJson(json, FIELD_EVENT, CLIENT_SEND_PK_INFO_EVENT) != HC_SUCCESS) {
275         LOGE("add eventName to json fail.");
276         FreeJson(json);
277         return HC_ERR_JSON_ADD;
278     }
279     if (AddByteToJson(json, FIELD_AUTH_ID_CLIENT, params->authIdSelf.val,
280         params->authIdSelf.length) != HC_SUCCESS) {
281         LOGE("add authIdC to json fail.");
282         FreeJson(json);
283         return HC_ERR_JSON_ADD;
284     }
285     if (AddIntToJson(json, FIELD_USER_TYPE_CLIENT, params->userTypeSelf) != HC_SUCCESS) {
286         LOGE("add userTypeC to json fail.");
287         FreeJson(json);
288         return HC_ERR_JSON_ADD;
289     }
290     if (AddByteToJson(json, FIELD_AUTH_PK_CLIENT, params->pkSelf.val, params->pkSelf.length) != HC_SUCCESS) {
291         LOGE("add authPkC to json fail.");
292         FreeJson(json);
293         return HC_ERR_JSON_ADD;
294     }
295     *outputEvent = json;
296     return HC_SUCCESS;
297 }
298 
GetAuthIdPeerFromInput(const CJson * inputEvent,CmdParams * params,bool isClient)299 static int32_t GetAuthIdPeerFromInput(const CJson *inputEvent, CmdParams *params, bool isClient)
300 {
301     const char *authIdPeerStr = isClient ? GetStringFromJson(inputEvent, FIELD_AUTH_ID_SERVER) :
302         GetStringFromJson(inputEvent, FIELD_AUTH_ID_CLIENT);
303     if (authIdPeerStr == NULL) {
304         LOGE("get authIdPeerStr from inputEvent fail.");
305         return HC_ERR_JSON_GET;
306     }
307     uint32_t authIdPeerStrLen = HcStrlen(authIdPeerStr) / BYTE_TO_HEX_OPER_LENGTH;
308     if (authIdPeerStrLen == 0) {
309         LOGE("Invalid authIdPeerStrLen: %u.", authIdPeerStrLen);
310         return HC_ERR_CONVERT_FAILED;
311     }
312     if (InitUint8Buff(&params->authIdPeer, authIdPeerStrLen) != HC_SUCCESS) {
313         LOGE("allocate authIdPeer memory fail.");
314         return HC_ERR_ALLOC_MEMORY;
315     }
316     if (HexStringToByte(authIdPeerStr, params->authIdPeer.val, params->authIdPeer.length) != HC_SUCCESS) {
317         LOGE("HexStringToByte for authIdPeerStr failed.");
318         return HC_ERR_CONVERT_FAILED;
319     }
320     return HC_SUCCESS;
321 }
322 
ServerSendPkInfoParseEvent(const CJson * inputEvent,CmdParams * params)323 static int32_t ServerSendPkInfoParseEvent(const CJson *inputEvent, CmdParams *params)
324 {
325     int32_t res = GetAuthIdPeerFromInput(inputEvent, params, false);
326     if (res != HC_SUCCESS) {
327         return res;
328     }
329     int32_t userTypeC;
330     if (GetIntFromJson(inputEvent, FIELD_USER_TYPE_CLIENT, &userTypeC) != HC_SUCCESS) {
331         LOGE("get userTypeC from json fail.");
332         return HC_ERR_JSON_GET;
333     }
334     if (InitUint8Buff(&params->pkPeer, PAKE_ED25519_KEY_PAIR_LEN) != HC_SUCCESS) {
335         LOGE("allocate pkPeer memory fail.");
336         return HC_ERR_ALLOC_MEMORY;
337     }
338     if (GetByteFromJson(inputEvent, FIELD_AUTH_PK_CLIENT, params->pkPeer.val,
339         params->pkPeer.length) != HC_SUCCESS) {
340         LOGE("get authPkC from json fail.");
341         return HC_ERR_JSON_GET;
342     }
343     params->userTypePeer = userTypeC;
344     return HC_SUCCESS;
345 }
346 
GenerateSelfKeyAlias(const CmdParams * params,Uint8Buff * selfKeyAlias)347 static int32_t GenerateSelfKeyAlias(const CmdParams *params, Uint8Buff *selfKeyAlias)
348 {
349     int32_t res = GenerateKeyAlias(params, true, false, selfKeyAlias);
350     if (res != HC_SUCCESS) {
351         LOGE("generate self keyAlias failed");
352         return res;
353     }
354     if (params->isSelfFromUpgrade) {
355         res = ToLowerCase(selfKeyAlias);
356         if (res != HC_SUCCESS) {
357             LOGE("Failed to convert self key alias to lower case!");
358             return res;
359         }
360     }
361     return HC_SUCCESS;
362 }
363 
ComputeAndSavePskInner(int32_t osAccountId,const Uint8Buff * selfKeyAlias,const Uint8Buff * peerKeyAlias,bool isSelfFromUpgrade,Uint8Buff * sharedKeyAlias)364 static int32_t ComputeAndSavePskInner(int32_t osAccountId, const Uint8Buff *selfKeyAlias,
365     const Uint8Buff *peerKeyAlias, bool isSelfFromUpgrade, Uint8Buff *sharedKeyAlias)
366 {
367     KeyParams selfKeyParams = { { selfKeyAlias->val, selfKeyAlias->length, true }, isSelfFromUpgrade, osAccountId };
368     uint8_t peerPubKeyVal[PAKE_ED25519_KEY_PAIR_LEN] = { 0 };
369     Uint8Buff peerPubKeyBuff = { peerPubKeyVal, PAKE_ED25519_KEY_PAIR_LEN };
370     KeyParams keyParams = { { peerKeyAlias->val, peerKeyAlias->length, true }, false, osAccountId };
371     int32_t res = GetLoaderInstance()->exportPublicKey(&keyParams, &peerPubKeyBuff);
372     if (res != HC_SUCCESS) {
373         LOGE("Failed to export peer public key!");
374         return res;
375     }
376     KeyBuff peerKeyBuff = { peerPubKeyBuff.val, peerPubKeyBuff.length, false };
377     res = GetLoaderInstance()->agreeSharedSecretWithStorage(&selfKeyParams, &peerKeyBuff, ED25519,
378         PAKE_PSK_LEN, sharedKeyAlias);
379     if (res != HC_SUCCESS) {
380         LOGE("Agree psk failed.");
381     }
382     return res;
383 }
384 
ComputeAndSavePsk(const CmdParams * params)385 static int32_t ComputeAndSavePsk(const CmdParams *params)
386 {
387     uint8_t selfKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
388     Uint8Buff selfKeyAlias = { selfKeyAliasVal, PAKE_KEY_ALIAS_LEN };
389     uint8_t peerKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
390     Uint8Buff peerKeyAlias = { peerKeyAliasVal, PAKE_KEY_ALIAS_LEN };
391     int32_t res = GenerateSelfKeyAlias(params, &selfKeyAlias);
392     if (res != HC_SUCCESS) {
393         return res;
394     }
395     res = GenerateKeyAlias(params, false, false, &peerKeyAlias);
396     if (res != HC_SUCCESS) {
397         LOGE("generate peer keyAlias failed");
398         return res;
399     }
400     res = GetLoaderInstance()->checkKeyExist(&selfKeyAlias, params->isSelfFromUpgrade, params->osAccountId);
401     if (res != HC_SUCCESS) {
402         LOGE("self auth keyPair not exist");
403         return res;
404     }
405     res = GetLoaderInstance()->checkKeyExist(&peerKeyAlias, false, params->osAccountId);
406     if (res != HC_SUCCESS) {
407         LOGE("peer auth pubKey not exist");
408         return res;
409     }
410     uint8_t sharedKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
411     Uint8Buff sharedKeyAlias = { sharedKeyAliasVal, PAKE_KEY_ALIAS_LEN };
412     res = GenerateKeyAlias(params, false, true, &sharedKeyAlias);
413     if (res != HC_SUCCESS) {
414         LOGE("generate psk keyAlias failed");
415         return res;
416     }
417     LOGI("peerPubKey alias: %x %x %x %x****", peerKeyAliasVal[DEV_AUTH_ZERO], peerKeyAliasVal[DEV_AUTH_ONE],
418         peerKeyAliasVal[DEV_AUTH_TWO], peerKeyAliasVal[DEV_AUTH_THREE]);
419     LOGI("selfPriKey alias: %x %x %x %x****", selfKeyAliasVal[DEV_AUTH_ZERO], selfKeyAliasVal[DEV_AUTH_ONE],
420         selfKeyAliasVal[DEV_AUTH_TWO], selfKeyAliasVal[DEV_AUTH_THREE]);
421     LOGI("psk alias: %x %x %x %x****", sharedKeyAliasVal[DEV_AUTH_ZERO], sharedKeyAliasVal[DEV_AUTH_ONE],
422         sharedKeyAliasVal[DEV_AUTH_TWO], sharedKeyAliasVal[DEV_AUTH_THREE]);
423     return ComputeAndSavePskInner(params->osAccountId, &selfKeyAlias, &peerKeyAlias, params->isSelfFromUpgrade,
424         &sharedKeyAlias);
425 }
426 
SavePeerPubKey(const CmdParams * params)427 static int32_t SavePeerPubKey(const CmdParams *params)
428 {
429     uint8_t keyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
430     Uint8Buff keyAlias = { keyAliasVal, PAKE_KEY_ALIAS_LEN };
431     int32_t res = GenerateKeyAlias(params, false, false, &keyAlias);
432     if (res != HC_SUCCESS) {
433         LOGE("generateKeyAlias failed");
434         return res;
435     }
436     LOGI("PubKey alias: %x %x %x %x****.", keyAliasVal[DEV_AUTH_ZERO], keyAliasVal[DEV_AUTH_ONE],
437         keyAliasVal[DEV_AUTH_TWO], keyAliasVal[DEV_AUTH_THREE]);
438     ExtraInfo exInfo = { params->authIdPeer, params->userTypeSelf, PAIR_TYPE_BIND };
439     KeyParams keyParams = { { keyAlias.val, keyAlias.length, true }, false, params->osAccountId };
440     res = GetLoaderInstance()->importPublicKey(&keyParams, &params->pkPeer, ED25519, &exInfo);
441     if (res != HC_SUCCESS) {
442         LOGE("import peer pubKey failed");
443         return res;
444     }
445     LOGI("Save pubKey success.");
446     return HC_SUCCESS;
447 }
448 
ServerSendPkInfoProcEvent(CmdParams * params)449 static int32_t ServerSendPkInfoProcEvent(CmdParams *params)
450 {
451     int32_t res = ExportSelfPubKey(params);
452     if (res != HC_SUCCESS) {
453         return res;
454     }
455     res = SavePeerPubKey(params);
456     if (res != HC_SUCCESS) {
457         return res;
458     }
459     return ComputeAndSavePsk(params);
460 }
461 
ServerSendAuthCodeBuildEvent(const CmdParams * params,CJson ** outputEvent)462 static int32_t ServerSendAuthCodeBuildEvent(const CmdParams *params, CJson **outputEvent)
463 {
464     CJson *json = CreateJson();
465     if (json == NULL) {
466         LOGE("create json failed.");
467         return HC_ERR_JSON_CREATE;
468     }
469     if (AddIntToJson(json, FIELD_EVENT, SERVER_SEND_PK_INFO_EVENT) != HC_SUCCESS) {
470         LOGE("add eventName to json fail.");
471         FreeJson(json);
472         return HC_ERR_JSON_ADD;
473     }
474     if (AddByteToJson(json, FIELD_AUTH_ID_SERVER, params->authIdSelf.val,
475         params->authIdSelf.length) != HC_SUCCESS) {
476         LOGE("add authIdS to json fail.");
477         FreeJson(json);
478         return HC_ERR_JSON_ADD;
479     }
480     if (AddIntToJson(json, FIELD_USER_TYPE_SERVER, params->userTypeSelf) != HC_SUCCESS) {
481         LOGE("add userTypeC to json fail.");
482         FreeJson(json);
483         return HC_ERR_JSON_ADD;
484     }
485     if (AddByteToJson(json, FIELD_AUTH_PK_SERVER, params->pkSelf.val, params->pkSelf.length) != HC_SUCCESS) {
486         LOGE("add authPkS to json fail.");
487         FreeJson(json);
488         return HC_ERR_JSON_ADD;
489     }
490     *outputEvent = json;
491     return HC_SUCCESS;
492 }
493 
ClientImportPkParseEvent(const CJson * inputEvent,CmdParams * params)494 static int32_t ClientImportPkParseEvent(const CJson *inputEvent, CmdParams *params)
495 {
496     int32_t res = GetAuthIdPeerFromInput(inputEvent, params, true);
497     if (res != HC_SUCCESS) {
498         return res;
499     }
500     int32_t userTypeS;
501     if (GetIntFromJson(inputEvent, FIELD_USER_TYPE_SERVER, &userTypeS) != HC_SUCCESS) {
502         LOGE("get userTypeS from json fail.");
503         return HC_ERR_JSON_GET;
504     }
505     if (InitUint8Buff(&params->pkPeer, PAKE_ED25519_KEY_PAIR_LEN) != HC_SUCCESS) {
506         LOGE("allocate pkPeer memory fail.");
507         return HC_ERR_ALLOC_MEMORY;
508     }
509     if (GetByteFromJson(inputEvent, FIELD_AUTH_PK_SERVER, params->pkPeer.val,
510         params->pkPeer.length) != HC_SUCCESS) {
511         LOGE("get authPkS from json fail.");
512         return HC_ERR_JSON_GET;
513     }
514     params->userTypePeer = userTypeS;
515     return HC_SUCCESS;
516 }
517 
ClientImportPkProcEvent(const CmdParams * params)518 static int32_t ClientImportPkProcEvent(const CmdParams *params)
519 {
520     int32_t res = SavePeerPubKey(params);
521     if (res != HC_SUCCESS) {
522         return res;
523     }
524     return ComputeAndSavePsk(params);
525 }
526 
ReturnError(int32_t errorCode,CJson ** outputEvent)527 static void ReturnError(int32_t errorCode, CJson **outputEvent)
528 {
529     (void)errorCode;
530     (void)outputEvent;
531     return;
532 }
533 
NotifyPeerError(int32_t errorCode,CJson ** outputEvent)534 static void NotifyPeerError(int32_t errorCode, CJson **outputEvent)
535 {
536     CJson *json = CreateJson();
537     if (json == NULL) {
538         LOGE("create json failed.");
539         return;
540     }
541     if (AddIntToJson(json, FIELD_EVENT, FAIL_EVENT) != HC_SUCCESS) {
542         LOGE("add eventName to json fail.");
543         FreeJson(json);
544         return;
545     }
546     if (AddIntToJson(json, FIELD_ERR_CODE, errorCode) != HC_SUCCESS) {
547         LOGE("add errorCode to json fail.");
548         FreeJson(json);
549         return;
550     }
551     *outputEvent = json;
552     return;
553 }
554 
ThrowException(BaseCmd * self,const CJson * baseEvent,CJson ** outputEvent)555 static int32_t ThrowException(BaseCmd *self, const CJson *baseEvent, CJson **outputEvent)
556 {
557     (void)self;
558     (void)outputEvent;
559     int32_t peerErrorCode = HC_ERR_PEER_ERROR;
560     (void)GetIntFromJson(baseEvent, FIELD_ERR_CODE, &peerErrorCode);
561     LOGE("An exception occurred in the peer cmd. [Code]: %d", peerErrorCode);
562     return peerErrorCode;
563 }
564 
ClientSendPkInfo(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)565 static int32_t ClientSendPkInfo(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
566 {
567     (void)inputEvent;
568     PubKeyExchangeCmd *impl = (PubKeyExchangeCmd *)self;
569     int32_t res = ClientSendPkInfoProcEvent(&impl->params);
570     if (res != HC_SUCCESS) {
571         return res;
572     }
573     return ClientSendPkInfoBuildEvent(&impl->params, outputEvent);
574 }
575 
ServerSendPkInfo(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)576 static int32_t ServerSendPkInfo(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
577 {
578     PubKeyExchangeCmd *impl = (PubKeyExchangeCmd *)self;
579     int32_t res = ServerSendPkInfoParseEvent(inputEvent, &impl->params);
580     if (res != HC_SUCCESS) {
581         return res;
582     }
583     res = ServerSendPkInfoProcEvent(&impl->params);
584     if (res != HC_SUCCESS) {
585         return res;
586     }
587     return ServerSendAuthCodeBuildEvent(&impl->params, outputEvent);
588 }
589 
ClientImportPk(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)590 static int32_t ClientImportPk(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
591 {
592     (void)outputEvent;
593     PubKeyExchangeCmd *impl = (PubKeyExchangeCmd *)self;
594     int32_t res = ClientImportPkParseEvent(inputEvent, &impl->params);
595     if (res != HC_SUCCESS) {
596         return res;
597     }
598     return ClientImportPkProcEvent(&impl->params);
599 }
600 
601 static const CmdStateNode STATE_MACHINE[] = {
602     { CREATE_AS_CLIENT_STATE, START_EVENT, ClientSendPkInfo, NotifyPeerError, CLIENT_START_REQ_STATE },
603     { CREATE_AS_SERVER_STATE, CLIENT_SEND_PK_INFO_EVENT, ServerSendPkInfo, NotifyPeerError, SERVER_FINISH_STATE },
604     { CREATE_AS_SERVER_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
605     { CLIENT_START_REQ_STATE, SERVER_SEND_PK_INFO_EVENT, ClientImportPk, ReturnError, CLIENT_FINISH_STATE },
606     { CLIENT_START_REQ_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
607 };
608 
DecodeEvent(const CJson * receviedMsg)609 static int32_t DecodeEvent(const CJson *receviedMsg)
610 {
611     if (receviedMsg == NULL) {
612         return START_EVENT;
613     }
614     int32_t event;
615     if (GetIntFromJson(receviedMsg, FIELD_EVENT, &event) != HC_SUCCESS) {
616         LOGE("get event from receviedMsg fail.");
617         return UNKNOWN_EVENT;
618     }
619     if (START_EVENT <= event && event <= UNKNOWN_EVENT) {
620         return event;
621     }
622     LOGE("unknown event.");
623     return UNKNOWN_EVENT;
624 }
625 
SwitchState(BaseCmd * self,const CJson * receviedMsg,CJson ** returnSendMsg,CmdState * returnState)626 static int32_t SwitchState(BaseCmd *self, const CJson *receviedMsg, CJson **returnSendMsg, CmdState *returnState)
627 {
628     int32_t eventType = DecodeEvent(receviedMsg);
629     for (uint32_t i = 0; i < sizeof(STATE_MACHINE) / sizeof(STATE_MACHINE[0]); i++) {
630         if ((STATE_MACHINE[i].curState == self->curState) && (STATE_MACHINE[i].eventType == eventType)) {
631             int32_t res = STATE_MACHINE[i].stateProcessFunc(self, receviedMsg, returnSendMsg);
632             if (res != HC_SUCCESS) {
633                 STATE_MACHINE[i].exceptionHandleFunc(res, returnSendMsg);
634                 self->curState = self->failState;
635                 return res;
636             }
637             LOGI("event: %d, curState: %d, nextState: %d", eventType, self->curState, STATE_MACHINE[i].nextState);
638             self->curState = STATE_MACHINE[i].nextState;
639             *returnState = (self->curState == self->finishState) ? CMD_STATE_FINISH : CMD_STATE_CONTINUE;
640             return HC_SUCCESS;
641         }
642     }
643     LOGI("Unsupported event type. Ignore process. [Event]: %d, [CurState]: %d", eventType, self->curState);
644     return HC_SUCCESS;
645 }
646 
StartPubKeyExchangeCmd(BaseCmd * self,CJson ** returnSendMsg)647 static int32_t StartPubKeyExchangeCmd(BaseCmd *self, CJson **returnSendMsg)
648 {
649     if ((self == NULL) || (returnSendMsg == NULL)) {
650         LOGE("invalid params.");
651         return HC_ERR_INVALID_PARAMS;
652     }
653     if (self->curState != self->beginState) {
654         LOGE("The protocol has ended, and the state switch cannot continue!");
655         return HC_ERR_UNSUPPORTED_OPCODE;
656     }
657     CmdState state;
658     return SwitchState(self, NULL, returnSendMsg, &state);
659 }
660 
ProcessPubKeyExchangeCmd(BaseCmd * self,const CJson * receviedMsg,CJson ** returnSendMsg,CmdState * returnState)661 static int32_t ProcessPubKeyExchangeCmd(BaseCmd *self, const CJson *receviedMsg,
662     CJson **returnSendMsg, CmdState *returnState)
663 {
664     if ((self == NULL) || (receviedMsg == NULL) || (returnSendMsg == NULL) || (returnState == NULL)) {
665         LOGE("invalid params.");
666         return HC_ERR_INVALID_PARAMS;
667     }
668     if ((self->curState == self->finishState) || (self->curState == self->failState)) {
669         LOGE("The protocol has ended, and the state switch cannot continue!");
670         return HC_ERR_UNSUPPORTED_OPCODE;
671     }
672     return SwitchState(self, receviedMsg, returnSendMsg, returnState);
673 }
674 
DestroyPubKeyExchangeCmd(BaseCmd * self)675 static void DestroyPubKeyExchangeCmd(BaseCmd *self)
676 {
677     if (self == NULL) {
678         LOGD("self is null.");
679         return;
680     }
681     PubKeyExchangeCmd *impl = (PubKeyExchangeCmd *)self;
682     ClearFreeUint8Buff(&impl->params.pkSelf);
683     ClearFreeUint8Buff(&impl->params.pkPeer);
684     ClearFreeUint8Buff(&impl->params.authIdSelf);
685     ClearFreeUint8Buff(&impl->params.authIdPeer);
686     HcFree(impl->params.groupId);
687     HcFree(impl->params.appId);
688     HcFree(impl);
689 }
690 
IsPubKeyExchangeParamsValid(const PubKeyExchangeParams * params)691 static bool IsPubKeyExchangeParamsValid(const PubKeyExchangeParams *params)
692 {
693     if ((params == NULL) || (params->appId == NULL) || (params->authId.val == NULL) ||
694         (params->authId.length == 0) || (params->groupId == NULL)) {
695         return false;
696     }
697     return true;
698 }
699 
InitPubkeyExchangeCmd(PubKeyExchangeCmd * instance,const PubKeyExchangeParams * params,bool isCaller,int32_t strategy)700 static int32_t InitPubkeyExchangeCmd(PubKeyExchangeCmd *instance, const PubKeyExchangeParams *params,
701     bool isCaller, int32_t strategy)
702 {
703     if (DeepCopyUint8Buff(&params->authId, &(instance->params.authIdSelf)) != HC_SUCCESS) {
704         LOGE("copy authIdSelf fail.");
705         return HC_ERR_ALLOC_MEMORY;
706     }
707     if (DeepCopyString(params->appId, &(instance->params.appId)) != HC_SUCCESS) {
708         LOGE("copy appId fail.");
709         return HC_ERR_ALLOC_MEMORY;
710     }
711     if (DeepCopyString(params->groupId, &(instance->params.groupId)) != HC_SUCCESS) {
712         LOGE("copy groupId fail.");
713         return HC_ERR_ALLOC_MEMORY;
714     }
715     instance->params.osAccountId = params->osAccountId;
716     instance->params.userTypeSelf = params->userType;
717     instance->params.isSelfFromUpgrade = params->isSelfFromUpgrade;
718     instance->base.type = PUB_KEY_EXCHANGE_CMD_TYPE;
719     instance->base.strategy = strategy;
720     instance->base.isCaller = isCaller;
721     instance->base.beginState = isCaller ? CREATE_AS_CLIENT_STATE : CREATE_AS_SERVER_STATE;
722     instance->base.finishState = isCaller ? CLIENT_FINISH_STATE : SERVER_FINISH_STATE;
723     instance->base.failState = FAIL_STATE;
724     instance->base.curState = instance->base.beginState;
725     instance->base.start = StartPubKeyExchangeCmd;
726     instance->base.process = ProcessPubKeyExchangeCmd;
727     instance->base.destroy = DestroyPubKeyExchangeCmd;
728     return HC_SUCCESS;
729 }
730 
CreatePubKeyExchangeCmd(const void * baseParams,bool isCaller,int32_t strategy)731 BaseCmd *CreatePubKeyExchangeCmd(const void *baseParams, bool isCaller, int32_t strategy)
732 {
733     const PubKeyExchangeParams *params = (const PubKeyExchangeParams *)baseParams;
734     if (!IsPubKeyExchangeParamsValid(params)) {
735         LOGE("invalid params.");
736         return NULL;
737     }
738     PubKeyExchangeCmd *instance = (PubKeyExchangeCmd *)HcMalloc(sizeof(PubKeyExchangeCmd), 0);
739     if (instance == NULL) {
740         LOGE("allocate instance memory fail.");
741         return NULL;
742     }
743     int32_t res = InitPubkeyExchangeCmd(instance, params, isCaller, strategy);
744     if (res != HC_SUCCESS) {
745         DestroyPubKeyExchangeCmd((BaseCmd *)instance);
746         return NULL;
747     }
748     return (BaseCmd *)instance;
749 }
750