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 "cert_operation.h"
17
18 #include "account_task_manager.h"
19 #include "account_related_group_auth.h"
20 #include "alg_loader.h"
21 #include "asy_token_manager.h"
22 #include "group_data_manager.h"
23 #include "group_auth_data_operation.h"
24 #include "group_operation_common.h"
25 #include "hc_log.h"
26 #include "hc_types.h"
27 #include "identity_common.h"
28 #include "pseudonym_manager.h"
29 #include "sym_token_manager.h"
30
31 #define FIELD_SHARED_SECRET "sharedSecret"
32
SetProtocolsForUidType(IdentityInfo * info)33 static int32_t SetProtocolsForUidType(IdentityInfo *info)
34 {
35 #ifdef ENABLE_ACCOUNT_AUTH_ISO
36 ProtocolEntity *entity = (ProtocolEntity *)HcMalloc(sizeof(ProtocolEntity), 0);
37 if (entity == NULL) {
38 LOGE("Failed to alloc memory for entity!");
39 return HC_ERR_ALLOC_MEMORY;
40 }
41 entity->protocolType = ALG_ISO;
42 entity->expandProcessCmds = CMD_ADD_TRUST_DEVICE;
43 if (info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&entity) == NULL) {
44 LOGE("Failed to push entity to vec");
45 HcFree(entity);
46 return HC_ERR_ALLOC_MEMORY;
47 }
48 #else
49 (void)info;
50 #endif
51
52 return HC_SUCCESS;
53 }
54
GetIdentityInfoByType(int32_t keyType,int32_t trustType,const char * groupId,IdentityInfo * info)55 static int32_t GetIdentityInfoByType(int32_t keyType, int32_t trustType, const char *groupId, IdentityInfo *info)
56 {
57 CJson *urlJson = CreateJson();
58 if (urlJson == NULL) {
59 LOGE("Failed to create url json!");
60 return HC_ERR_JSON_CREATE;
61 }
62 if (AddIntToJson(urlJson, PRESHARED_URL_CREDENTIAL_TYPE, PRE_SHARED) != HC_SUCCESS) {
63 LOGE("Failed to add credential type!");
64 FreeJson(urlJson);
65 return HC_ERR_JSON_ADD;
66 }
67 if (AddIntToJson(urlJson, PRESHARED_URL_KEY_TYPE, keyType) != HC_SUCCESS) {
68 LOGE("Failed to add key type!");
69 FreeJson(urlJson);
70 return HC_ERR_JSON_ADD;
71 }
72 if (AddIntToJson(urlJson, PRESHARED_URL_TRUST_TYPE, trustType) != HC_SUCCESS) {
73 LOGE("Failed to add trust type!");
74 FreeJson(urlJson);
75 return HC_ERR_JSON_ADD;
76 }
77 if ((trustType == TRUST_TYPE_P2P || trustType == TRUST_TYPE_UID) &&
78 AddStringToJson(urlJson, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
79 LOGE("Failed to add group id!");
80 FreeJson(urlJson);
81 return HC_ERR_JSON_ADD;
82 }
83 char *urlStr = PackJsonToString(urlJson);
84 FreeJson(urlJson);
85 if (urlStr == NULL) {
86 LOGE("Failed to pack url json to string!");
87 return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
88 }
89
90 int32_t ret = SetPreSharedUrlForProof(urlStr, &info->proof.preSharedUrl);
91 FreeJsonString(urlStr);
92 if (ret != HC_SUCCESS) {
93 LOGE("Failed to set preSharedUrl of proof!");
94 return ret;
95 }
96
97 ret = SetProtocolsForUidType(info);
98 if (ret != HC_SUCCESS) {
99 LOGE("Failed to set protocols!");
100 return ret;
101 }
102
103 info->proofType = PRE_SHARED;
104 return ret;
105 }
106
AddCertInfoToJson(const CertInfo * certInfo,CJson * out)107 int32_t AddCertInfoToJson(const CertInfo *certInfo, CJson *out)
108 {
109 if (certInfo == NULL || out == NULL) {
110 LOGE("Invalid cert info or out!");
111 return HC_ERR_INVALID_PARAMS;
112 }
113 if (AddIntToJson(out, FIELD_SIGN_ALG, certInfo->signAlg) != HC_SUCCESS) {
114 LOGE("add sign alg to json failed!");
115 return HC_ERR_JSON_ADD;
116 }
117 if (AddStringToJson(out, FIELD_PK_INFO, (const char *)certInfo->pkInfoStr.val) != HC_SUCCESS) {
118 LOGE("add pk info str to json failed!");
119 return HC_ERR_JSON_ADD;
120 }
121 if (AddByteToJson(out, FIELD_PK_INFO_SIGNATURE, certInfo->pkInfoSignature.val,
122 certInfo->pkInfoSignature.length) != HC_SUCCESS) {
123 LOGE("add pk info sign to json failed!");
124 return HC_ERR_JSON_ADD;
125 }
126 return HC_SUCCESS;
127 }
128
GetSelfUserId(int32_t osAccountId,char * userId,uint32_t userIdLen)129 static int32_t GetSelfUserId(int32_t osAccountId, char *userId, uint32_t userIdLen)
130 {
131 GroupEntryVec accountVec = CreateGroupEntryVec();
132 QueryGroupParams queryParams = InitQueryGroupParams();
133 queryParams.groupType = IDENTICAL_ACCOUNT_GROUP;
134 do {
135 if (QueryGroups(osAccountId, &queryParams, &accountVec) != HC_SUCCESS) {
136 LOGD("No identical-account group in db, no identical-account auth!");
137 break;
138 }
139 uint32_t index = 0;
140 TrustedGroupEntry **ptr = NULL;
141 while (index < accountVec.size(&accountVec)) {
142 ptr = accountVec.getp(&accountVec, index);
143 if ((ptr == NULL) || (*ptr == NULL)) {
144 index++;
145 continue;
146 }
147 if (memcpy_s(userId, userIdLen, StringGet(&(*ptr)->userId), StringLength(&(*ptr)->userId)) != EOK) {
148 LOGE("copy fail");
149 ClearGroupEntryVec(&accountVec);
150 return HC_ERROR;
151 }
152 index++;
153 }
154 } while (0);
155 ClearGroupEntryVec(&accountVec);
156 return HC_SUCCESS;
157 }
158
GetLocalIdenticalGroup(int32_t osAccountId,CJson * param,QueryGroupParams * queryParams,GroupEntryVec * groupEntryVec)159 static void GetLocalIdenticalGroup(int32_t osAccountId, CJson *param, QueryGroupParams *queryParams,
160 GroupEntryVec *groupEntryVec)
161 {
162 char selfUserId[USER_ID_LEN] = { 0 };
163 int32_t ret = GetSelfUserId(osAccountId, selfUserId, USER_ID_LEN);
164 if (ret != HC_SUCCESS) {
165 LOGE("Get user id fail");
166 return;
167 }
168
169 ret = AddStringToJson(param, FIELD_USER_ID, selfUserId);
170 if (ret != HC_SUCCESS) {
171 LOGE("add self userId to params fail");
172 return;
173 }
174
175 BaseGroupAuth *groupAuth = GetAccountRelatedGroupAuth();
176 if (groupAuth == NULL) {
177 LOGE("Failed to get account group auth!");
178 return;
179 }
180
181 ((AccountRelatedGroupAuth *)groupAuth)
182 ->getAccountCandidateGroup(osAccountId, param, queryParams, groupEntryVec);
183 if (groupEntryVec->size(groupEntryVec) == 0) {
184 LOGE("group not found by self user id!");
185 }
186 }
187
GetSelfGroupEntryByPeerCert(int32_t osAccountId,const CertInfo * certInfo)188 static TrustedGroupEntry *GetSelfGroupEntryByPeerCert(int32_t osAccountId, const CertInfo *certInfo)
189 {
190 CJson *peerPkInfoJson = CreateJsonFromString((const char *)certInfo->pkInfoStr.val);
191 if (peerPkInfoJson == NULL) {
192 LOGE("Failed to create peer pkInfoJson!");
193 return NULL;
194 }
195 const char *peerUserId = GetStringFromJson(peerPkInfoJson, FIELD_USER_ID);
196 if (peerUserId == NULL) {
197 LOGE("Failed to get peer userId!");
198 FreeJson(peerPkInfoJson);
199 return NULL;
200 }
201 CJson *param = CreateJson();
202 if (param == NULL) {
203 LOGE("Failed to create query param!");
204 FreeJson(peerPkInfoJson);
205 return NULL;
206 }
207 if (AddStringToJson(param, FIELD_USER_ID, peerUserId) != HC_SUCCESS) {
208 LOGE("Failed to add peer userId to param!");
209 FreeJson(param);
210 FreeJson(peerPkInfoJson);
211 return NULL;
212 }
213 FreeJson(peerPkInfoJson);
214 BaseGroupAuth *groupAuth = GetAccountRelatedGroupAuth();
215 if (groupAuth == NULL) {
216 LOGE("Failed to get account group auth!");
217 FreeJson(param);
218 return NULL;
219 }
220 GroupEntryVec groupEntryVec = CreateGroupEntryVec();
221 QueryGroupParams queryParams = InitQueryGroupParams();
222 ((AccountRelatedGroupAuth *)groupAuth)
223 ->getAccountCandidateGroup(osAccountId, param, &queryParams, &groupEntryVec);
224 if (groupEntryVec.size(&groupEntryVec) == 0) {
225 LOGE("group not found by peer user id!");
226 (void)GetLocalIdenticalGroup(osAccountId, param, &queryParams, &groupEntryVec);
227 if (groupEntryVec.size(&groupEntryVec) == 0) {
228 LOGE("can not find group");
229 ClearGroupEntryVec(&groupEntryVec);
230 FreeJson(param);
231 return NULL;
232 }
233 }
234 FreeJson(param);
235 TrustedGroupEntry *returnEntry = DeepCopyGroupEntry(groupEntryVec.get(&groupEntryVec, 0));
236 ClearGroupEntryVec(&groupEntryVec);
237 return returnEntry;
238 }
239
GetSelfDeviceEntryByPeerCert(int32_t osAccountId,const CertInfo * certInfo,TrustedDeviceEntry * deviceEntry)240 static int32_t GetSelfDeviceEntryByPeerCert(
241 int32_t osAccountId, const CertInfo *certInfo, TrustedDeviceEntry *deviceEntry)
242 {
243 TrustedGroupEntry *groupEntry = GetSelfGroupEntryByPeerCert(osAccountId, certInfo);
244 if (groupEntry == NULL) {
245 LOGE("Failed to get self group entry!");
246 return HC_ERR_GROUP_NOT_EXIST;
247 }
248 const char *groupId = StringGet(&groupEntry->id);
249 int32_t ret = GetSelfDeviceEntry(osAccountId, groupId, deviceEntry);
250 DestroyGroupEntry(groupEntry);
251 return ret;
252 }
253
VerifyPeerCertInfo(int32_t osAccountId,const char * selfUserId,const char * selfAuthId,const CertInfo * certInfo)254 static int32_t VerifyPeerCertInfo(int32_t osAccountId, const char *selfUserId, const char *selfAuthId,
255 const CertInfo *certInfo)
256 {
257 uint8_t *keyAliasValue = (uint8_t *)HcMalloc(SHA256_LEN, 0);
258 if (keyAliasValue == NULL) {
259 LOGE("Failed to alloc memory for key alias value!");
260 return HC_ERR_ALLOC_MEMORY;
261 }
262 Uint8Buff keyAlias = { .val = keyAliasValue, .length = SHA256_LEN };
263 int32_t ret = GetAccountAuthTokenManager()->generateKeyAlias(selfUserId, selfAuthId, &keyAlias, true);
264 if (ret != HC_SUCCESS) {
265 LOGE("Failed to generate server pk alias!");
266 HcFree(keyAliasValue);
267 return ret;
268 }
269 KeyParams keyParams = { { keyAlias.val, keyAlias.length, true }, false, osAccountId };
270 ret = GetLoaderInstance()->verify(
271 &keyParams, &certInfo->pkInfoStr, certInfo->signAlg, &certInfo->pkInfoSignature);
272 HcFree(keyAliasValue);
273 if (ret != HC_SUCCESS) {
274 return HC_ERR_VERIFY_FAILED;
275 }
276 return HC_SUCCESS;
277 }
278
GetPeerPubKeyFromCert(const CertInfo * peerCertInfo,Uint8Buff * peerPkBuff)279 static int32_t GetPeerPubKeyFromCert(const CertInfo *peerCertInfo, Uint8Buff *peerPkBuff)
280 {
281 CJson *pkInfoPeer = CreateJsonFromString((const char *)peerCertInfo->pkInfoStr.val);
282 if (pkInfoPeer == NULL) {
283 LOGE("Failed to create peer pkInfo json!");
284 return HC_ERR_JSON_CREATE;
285 }
286 const char *devicePk = GetStringFromJson(pkInfoPeer, FIELD_DEVICE_PK);
287 if (devicePk == NULL) {
288 LOGE("Failed to get peer devicePk!");
289 FreeJson(pkInfoPeer);
290 return HC_ERR_JSON_GET;
291 }
292 uint32_t pkSize = HcStrlen(devicePk) / BYTE_TO_HEX_OPER_LENGTH;
293 peerPkBuff->val = (uint8_t *)HcMalloc(pkSize, 0);
294 if (peerPkBuff->val == NULL) {
295 LOGE("Failed to alloc memory for peerPk!");
296 FreeJson(pkInfoPeer);
297 return HC_ERR_ALLOC_MEMORY;
298 }
299 if (GetByteFromJson(pkInfoPeer, FIELD_DEVICE_PK, peerPkBuff->val, pkSize) != HC_SUCCESS) {
300 LOGE("Failed to get peer public key!");
301 HcFree(peerPkBuff->val);
302 FreeJson(pkInfoPeer);
303 return HC_ERR_JSON_GET;
304 }
305 FreeJson(pkInfoPeer);
306 peerPkBuff->length = pkSize;
307 return HC_SUCCESS;
308 }
309
GetSharedSecretForAccountInPake(int32_t osAccountId,const char * userId,const char * authId,const CertInfo * peerCertInfo,Uint8Buff * sharedSecret)310 static int32_t GetSharedSecretForAccountInPake(int32_t osAccountId, const char *userId, const char *authId,
311 const CertInfo *peerCertInfo, Uint8Buff *sharedSecret)
312 {
313 uint8_t *priAliasVal = (uint8_t *)HcMalloc(SHA256_LEN, 0);
314 if (priAliasVal == NULL) {
315 LOGE("Failed to alloc memory for self key alias!");
316 return HC_ERR_ALLOC_MEMORY;
317 }
318 Uint8Buff aliasBuff = { priAliasVal, SHA256_LEN };
319 int32_t ret = GetAccountAuthTokenManager()->generateKeyAlias(userId, authId, &aliasBuff, false);
320 if (ret != HC_SUCCESS) {
321 HcFree(priAliasVal);
322 return ret;
323 }
324 Uint8Buff peerPkBuff = { 0 };
325 ret = GetPeerPubKeyFromCert(peerCertInfo, &peerPkBuff);
326 if (ret != HC_SUCCESS) {
327 HcFree(priAliasVal);
328 return ret;
329 }
330
331 uint32_t sharedKeyAliasLen = HcStrlen(SHARED_KEY_ALIAS) + 1;
332 sharedSecret->val = (uint8_t *)HcMalloc(sharedKeyAliasLen, 0);
333 if (sharedSecret->val == NULL) {
334 LOGE("Failed to malloc for psk alias.");
335 HcFree(priAliasVal);
336 ClearFreeUint8Buff(&peerPkBuff);
337 return HC_ERR_ALLOC_MEMORY;
338 }
339 sharedSecret->length = sharedKeyAliasLen;
340 (void)memcpy_s(sharedSecret->val, sharedKeyAliasLen, SHARED_KEY_ALIAS, sharedKeyAliasLen);
341 KeyParams privKeyParams = { { aliasBuff.val, aliasBuff.length, true }, false, osAccountId };
342 KeyBuff pubKeyBuff = { peerPkBuff.val, peerPkBuff.length, false };
343 ret = GetLoaderInstance()->agreeSharedSecretWithStorage(
344 &privKeyParams, &pubKeyBuff, P256, P256_SHARED_SECRET_KEY_SIZE, sharedSecret);
345 HcFree(priAliasVal);
346 ClearFreeUint8Buff(&peerPkBuff);
347 if (ret != HC_SUCCESS) {
348 LOGE("Failed to agree shared secret!");
349 FreeBuffData(sharedSecret);
350 }
351 return ret;
352 }
353
GenerateCertInfo(const Uint8Buff * pkInfoStr,const Uint8Buff * pkInfoSignature,CertInfo * certInfo)354 int32_t GenerateCertInfo(const Uint8Buff *pkInfoStr, const Uint8Buff *pkInfoSignature, CertInfo *certInfo)
355 {
356 if (!(IsUint8BuffValid(pkInfoStr, pkInfoStr->length) &&
357 IsUint8BuffValid(pkInfoSignature, pkInfoSignature->length) &&
358 certInfo != NULL)) {
359 LOGE("input invailed!");
360 return HC_ERR_INVALID_PARAMS;
361 }
362 uint32_t pkInfoLen = pkInfoStr->length;
363 certInfo->pkInfoStr.val = (uint8_t *)HcMalloc(pkInfoLen, 0);
364 if (certInfo->pkInfoStr.val == NULL) {
365 LOGE("Failed to alloc pkInfo memory!");
366 return HC_ERR_ALLOC_MEMORY;
367 }
368 if (memcpy_s(certInfo->pkInfoStr.val, pkInfoLen, pkInfoStr->val, pkInfoLen) != EOK) {
369 LOGE("Failed to copy pkInfo!");
370 FreeBuffData(&certInfo->pkInfoStr);
371 return HC_ERR_MEMORY_COPY;
372 }
373 certInfo->pkInfoStr.length = pkInfoLen;
374
375 uint32_t signatureLen = pkInfoSignature->length;
376 certInfo->pkInfoSignature.val = (uint8_t *)HcMalloc(signatureLen, 0);
377 if (certInfo->pkInfoSignature.val == NULL) {
378 LOGE("Failed to alloc pkInfoSignature memory!");
379 FreeBuffData(&certInfo->pkInfoStr);
380 return HC_ERR_ALLOC_MEMORY;
381 }
382 if (memcpy_s(certInfo->pkInfoSignature.val, signatureLen, pkInfoSignature->val, signatureLen) != EOK) {
383 LOGE("Failed to copy pkInfoSignature!");
384 FreeBuffData(&certInfo->pkInfoStr);
385 FreeBuffData(&certInfo->pkInfoSignature);
386 return HC_ERR_MEMORY_COPY;
387 }
388 certInfo->pkInfoSignature.length = signatureLen;
389 return HC_SUCCESS;
390 }
391
GetCertInfo(int32_t osAccountId,const char * userId,const char * authId,CertInfo * certInfo)392 static int32_t GetCertInfo(int32_t osAccountId, const char *userId, const char *authId, CertInfo *certInfo)
393 {
394 AccountToken *token = CreateAccountToken();
395 if (token == NULL) {
396 LOGE("Failed to create account token.");
397 return HC_ERR_ALLOC_MEMORY;
398 }
399 int32_t ret = GetAccountAuthTokenManager()->getToken(osAccountId, token, userId, authId);
400 if (ret != HC_SUCCESS) {
401 LOGE("Failed to get account token!");
402 DestroyAccountToken(token);
403 return ret;
404 }
405 ret = GenerateCertInfo(&token->pkInfoStr, &token->pkInfoSignature, certInfo);
406 DestroyAccountToken(token);
407 if (ret != HC_SUCCESS) {
408 LOGE("Failed to generate cert info!");
409 return ret;
410 }
411 certInfo->signAlg = P256;
412 return HC_SUCCESS;
413 }
414
GetAccountAsymIdentityInfo(int32_t osAccountId,const char * userId,const char * authId,IdentityInfo * info,bool isNeedGeneratePdid)415 static int32_t GetAccountAsymIdentityInfo(
416 int32_t osAccountId, const char *userId, const char *authId, IdentityInfo *info, bool isNeedGeneratePdid)
417 {
418 int32_t ret = GetCertInfo(osAccountId, userId, authId, &info->proof.certInfo);
419 if (ret != HC_SUCCESS) {
420 LOGE("Failed to generate certInfo!");
421 return ret;
422 }
423
424 #ifdef ENABLE_ACCOUNT_AUTH_EC_SPEKE
425 ProtocolEntity *ecSpekeEntity = (ProtocolEntity *)HcMalloc(sizeof(ProtocolEntity), 0);
426 if (ecSpekeEntity == NULL) {
427 LOGE("Failed to alloc memory for ec speke entity!");
428 return HC_ERR_ALLOC_MEMORY;
429 }
430 ecSpekeEntity->protocolType = ALG_EC_SPEKE;
431 ecSpekeEntity->expandProcessCmds = CMD_ADD_TRUST_DEVICE;
432 #ifdef ENABLE_PSEUDONYM
433 if (isNeedGeneratePdid) {
434 ecSpekeEntity->expandProcessCmds |= CMD_MK_AGREE;
435 }
436 #else
437 (void)isNeedGeneratePdid;
438 #endif
439 if (info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&ecSpekeEntity) == NULL) {
440 LOGE("Failed to push ecSpeke entity!");
441 HcFree(ecSpekeEntity);
442 return HC_ERR_ALLOC_MEMORY;
443 }
444 #else
445 (void)isNeedGeneratePdid;
446 #endif
447
448 info->proofType = CERTIFICATED;
449 return HC_SUCCESS;
450 }
451
GetLocalDeviceType(int32_t osAccountId,const CJson * in,const char * groupId,int32_t * localDevType)452 static int32_t GetLocalDeviceType(int32_t osAccountId, const CJson *in, const char *groupId, int32_t *localDevType)
453 {
454 TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
455 if (deviceEntry == NULL) {
456 LOGE("Failed to alloc memory for deviceEntry!");
457 return HC_ERR_ALLOC_MEMORY;
458 }
459 int32_t ret = GetPeerDeviceEntry(osAccountId, in, groupId, deviceEntry);
460 if (ret != HC_SUCCESS) {
461 LOGI("Peer device not found, set local device type to accessory!");
462 *localDevType = DEVICE_TYPE_ACCESSORY;
463 DestroyDeviceEntry(deviceEntry);
464 return HC_SUCCESS;
465 }
466 if (deviceEntry->source == SELF_CREATED) {
467 LOGI("Peer device is self created, set local device type to accessory!");
468 *localDevType = DEVICE_TYPE_ACCESSORY;
469 }
470 DestroyDeviceEntry(deviceEntry);
471 return HC_SUCCESS;
472 }
473
GenerateAuthTokenForAccessory(int32_t osAccountId,const char * groupId,Uint8Buff * authToken)474 static int32_t GenerateAuthTokenForAccessory(int32_t osAccountId, const char *groupId, Uint8Buff *authToken)
475 {
476 TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
477 if (deviceEntry == NULL) {
478 LOGE("Failed to create device entry!");
479 return HC_ERR_ALLOC_MEMORY;
480 }
481 int32_t ret = GetSelfDeviceEntry(osAccountId, groupId, deviceEntry);
482 if (ret != HC_SUCCESS) {
483 LOGE("Failed to get self device entry!");
484 DestroyDeviceEntry(deviceEntry);
485 return ret;
486 }
487 const char *userIdSelf = StringGet(&deviceEntry->userId);
488 const char *devIdSelf = StringGet(&deviceEntry->authId);
489 uint8_t keyAliasVal[SHA256_LEN] = { 0 };
490 Uint8Buff keyAlias = { keyAliasVal, SHA256_LEN };
491 ret = GetSymTokenManager()->generateKeyAlias(userIdSelf, devIdSelf, &keyAlias);
492 if (ret != HC_SUCCESS) {
493 LOGE("Failed to generate key alias for authCode!");
494 DestroyDeviceEntry(deviceEntry);
495 return ret;
496 }
497
498 authToken->val = (uint8_t *)HcMalloc(AUTH_TOKEN_SIZE, 0);
499 if (authToken->val == NULL) {
500 LOGE("Failed to alloc memory for auth token!");
501 DestroyDeviceEntry(deviceEntry);
502 return HC_ERR_ALLOC_MEMORY;
503 }
504 authToken->length = AUTH_TOKEN_SIZE;
505 Uint8Buff userIdBuff = { (uint8_t *)userIdSelf, HcStrlen(userIdSelf) };
506 Uint8Buff challenge = { (uint8_t *)KEY_INFO_PERSISTENT_TOKEN, HcStrlen(KEY_INFO_PERSISTENT_TOKEN) };
507 KeyParams keyAliasParams = { { keyAlias.val, keyAlias.length, true }, false, osAccountId };
508 ret = GetLoaderInstance()->computeHkdf(&keyAliasParams, &userIdBuff, &challenge, authToken);
509 DestroyDeviceEntry(deviceEntry);
510 if (ret != HC_SUCCESS) {
511 LOGE("Failed to computeHkdf from authCode to authToken!");
512 FreeBuffData(authToken);
513 }
514 return ret;
515 }
516
GenerateTokenAliasForController(int32_t osAccountId,const CJson * in,const char * groupId,Uint8Buff * authTokenAlias)517 static int32_t GenerateTokenAliasForController(
518 int32_t osAccountId, const CJson *in, const char *groupId, Uint8Buff *authTokenAlias)
519 {
520 TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
521 if (deviceEntry == NULL) {
522 LOGE("Failed to create device entry!");
523 return HC_ERR_ALLOC_MEMORY;
524 }
525 int32_t ret = GetPeerDeviceEntry(osAccountId, in, groupId, deviceEntry);
526 if (ret != HC_SUCCESS) {
527 LOGE("Failed to get peer device entry!");
528 DestroyDeviceEntry(deviceEntry);
529 return ret;
530 }
531 authTokenAlias->val = (uint8_t *)HcMalloc(SHA256_LEN, 0);
532 if (authTokenAlias->val == NULL) {
533 LOGE("Failed to alloc memory for auth token alias!");
534 DestroyDeviceEntry(deviceEntry);
535 return HC_ERR_ALLOC_MEMORY;
536 }
537 authTokenAlias->length = SHA256_LEN;
538 const char *userIdPeer = StringGet(&deviceEntry->userId);
539 const char *devIdPeer = StringGet(&deviceEntry->authId);
540 ret = GetSymTokenManager()->generateKeyAlias(userIdPeer, devIdPeer, authTokenAlias);
541 DestroyDeviceEntry(deviceEntry);
542 if (ret != HC_SUCCESS) {
543 LOGE("Failed to generate key alias for authToken!");
544 FreeBuffData(authTokenAlias);
545 }
546 return ret;
547 }
548
GenerateAuthTokenByDevType(const CJson * in,const CJson * urlJson,Uint8Buff * authToken,bool * isTokenStored)549 static int32_t GenerateAuthTokenByDevType(
550 const CJson *in, const CJson *urlJson, Uint8Buff *authToken, bool *isTokenStored)
551 {
552 int32_t osAccountId = INVALID_OS_ACCOUNT;
553 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
554 LOGE("Failed to get osAccountId!");
555 return HC_ERR_JSON_GET;
556 }
557 const char *groupId = GetStringFromJson(urlJson, FIELD_GROUP_ID);
558 if (groupId == NULL) {
559 LOGE("Failed to get groupId!");
560 return HC_ERR_JSON_GET;
561 }
562 int32_t localDevType = DEVICE_TYPE_CONTROLLER;
563 int32_t ret = GetLocalDeviceType(osAccountId, in, groupId, &localDevType);
564 if (ret != HC_SUCCESS) {
565 LOGE("Failed to get local device type!");
566 return ret;
567 }
568 if (localDevType == DEVICE_TYPE_ACCESSORY) {
569 *isTokenStored = false;
570 ret = GenerateAuthTokenForAccessory(osAccountId, groupId, authToken);
571 } else {
572 ret = GenerateTokenAliasForController(osAccountId, in, groupId, authToken);
573 }
574 return ret;
575 }
576
GetSelfAccountIdentityInfo(int32_t osAccountId,const char * groupId,IdentityInfo * info,bool isNeedGeneratePdid)577 static int32_t GetSelfAccountIdentityInfo(
578 int32_t osAccountId, const char *groupId, IdentityInfo *info, bool isNeedGeneratePdid)
579 {
580 TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
581 if (deviceEntry == NULL) {
582 LOGE("Failed to create device entry!");
583 return HC_ERR_ALLOC_MEMORY;
584 }
585 int32_t ret = GetSelfDeviceEntry(osAccountId, groupId, deviceEntry);
586 if (ret != HC_SUCCESS) {
587 LOGE("Failed to get self device entry!");
588 DestroyDeviceEntry(deviceEntry);
589 return ret;
590 }
591 if (deviceEntry->credential == SYMMETRIC_CRED) {
592 ret = GetIdentityInfoByType(KEY_TYPE_SYM, TRUST_TYPE_UID, groupId, info);
593 } else {
594 const char *userId = StringGet(&deviceEntry->userId);
595 const char *authId = StringGet(&deviceEntry->authId);
596 ret = GetAccountAsymIdentityInfo(osAccountId, userId, authId, info, isNeedGeneratePdid);
597 }
598 DestroyDeviceEntry(deviceEntry);
599 return ret;
600 }
601
isNeedGeneratePdidByPeerCert(int32_t osAccountId,const CertInfo * certInfo)602 static bool isNeedGeneratePdidByPeerCert(int32_t osAccountId, const CertInfo *certInfo)
603 {
604 #ifdef ENABLE_PSEUDONYM
605 CJson *pkInfoJson = CreateJsonFromString((const char *)certInfo->pkInfoStr.val);
606 if (pkInfoJson == NULL) {
607 LOGE("Failed to create pkInfo json!");
608 return false;
609 }
610 const char *userId = GetStringFromJson(pkInfoJson, FIELD_USER_ID);
611 if (userId == NULL) {
612 LOGE("Failed to get userId!");
613 FreeJson(pkInfoJson);
614 return false;
615 }
616 bool isNeedGenerate = GetPseudonymInstance()->isNeedRefreshPseudonymId(osAccountId, userId);
617 FreeJson(pkInfoJson);
618 return isNeedGenerate;
619 #else
620 (void)osAccountId;
621 (void)certInfo;
622 return false;
623 #endif
624 }
625
GetAccountRelatedCredInfo(int32_t osAccountId,const char * groupId,const char * deviceId,bool isUdid,IdentityInfo * info)626 int32_t GetAccountRelatedCredInfo(
627 int32_t osAccountId, const char *groupId, const char *deviceId, bool isUdid, IdentityInfo *info)
628 {
629 if (groupId == NULL || deviceId == NULL || info == NULL) {
630 LOGE("Invalid input params!");
631 return HC_ERR_INVALID_PARAMS;
632 }
633 TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
634 if (deviceEntry == NULL) {
635 LOGE("Failed to create device entry!");
636 return HC_ERR_ALLOC_MEMORY;
637 }
638 int32_t ret = GaGetTrustedDeviceEntryById(osAccountId, deviceId, isUdid, groupId, deviceEntry);
639 if (ret != HC_SUCCESS) {
640 LOGI("peer device not exist, get self identity info.");
641 DestroyDeviceEntry(deviceEntry);
642 return GetSelfAccountIdentityInfo(osAccountId, groupId, info, true);
643 }
644 bool isNeedGeneratePdid = false;
645 #ifdef ENABLE_PSEUDONYM
646 const char *peerUserId = StringGet(&deviceEntry->userId);
647 isNeedGeneratePdid = GetPseudonymInstance()->isNeedRefreshPseudonymId(osAccountId, peerUserId);
648 #endif
649 if (deviceEntry->source == SELF_CREATED) {
650 LOGI("peer device is from self created, get self identity info.");
651 DestroyDeviceEntry(deviceEntry);
652 return GetSelfAccountIdentityInfo(osAccountId, groupId, info, isNeedGeneratePdid);
653 }
654 int credType = deviceEntry->credential;
655 DestroyDeviceEntry(deviceEntry);
656 if (credType == SYMMETRIC_CRED) {
657 LOGI("credential type is symmetric, get sym identity info.");
658 return GetIdentityInfoByType(KEY_TYPE_SYM, TRUST_TYPE_UID, groupId, info);
659 } else {
660 LOGI("credential type is asymmetric, get self identity info.");
661 return GetSelfAccountIdentityInfo(osAccountId, groupId, info, isNeedGeneratePdid);
662 }
663 }
664
GetSharedSecretByPeerCertFromPlugin(int32_t osAccountId,const char * credId,const CertInfo * peerCertInfo,Uint8Buff * sharedSecret)665 static int32_t GetSharedSecretByPeerCertFromPlugin(
666 int32_t osAccountId, const char *credId, const CertInfo *peerCertInfo, Uint8Buff *sharedSecret)
667 {
668 CJson *input = CreateJson();
669 if (input == NULL) {
670 LOGE("Create input params json failed!");
671 return HC_ERR_JSON_CREATE;
672 }
673 CJson *output = CreateJson();
674 if (output == NULL) {
675 LOGE("Create output results json failed!");
676 FreeJson(input);
677 return HC_ERR_JSON_CREATE;
678 }
679 int32_t res = HC_ERR_JSON_ADD;
680 if ((credId != NULL) && (AddStringToJson(input, FIELD_ACROSS_ACCOUNT_CRED_ID, credId) != HC_SUCCESS)) {
681 LOGE("across account cred eixsts, but add cred id to json failed!");
682 goto ERR;
683 }
684 GOTO_ERR_AND_SET_RET(AddCertInfoToJson(peerCertInfo, input), res);
685 GOTO_ERR_AND_SET_RET(ExecuteAccountAuthCmd(osAccountId, GET_SHARED_SECRET_BY_PEER_CERT, input, output), res);
686 res = HC_ERR_JSON_GET;
687 const char *sharedKeyAlias = GetStringFromJson(output, FIELD_SHARED_SECRET);
688 if (sharedKeyAlias == NULL) {
689 LOGE("Get alias failed!");
690 goto ERR;
691 }
692 uint32_t sharedKeyAliasLen = HcStrlen(sharedKeyAlias) + 1;
693 uint8_t *aliasVal = (uint8_t *)HcMalloc(sharedKeyAliasLen, 0);
694 GOTO_IF_CHECK_NULL(aliasVal, FIELD_SHARED_SECRET);
695 if (memcpy_s(aliasVal, sharedKeyAliasLen, sharedKeyAlias, sharedKeyAliasLen) != EOK) {
696 LOGE("parse output result set memcpy alias failed!");
697 HcFree(aliasVal);
698 aliasVal = NULL;
699 goto ERR;
700 }
701 sharedSecret->val = aliasVal;
702 sharedSecret->length = sharedKeyAliasLen;
703 res = HC_SUCCESS;
704 ERR:
705 FreeJson(input);
706 FreeJson(output);
707 return res;
708 }
709
GetAccountAsymSharedSecret(int32_t osAccountId,const char * credId,const CertInfo * peerCertInfo,Uint8Buff * sharedSecret)710 int32_t GetAccountAsymSharedSecret(int32_t osAccountId, const char *credId, const CertInfo *peerCertInfo,
711 Uint8Buff *sharedSecret)
712 {
713 if (peerCertInfo == NULL || sharedSecret == NULL) {
714 LOGE("Invalid input params!");
715 return HC_ERR_INVALID_PARAMS;
716 }
717 if (HasAccountPlugin()) {
718 return GetSharedSecretByPeerCertFromPlugin(osAccountId, credId, peerCertInfo, sharedSecret);
719 }
720 TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
721 if (deviceEntry == NULL) {
722 LOGE("Failed to create self device entry!");
723 return HC_ERR_ALLOC_MEMORY;
724 }
725 int32_t ret = GetSelfDeviceEntryByPeerCert(osAccountId, peerCertInfo, deviceEntry);
726 if (ret != HC_SUCCESS) {
727 LOGE("Failed to get self device entry!");
728 DestroyDeviceEntry(deviceEntry);
729 return ret;
730 }
731 const char *selfUserId = StringGet(&deviceEntry->userId);
732 const char *selfAuthId = StringGet(&deviceEntry->authId);
733 ret = VerifyPeerCertInfo(osAccountId, selfUserId, selfAuthId, peerCertInfo);
734 if (ret != HC_SUCCESS) {
735 LOGE("Failed to verify peer cert! [Res]: %" LOG_PUB "d", ret);
736 DestroyDeviceEntry(deviceEntry);
737 return ret;
738 }
739 ret = GetSharedSecretForAccountInPake(osAccountId, selfUserId, selfAuthId, peerCertInfo, sharedSecret);
740 DestroyDeviceEntry(deviceEntry);
741 return ret;
742 }
743
GetAccountSymSharedSecret(const CJson * in,const CJson * urlJson,Uint8Buff * sharedSecret)744 int32_t GetAccountSymSharedSecret(const CJson *in, const CJson *urlJson, Uint8Buff *sharedSecret)
745 {
746 if (in == NULL || urlJson == NULL || sharedSecret == NULL) {
747 LOGE("Invalid input params!");
748 return HC_ERR_INVALID_PARAMS;
749 }
750 int32_t osAccountId;
751 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
752 LOGE("Failed to get osAccountId!");
753 return HC_ERR_JSON_GET;
754 }
755 bool isTokenStored = true;
756 Uint8Buff authToken = { NULL, 0 };
757 int32_t ret = GenerateAuthTokenByDevType(in, urlJson, &authToken, &isTokenStored);
758 if (ret != HC_SUCCESS) {
759 LOGE("Failed to generate auth token!");
760 return ret;
761 }
762 uint8_t seed[SEED_SIZE] = { 0 };
763 Uint8Buff seedBuff = { seed, SEED_SIZE };
764 ret = GetByteFromJson(in, FIELD_SEED, seed, SEED_SIZE);
765 if (ret != HC_SUCCESS) {
766 LOGE("Failed to get seed!");
767 FreeBuffData(&authToken);
768 return HC_ERR_JSON_GET;
769 }
770 sharedSecret->val = (uint8_t *)HcMalloc(ISO_PSK_LEN, 0);
771 if (sharedSecret->val == NULL) {
772 LOGE("Failed to alloc sharedSecret memory!");
773 FreeBuffData(&authToken);
774 return HC_ERR_ALLOC_MEMORY;
775 }
776 sharedSecret->length = ISO_PSK_LEN;
777 KeyParams keyParams = { { authToken.val, authToken.length, isTokenStored }, false, osAccountId };
778 ret = GetLoaderInstance()->computeHmac(&keyParams, &seedBuff, sharedSecret);
779 FreeBuffData(&authToken);
780 if (ret != HC_SUCCESS) {
781 LOGE("ComputeHmac for psk failed, ret: %" LOG_PUB "d.", ret);
782 FreeBuffData(sharedSecret);
783 }
784 return ret;
785 }
786
GetAccountAsymCredInfo(int32_t osAccountId,const CertInfo * certInfo,IdentityInfo ** returnInfo)787 int32_t GetAccountAsymCredInfo(int32_t osAccountId, const CertInfo *certInfo, IdentityInfo **returnInfo)
788 {
789 if (certInfo == NULL || returnInfo == NULL) {
790 LOGE("Invalid input params!");
791 return HC_ERR_INVALID_PARAMS;
792 }
793 TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
794 if (deviceEntry == NULL) {
795 LOGE("Failed to create self device entry!");
796 return HC_ERR_ALLOC_MEMORY;
797 }
798 int32_t ret = GetSelfDeviceEntryByPeerCert(osAccountId, certInfo, deviceEntry);
799 if (ret != HC_SUCCESS) {
800 LOGE("Failed to get self device entry!");
801 DestroyDeviceEntry(deviceEntry);
802 return ret;
803 }
804 IdentityInfo *info = CreateIdentityInfo();
805 if (info == NULL) {
806 LOGE("Failed to create identity info!");
807 DestroyDeviceEntry(deviceEntry);
808 return HC_ERR_ALLOC_MEMORY;
809 }
810 const char *selfUserId = StringGet(&deviceEntry->userId);
811 const char *selfAuthId = StringGet(&deviceEntry->authId);
812 bool isNeedGeneratePdid = isNeedGeneratePdidByPeerCert(osAccountId, certInfo);
813 ret = GetAccountAsymIdentityInfo(osAccountId, selfUserId, selfAuthId, info, isNeedGeneratePdid);
814 DestroyDeviceEntry(deviceEntry);
815 if (ret != HC_SUCCESS) {
816 LOGE("Failed to get account asym identity info!");
817 DestroyIdentityInfo(info);
818 return ret;
819 }
820 *returnInfo = info;
821 return HC_SUCCESS;
822 }
823
GetAccountSymCredInfoByPeerUrl(const CJson * in,const CJson * urlJson,IdentityInfo * info)824 int32_t GetAccountSymCredInfoByPeerUrl(const CJson *in, const CJson *urlJson, IdentityInfo *info)
825 {
826 if (in == NULL || urlJson == NULL || info == NULL) {
827 LOGE("Invalid input params!");
828 return HC_ERR_INVALID_PARAMS;
829 }
830 int32_t osAccountId = INVALID_OS_ACCOUNT;
831 if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
832 LOGE("Failed to get osAccountId!");
833 return HC_ERR_JSON_GET;
834 }
835 const char *groupId = GetStringFromJson(urlJson, FIELD_GROUP_ID);
836 if (groupId == NULL) {
837 LOGE("Failed to get group id!");
838 return HC_ERR_JSON_GET;
839 }
840 int32_t ret = CheckGroupExist(osAccountId, groupId);
841 if (ret != HC_SUCCESS) {
842 LOGE("group not exist!");
843 return ret;
844 }
845 return GetIdentityInfoByType(KEY_TYPE_SYM, TRUST_TYPE_UID, groupId, info);
846 }