• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "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 }