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