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