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(¶ms->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, ¶ms->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(¶ms->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(¶ms->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, ¶ms->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(¶ms->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(¶ms->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