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