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