• 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 "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: %" LOG_PUB "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: %" LOG_PUB "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: %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****",
418         peerKeyAliasVal[DEV_AUTH_ZERO], peerKeyAliasVal[DEV_AUTH_ONE],
419         peerKeyAliasVal[DEV_AUTH_TWO], peerKeyAliasVal[DEV_AUTH_THREE]);
420     LOGI("selfPriKey alias: %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****",
421         selfKeyAliasVal[DEV_AUTH_ZERO], selfKeyAliasVal[DEV_AUTH_ONE],
422         selfKeyAliasVal[DEV_AUTH_TWO], selfKeyAliasVal[DEV_AUTH_THREE]);
423     LOGI("psk alias: %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****",
424         sharedKeyAliasVal[DEV_AUTH_ZERO], sharedKeyAliasVal[DEV_AUTH_ONE],
425         sharedKeyAliasVal[DEV_AUTH_TWO], sharedKeyAliasVal[DEV_AUTH_THREE]);
426     return ComputeAndSavePskInner(params->osAccountId, &selfKeyAlias, &peerKeyAlias, params->isSelfFromUpgrade,
427         &sharedKeyAlias);
428 }
429 
SavePeerPubKey(const CmdParams * params)430 static int32_t SavePeerPubKey(const CmdParams *params)
431 {
432     uint8_t keyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
433     Uint8Buff keyAlias = { keyAliasVal, PAKE_KEY_ALIAS_LEN };
434     int32_t res = GenerateKeyAlias(params, false, false, &keyAlias);
435     if (res != HC_SUCCESS) {
436         LOGE("generateKeyAlias failed");
437         return res;
438     }
439     LOGI("PubKey alias: %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x %" LOG_PUB "x****.", keyAliasVal[DEV_AUTH_ZERO],
440         keyAliasVal[DEV_AUTH_ONE], keyAliasVal[DEV_AUTH_TWO], keyAliasVal[DEV_AUTH_THREE]);
441     ExtraInfo exInfo = { params->authIdPeer, params->userTypeSelf, PAIR_TYPE_BIND };
442     KeyParams keyParams = { { keyAlias.val, keyAlias.length, true }, false, params->osAccountId };
443     res = GetLoaderInstance()->importPublicKey(&keyParams, &params->pkPeer, ED25519, &exInfo);
444     if (res != HC_SUCCESS) {
445         LOGE("import peer pubKey failed");
446         return res;
447     }
448     LOGI("Save pubKey success.");
449     return HC_SUCCESS;
450 }
451 
ServerSendPkInfoProcEvent(CmdParams * params)452 static int32_t ServerSendPkInfoProcEvent(CmdParams *params)
453 {
454     int32_t res = ExportSelfPubKey(params);
455     if (res != HC_SUCCESS) {
456         return res;
457     }
458     res = SavePeerPubKey(params);
459     if (res != HC_SUCCESS) {
460         return res;
461     }
462     return ComputeAndSavePsk(params);
463 }
464 
ServerSendAuthCodeBuildEvent(const CmdParams * params,CJson ** outputEvent)465 static int32_t ServerSendAuthCodeBuildEvent(const CmdParams *params, CJson **outputEvent)
466 {
467     CJson *json = CreateJson();
468     if (json == NULL) {
469         LOGE("create json failed.");
470         return HC_ERR_JSON_CREATE;
471     }
472     if (AddIntToJson(json, FIELD_EVENT, SERVER_SEND_PK_INFO_EVENT) != HC_SUCCESS) {
473         LOGE("add eventName to json fail.");
474         FreeJson(json);
475         return HC_ERR_JSON_ADD;
476     }
477     if (AddByteToJson(json, FIELD_AUTH_ID_SERVER, params->authIdSelf.val,
478         params->authIdSelf.length) != HC_SUCCESS) {
479         LOGE("add authIdS to json fail.");
480         FreeJson(json);
481         return HC_ERR_JSON_ADD;
482     }
483     if (AddIntToJson(json, FIELD_USER_TYPE_SERVER, params->userTypeSelf) != HC_SUCCESS) {
484         LOGE("add userTypeC to json fail.");
485         FreeJson(json);
486         return HC_ERR_JSON_ADD;
487     }
488     if (AddByteToJson(json, FIELD_AUTH_PK_SERVER, params->pkSelf.val, params->pkSelf.length) != HC_SUCCESS) {
489         LOGE("add authPkS to json fail.");
490         FreeJson(json);
491         return HC_ERR_JSON_ADD;
492     }
493     *outputEvent = json;
494     return HC_SUCCESS;
495 }
496 
ClientImportPkParseEvent(const CJson * inputEvent,CmdParams * params)497 static int32_t ClientImportPkParseEvent(const CJson *inputEvent, CmdParams *params)
498 {
499     int32_t res = GetAuthIdPeerFromInput(inputEvent, params, true);
500     if (res != HC_SUCCESS) {
501         return res;
502     }
503     int32_t userTypeS;
504     if (GetIntFromJson(inputEvent, FIELD_USER_TYPE_SERVER, &userTypeS) != HC_SUCCESS) {
505         LOGE("get userTypeS from json fail.");
506         return HC_ERR_JSON_GET;
507     }
508     if (InitUint8Buff(&params->pkPeer, PAKE_ED25519_KEY_PAIR_LEN) != HC_SUCCESS) {
509         LOGE("allocate pkPeer memory fail.");
510         return HC_ERR_ALLOC_MEMORY;
511     }
512     if (GetByteFromJson(inputEvent, FIELD_AUTH_PK_SERVER, params->pkPeer.val,
513         params->pkPeer.length) != HC_SUCCESS) {
514         LOGE("get authPkS from json fail.");
515         return HC_ERR_JSON_GET;
516     }
517     params->userTypePeer = userTypeS;
518     return HC_SUCCESS;
519 }
520 
ClientImportPkProcEvent(const CmdParams * params)521 static int32_t ClientImportPkProcEvent(const CmdParams *params)
522 {
523     int32_t res = SavePeerPubKey(params);
524     if (res != HC_SUCCESS) {
525         return res;
526     }
527     return ComputeAndSavePsk(params);
528 }
529 
ReturnError(int32_t errorCode,CJson ** outputEvent)530 static void ReturnError(int32_t errorCode, CJson **outputEvent)
531 {
532     (void)errorCode;
533     (void)outputEvent;
534     return;
535 }
536 
NotifyPeerError(int32_t errorCode,CJson ** outputEvent)537 static void NotifyPeerError(int32_t errorCode, CJson **outputEvent)
538 {
539     CJson *json = CreateJson();
540     if (json == NULL) {
541         LOGE("create json failed.");
542         return;
543     }
544     if (AddIntToJson(json, FIELD_EVENT, FAIL_EVENT) != HC_SUCCESS) {
545         LOGE("add eventName to json fail.");
546         FreeJson(json);
547         return;
548     }
549     if (AddIntToJson(json, FIELD_ERR_CODE, errorCode) != HC_SUCCESS) {
550         LOGE("add errorCode to json fail.");
551         FreeJson(json);
552         return;
553     }
554     *outputEvent = json;
555     return;
556 }
557 
ThrowException(BaseCmd * self,const CJson * baseEvent,CJson ** outputEvent)558 static int32_t ThrowException(BaseCmd *self, const CJson *baseEvent, CJson **outputEvent)
559 {
560     (void)self;
561     (void)outputEvent;
562     int32_t peerErrorCode = HC_ERR_PEER_ERROR;
563     (void)GetIntFromJson(baseEvent, FIELD_ERR_CODE, &peerErrorCode);
564     LOGE("An exception occurred in the peer cmd. [Code]: %" LOG_PUB "d", peerErrorCode);
565     return peerErrorCode;
566 }
567 
ClientSendPkInfo(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)568 static int32_t ClientSendPkInfo(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
569 {
570     (void)inputEvent;
571     PubKeyExchangeCmd *impl = (PubKeyExchangeCmd *)self;
572     int32_t res = ClientSendPkInfoProcEvent(&impl->params);
573     if (res != HC_SUCCESS) {
574         return res;
575     }
576     return ClientSendPkInfoBuildEvent(&impl->params, outputEvent);
577 }
578 
ServerSendPkInfo(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)579 static int32_t ServerSendPkInfo(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
580 {
581     PubKeyExchangeCmd *impl = (PubKeyExchangeCmd *)self;
582     int32_t res = ServerSendPkInfoParseEvent(inputEvent, &impl->params);
583     if (res != HC_SUCCESS) {
584         return res;
585     }
586     res = ServerSendPkInfoProcEvent(&impl->params);
587     if (res != HC_SUCCESS) {
588         return res;
589     }
590     return ServerSendAuthCodeBuildEvent(&impl->params, outputEvent);
591 }
592 
ClientImportPk(BaseCmd * self,const CJson * inputEvent,CJson ** outputEvent)593 static int32_t ClientImportPk(BaseCmd *self, const CJson *inputEvent, CJson **outputEvent)
594 {
595     (void)outputEvent;
596     PubKeyExchangeCmd *impl = (PubKeyExchangeCmd *)self;
597     int32_t res = ClientImportPkParseEvent(inputEvent, &impl->params);
598     if (res != HC_SUCCESS) {
599         return res;
600     }
601     return ClientImportPkProcEvent(&impl->params);
602 }
603 
604 static const CmdStateNode STATE_MACHINE[] = {
605     { CREATE_AS_CLIENT_STATE, START_EVENT, ClientSendPkInfo, NotifyPeerError, CLIENT_START_REQ_STATE },
606     { CREATE_AS_SERVER_STATE, CLIENT_SEND_PK_INFO_EVENT, ServerSendPkInfo, NotifyPeerError, SERVER_FINISH_STATE },
607     { CREATE_AS_SERVER_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
608     { CLIENT_START_REQ_STATE, SERVER_SEND_PK_INFO_EVENT, ClientImportPk, ReturnError, CLIENT_FINISH_STATE },
609     { CLIENT_START_REQ_STATE, FAIL_EVENT, ThrowException, ReturnError, FAIL_STATE },
610 };
611 
DecodeEvent(const CJson * receviedMsg)612 static int32_t DecodeEvent(const CJson *receviedMsg)
613 {
614     if (receviedMsg == NULL) {
615         return START_EVENT;
616     }
617     int32_t event;
618     if (GetIntFromJson(receviedMsg, FIELD_EVENT, &event) != HC_SUCCESS) {
619         LOGE("get event from receviedMsg fail.");
620         return UNKNOWN_EVENT;
621     }
622     if (START_EVENT <= event && event <= UNKNOWN_EVENT) {
623         return event;
624     }
625     LOGE("unknown event.");
626     return UNKNOWN_EVENT;
627 }
628 
SwitchState(BaseCmd * self,const CJson * receviedMsg,CJson ** returnSendMsg,CmdState * returnState)629 static int32_t SwitchState(BaseCmd *self, const CJson *receviedMsg, CJson **returnSendMsg, CmdState *returnState)
630 {
631     int32_t eventType = DecodeEvent(receviedMsg);
632     for (uint32_t i = 0; i < sizeof(STATE_MACHINE) / sizeof(STATE_MACHINE[0]); i++) {
633         if ((STATE_MACHINE[i].curState == self->curState) && (STATE_MACHINE[i].eventType == eventType)) {
634             int32_t res = STATE_MACHINE[i].stateProcessFunc(self, receviedMsg, returnSendMsg);
635             if (res != HC_SUCCESS) {
636                 STATE_MACHINE[i].exceptionHandleFunc(res, returnSendMsg);
637                 self->curState = self->failState;
638                 return res;
639             }
640             LOGI("event: %" LOG_PUB "d, curState: %" LOG_PUB "d, nextState: %" LOG_PUB "d", eventType, self->curState,
641                 STATE_MACHINE[i].nextState);
642             self->curState = STATE_MACHINE[i].nextState;
643             *returnState = (self->curState == self->finishState) ? CMD_STATE_FINISH : CMD_STATE_CONTINUE;
644             return HC_SUCCESS;
645         }
646     }
647     LOGI("Unsupported event type. Ignore process. [Event]: %" LOG_PUB "d, [CurState]: %" LOG_PUB "d",
648         eventType, self->curState);
649     return HC_SUCCESS;
650 }
651 
StartPubKeyExchangeCmd(BaseCmd * self,CJson ** returnSendMsg)652 static int32_t StartPubKeyExchangeCmd(BaseCmd *self, CJson **returnSendMsg)
653 {
654     if ((self == NULL) || (returnSendMsg == NULL)) {
655         LOGE("invalid params.");
656         return HC_ERR_INVALID_PARAMS;
657     }
658     if (self->curState != self->beginState) {
659         LOGE("The protocol has ended, and the state switch cannot continue!");
660         return HC_ERR_UNSUPPORTED_OPCODE;
661     }
662     CmdState state;
663     return SwitchState(self, NULL, returnSendMsg, &state);
664 }
665 
ProcessPubKeyExchangeCmd(BaseCmd * self,const CJson * receviedMsg,CJson ** returnSendMsg,CmdState * returnState)666 static int32_t ProcessPubKeyExchangeCmd(BaseCmd *self, const CJson *receviedMsg,
667     CJson **returnSendMsg, CmdState *returnState)
668 {
669     if ((self == NULL) || (receviedMsg == NULL) || (returnSendMsg == NULL) || (returnState == NULL)) {
670         LOGE("invalid params.");
671         return HC_ERR_INVALID_PARAMS;
672     }
673     if ((self->curState == self->finishState) || (self->curState == self->failState)) {
674         LOGE("The protocol has ended, and the state switch cannot continue!");
675         return HC_ERR_UNSUPPORTED_OPCODE;
676     }
677     return SwitchState(self, receviedMsg, returnSendMsg, returnState);
678 }
679 
DestroyPubKeyExchangeCmd(BaseCmd * self)680 static void DestroyPubKeyExchangeCmd(BaseCmd *self)
681 {
682     if (self == NULL) {
683         LOGD("self is null.");
684         return;
685     }
686     PubKeyExchangeCmd *impl = (PubKeyExchangeCmd *)self;
687     ClearFreeUint8Buff(&impl->params.pkSelf);
688     ClearFreeUint8Buff(&impl->params.pkPeer);
689     ClearFreeUint8Buff(&impl->params.authIdSelf);
690     ClearFreeUint8Buff(&impl->params.authIdPeer);
691     HcFree(impl->params.groupId);
692     HcFree(impl->params.appId);
693     HcFree(impl);
694 }
695 
IsPubKeyExchangeParamsValid(const PubKeyExchangeParams * params)696 static bool IsPubKeyExchangeParamsValid(const PubKeyExchangeParams *params)
697 {
698     if ((params == NULL) || (params->appId == NULL) || (params->authId.val == NULL) ||
699         (params->authId.length == 0) || (params->groupId == NULL)) {
700         return false;
701     }
702     return true;
703 }
704 
InitPubkeyExchangeCmd(PubKeyExchangeCmd * instance,const PubKeyExchangeParams * params,bool isCaller,int32_t strategy)705 static int32_t InitPubkeyExchangeCmd(PubKeyExchangeCmd *instance, const PubKeyExchangeParams *params,
706     bool isCaller, int32_t strategy)
707 {
708     if (DeepCopyUint8Buff(&params->authId, &(instance->params.authIdSelf)) != HC_SUCCESS) {
709         LOGE("copy authIdSelf fail.");
710         return HC_ERR_ALLOC_MEMORY;
711     }
712     if (DeepCopyString(params->appId, &(instance->params.appId)) != HC_SUCCESS) {
713         LOGE("copy appId fail.");
714         return HC_ERR_ALLOC_MEMORY;
715     }
716     if (DeepCopyString(params->groupId, &(instance->params.groupId)) != HC_SUCCESS) {
717         LOGE("copy groupId fail.");
718         return HC_ERR_ALLOC_MEMORY;
719     }
720     instance->params.osAccountId = params->osAccountId;
721     instance->params.userTypeSelf = params->userType;
722     instance->params.isSelfFromUpgrade = params->isSelfFromUpgrade;
723     instance->base.type = PUB_KEY_EXCHANGE_CMD_TYPE;
724     instance->base.strategy = strategy;
725     instance->base.isCaller = isCaller;
726     instance->base.beginState = isCaller ? CREATE_AS_CLIENT_STATE : CREATE_AS_SERVER_STATE;
727     instance->base.finishState = isCaller ? CLIENT_FINISH_STATE : SERVER_FINISH_STATE;
728     instance->base.failState = FAIL_STATE;
729     instance->base.curState = instance->base.beginState;
730     instance->base.start = StartPubKeyExchangeCmd;
731     instance->base.process = ProcessPubKeyExchangeCmd;
732     instance->base.destroy = DestroyPubKeyExchangeCmd;
733     return HC_SUCCESS;
734 }
735 
CreatePubKeyExchangeCmd(const void * baseParams,bool isCaller,int32_t strategy)736 BaseCmd *CreatePubKeyExchangeCmd(const void *baseParams, bool isCaller, int32_t strategy)
737 {
738     const PubKeyExchangeParams *params = (const PubKeyExchangeParams *)baseParams;
739     if (!IsPubKeyExchangeParamsValid(params)) {
740         LOGE("invalid params.");
741         return NULL;
742     }
743     PubKeyExchangeCmd *instance = (PubKeyExchangeCmd *)HcMalloc(sizeof(PubKeyExchangeCmd), 0);
744     if (instance == NULL) {
745         LOGE("allocate instance memory fail.");
746         return NULL;
747     }
748     int32_t res = InitPubkeyExchangeCmd(instance, params, isCaller, strategy);
749     if (res != HC_SUCCESS) {
750         DestroyPubKeyExchangeCmd((BaseCmd *)instance);
751         return NULL;
752     }
753     return (BaseCmd *)instance;
754 }
755