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     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     uint32_t pkInfoLen = pkInfoStr->length;
357     certInfo->pkInfoStr.val = (uint8_t *)HcMalloc(pkInfoLen, 0);
358     if (certInfo->pkInfoStr.val == NULL) {
359         LOGE("Failed to alloc pkInfo memory!");
360         return HC_ERR_ALLOC_MEMORY;
361     }
362     if (memcpy_s(certInfo->pkInfoStr.val, pkInfoLen, pkInfoStr->val, pkInfoLen) != EOK) {
363         LOGE("Failed to copy pkInfo!");
364         FreeBuffData(&certInfo->pkInfoStr);
365         return HC_ERR_MEMORY_COPY;
366     }
367     certInfo->pkInfoStr.length = pkInfoLen;
368 
369     uint32_t signatureLen = pkInfoSignature->length;
370     certInfo->pkInfoSignature.val = (uint8_t *)HcMalloc(signatureLen, 0);
371     if (certInfo->pkInfoSignature.val == NULL) {
372         LOGE("Failed to alloc pkInfoSignature memory!");
373         FreeBuffData(&certInfo->pkInfoStr);
374         return HC_ERR_ALLOC_MEMORY;
375     }
376     if (memcpy_s(certInfo->pkInfoSignature.val, signatureLen, pkInfoSignature->val, signatureLen) != EOK) {
377         LOGE("Failed to copy pkInfoSignature!");
378         FreeBuffData(&certInfo->pkInfoStr);
379         FreeBuffData(&certInfo->pkInfoSignature);
380         return HC_ERR_MEMORY_COPY;
381     }
382     certInfo->pkInfoSignature.length = signatureLen;
383     return HC_SUCCESS;
384 }
385 
GetCertInfo(int32_t osAccountId, const char *userId, const char *authId, CertInfo *certInfo)386 static int32_t GetCertInfo(int32_t osAccountId, const char *userId, const char *authId, CertInfo *certInfo)
387 {
388     AccountToken *token = CreateAccountToken();
389     if (token == NULL) {
390         LOGE("Failed to create account token.");
391         return HC_ERR_ALLOC_MEMORY;
392     }
393     int32_t ret = GetAccountAuthTokenManager()->getToken(osAccountId, token, userId, authId);
394     if (ret != HC_SUCCESS) {
395         LOGE("Failed to get account token!");
396         DestroyAccountToken(token);
397         return ret;
398     }
399     ret = GenerateCertInfo(&token->pkInfoStr, &token->pkInfoSignature, certInfo);
400     DestroyAccountToken(token);
401     if (ret != HC_SUCCESS) {
402         LOGE("Failed to generate cert info!");
403         return ret;
404     }
405     certInfo->signAlg = P256;
406     return HC_SUCCESS;
407 }
408 
GetAccountAsymIdentityInfo( int32_t osAccountId, const char *userId, const char *authId, IdentityInfo *info, bool isNeedGeneratePdid)409 static int32_t GetAccountAsymIdentityInfo(
410     int32_t osAccountId, const char *userId, const char *authId, IdentityInfo *info, bool isNeedGeneratePdid)
411 {
412     int32_t ret = GetCertInfo(osAccountId, userId, authId, &info->proof.certInfo);
413     if (ret != HC_SUCCESS) {
414         LOGE("Failed to generate certInfo!");
415         return ret;
416     }
417 
418 #ifdef ENABLE_ACCOUNT_AUTH_EC_SPEKE
419     ProtocolEntity *ecSpekeEntity = (ProtocolEntity *)HcMalloc(sizeof(ProtocolEntity), 0);
420     if (ecSpekeEntity == NULL) {
421         LOGE("Failed to alloc memory for ec speke entity!");
422         return HC_ERR_ALLOC_MEMORY;
423     }
424     ecSpekeEntity->protocolType = ALG_EC_SPEKE;
425     ecSpekeEntity->expandProcessCmds = CMD_ADD_TRUST_DEVICE;
426 #ifdef ENABLE_PSEUDONYM
427     if (isNeedGeneratePdid) {
428         ecSpekeEntity->expandProcessCmds |= CMD_MK_AGREE;
429     }
430 #else
431     (void)isNeedGeneratePdid;
432 #endif
433     info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&ecSpekeEntity);
434 #else
435     (void)isNeedGeneratePdid;
436 #endif
437 
438     info->proofType = CERTIFICATED;
439     return HC_SUCCESS;
440 }
441 
GetLocalDeviceType(int32_t osAccountId, const CJson *in, const char *groupId, int32_t *localDevType)442 static int32_t GetLocalDeviceType(int32_t osAccountId, const CJson *in, const char *groupId, int32_t *localDevType)
443 {
444     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
445     if (deviceEntry == NULL) {
446         LOGE("Failed to alloc memory for deviceEntry!");
447         return HC_ERR_ALLOC_MEMORY;
448     }
449     int32_t ret = GetPeerDeviceEntry(osAccountId, in, groupId, deviceEntry);
450     if (ret != HC_SUCCESS) {
451         LOGI("Peer device not found, set local device type to accessory!");
452         *localDevType = DEVICE_TYPE_ACCESSORY;
453         DestroyDeviceEntry(deviceEntry);
454         return HC_SUCCESS;
455     }
456     if (deviceEntry->source == SELF_CREATED) {
457         LOGI("Peer device is self created, set local device type to accessory!");
458         *localDevType = DEVICE_TYPE_ACCESSORY;
459     }
460     DestroyDeviceEntry(deviceEntry);
461     return HC_SUCCESS;
462 }
463 
GenerateAuthTokenForAccessory(int32_t osAccountId, const char *groupId, Uint8Buff *authToken)464 static int32_t GenerateAuthTokenForAccessory(int32_t osAccountId, const char *groupId, Uint8Buff *authToken)
465 {
466     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
467     if (deviceEntry == NULL) {
468         LOGE("Failed to create device entry!");
469         return HC_ERR_ALLOC_MEMORY;
470     }
471     int32_t ret = GetSelfDeviceEntry(osAccountId, groupId, deviceEntry);
472     if (ret != HC_SUCCESS) {
473         LOGE("Failed to get self device entry!");
474         DestroyDeviceEntry(deviceEntry);
475         return ret;
476     }
477     const char *userIdSelf = StringGet(&deviceEntry->userId);
478     const char *devIdSelf = StringGet(&deviceEntry->authId);
479     uint8_t keyAliasVal[SHA256_LEN] = { 0 };
480     Uint8Buff keyAlias = { keyAliasVal, SHA256_LEN };
481     ret = GetSymTokenManager()->generateKeyAlias(userIdSelf, devIdSelf, &keyAlias);
482     if (ret != HC_SUCCESS) {
483         LOGE("Failed to generate key alias for authCode!");
484         DestroyDeviceEntry(deviceEntry);
485         return ret;
486     }
487 
488     authToken->val = (uint8_t *)HcMalloc(AUTH_TOKEN_SIZE, 0);
489     if (authToken->val == NULL) {
490         LOGE("Failed to alloc memory for auth token!");
491         DestroyDeviceEntry(deviceEntry);
492         return HC_ERR_ALLOC_MEMORY;
493     }
494     authToken->length = AUTH_TOKEN_SIZE;
495     Uint8Buff userIdBuff = { (uint8_t *)userIdSelf, HcStrlen(userIdSelf) };
496     Uint8Buff challenge = { (uint8_t *)KEY_INFO_PERSISTENT_TOKEN, HcStrlen(KEY_INFO_PERSISTENT_TOKEN) };
497     KeyParams keyAliasParams = { { keyAlias.val, keyAlias.length, true }, false, osAccountId };
498     ret = GetLoaderInstance()->computeHkdf(&keyAliasParams, &userIdBuff, &challenge, authToken);
499     DestroyDeviceEntry(deviceEntry);
500     if (ret != HC_SUCCESS) {
501         LOGE("Failed to computeHkdf from authCode to authToken!");
502         FreeBuffData(authToken);
503     }
504     return ret;
505 }
506 
GenerateTokenAliasForController( int32_t osAccountId, const CJson *in, const char *groupId, Uint8Buff *authTokenAlias)507 static int32_t GenerateTokenAliasForController(
508     int32_t osAccountId, const CJson *in, const char *groupId, Uint8Buff *authTokenAlias)
509 {
510     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
511     if (deviceEntry == NULL) {
512         LOGE("Failed to create device entry!");
513         return HC_ERR_ALLOC_MEMORY;
514     }
515     int32_t ret = GetPeerDeviceEntry(osAccountId, in, groupId, deviceEntry);
516     if (ret != HC_SUCCESS) {
517         LOGE("Failed to get peer device entry!");
518         DestroyDeviceEntry(deviceEntry);
519         return ret;
520     }
521     authTokenAlias->val = (uint8_t *)HcMalloc(SHA256_LEN, 0);
522     if (authTokenAlias->val == NULL) {
523         LOGE("Failed to alloc memory for auth token alias!");
524         DestroyDeviceEntry(deviceEntry);
525         return HC_ERR_ALLOC_MEMORY;
526     }
527     authTokenAlias->length = SHA256_LEN;
528     const char *userIdPeer = StringGet(&deviceEntry->userId);
529     const char *devIdPeer = StringGet(&deviceEntry->authId);
530     ret = GetSymTokenManager()->generateKeyAlias(userIdPeer, devIdPeer, authTokenAlias);
531     DestroyDeviceEntry(deviceEntry);
532     if (ret != HC_SUCCESS) {
533         LOGE("Failed to generate key alias for authToken!");
534         FreeBuffData(authTokenAlias);
535     }
536     return ret;
537 }
538 
GenerateAuthTokenByDevType( const CJson *in, const CJson *urlJson, Uint8Buff *authToken, bool *isTokenStored)539 static int32_t GenerateAuthTokenByDevType(
540     const CJson *in, const CJson *urlJson, Uint8Buff *authToken, bool *isTokenStored)
541 {
542     int32_t osAccountId = INVALID_OS_ACCOUNT;
543     if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
544         LOGE("Failed to get osAccountId!");
545         return HC_ERR_JSON_GET;
546     }
547     const char *groupId = GetStringFromJson(urlJson, FIELD_GROUP_ID);
548     if (groupId == NULL) {
549         LOGE("Failed to get groupId!");
550         return HC_ERR_JSON_GET;
551     }
552     int32_t localDevType = DEVICE_TYPE_CONTROLLER;
553     int32_t ret = GetLocalDeviceType(osAccountId, in, groupId, &localDevType);
554     if (ret != HC_SUCCESS) {
555         LOGE("Failed to get local device type!");
556         return ret;
557     }
558     if (localDevType == DEVICE_TYPE_ACCESSORY) {
559         *isTokenStored = false;
560         ret = GenerateAuthTokenForAccessory(osAccountId, groupId, authToken);
561     } else {
562         ret = GenerateTokenAliasForController(osAccountId, in, groupId, authToken);
563     }
564     return ret;
565 }
566 
GetSelfAccountIdentityInfo( int32_t osAccountId, const char *groupId, IdentityInfo *info, bool isNeedGeneratePdid)567 static int32_t GetSelfAccountIdentityInfo(
568     int32_t osAccountId, const char *groupId, IdentityInfo *info, bool isNeedGeneratePdid)
569 {
570     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
571     if (deviceEntry == NULL) {
572         LOGE("Failed to create device entry!");
573         return HC_ERR_ALLOC_MEMORY;
574     }
575     int32_t ret = GetSelfDeviceEntry(osAccountId, groupId, deviceEntry);
576     if (ret != HC_SUCCESS) {
577         LOGE("Failed to get self device entry!");
578         DestroyDeviceEntry(deviceEntry);
579         return ret;
580     }
581     if (deviceEntry->credential == SYMMETRIC_CRED) {
582         ret = GetIdentityInfoByType(KEY_TYPE_SYM, TRUST_TYPE_UID, groupId, info);
583     } else {
584         const char *userId = StringGet(&deviceEntry->userId);
585         const char *authId = StringGet(&deviceEntry->authId);
586         ret = GetAccountAsymIdentityInfo(osAccountId, userId, authId, info, isNeedGeneratePdid);
587     }
588     DestroyDeviceEntry(deviceEntry);
589     return ret;
590 }
591 
isNeedGeneratePdidByPeerCert(int32_t osAccountId, const CertInfo *certInfo)592 static bool isNeedGeneratePdidByPeerCert(int32_t osAccountId, const CertInfo *certInfo)
593 {
594 #ifdef ENABLE_PSEUDONYM
595     CJson *pkInfoJson = CreateJsonFromString((const char *)certInfo->pkInfoStr.val);
596     if (pkInfoJson == NULL) {
597         LOGE("Failed to create pkInfo json!");
598         return false;
599     }
600     const char *userId = GetStringFromJson(pkInfoJson, FIELD_USER_ID);
601     if (userId == NULL) {
602         LOGE("Failed to get userId!");
603         FreeJson(pkInfoJson);
604         return false;
605     }
606     bool isNeedGenerate = GetPseudonymInstance()->isNeedRefreshPseudonymId(osAccountId, userId);
607     FreeJson(pkInfoJson);
608     return isNeedGenerate;
609 #else
610     (void)osAccountId;
611     (void)certInfo;
612     return false;
613 #endif
614 }
615 
GetAccountRelatedCredInfo( int32_t osAccountId, const char *groupId, const char *deviceId, bool isUdid, IdentityInfo *info)616 int32_t GetAccountRelatedCredInfo(
617     int32_t osAccountId, const char *groupId, const char *deviceId, bool isUdid, IdentityInfo *info)
618 {
619     if (groupId == NULL || deviceId == NULL || info == NULL) {
620         LOGE("Invalid input params!");
621         return HC_ERR_INVALID_PARAMS;
622     }
623     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
624     if (deviceEntry == NULL) {
625         LOGE("Failed to create device entry!");
626         return HC_ERR_ALLOC_MEMORY;
627     }
628     int32_t ret = GaGetTrustedDeviceEntryById(osAccountId, deviceId, isUdid, groupId, deviceEntry);
629     if (ret != HC_SUCCESS) {
630         LOGI("peer device not exist, get self identity info.");
631         DestroyDeviceEntry(deviceEntry);
632         return GetSelfAccountIdentityInfo(osAccountId, groupId, info, true);
633     }
634     bool isNeedGeneratePdid = false;
635 #ifdef ENABLE_PSEUDONYM
636     const char *peerUserId = StringGet(&deviceEntry->userId);
637     isNeedGeneratePdid = GetPseudonymInstance()->isNeedRefreshPseudonymId(osAccountId, peerUserId);
638 #endif
639     if (deviceEntry->source == SELF_CREATED) {
640         LOGI("peer device is from self created, get self identity info.");
641         DestroyDeviceEntry(deviceEntry);
642         return GetSelfAccountIdentityInfo(osAccountId, groupId, info, isNeedGeneratePdid);
643     }
644     int credType = deviceEntry->credential;
645     DestroyDeviceEntry(deviceEntry);
646     if (credType == SYMMETRIC_CRED) {
647         LOGI("credential type is symmetric, get sym identity info.");
648         return GetIdentityInfoByType(KEY_TYPE_SYM, TRUST_TYPE_UID, groupId, info);
649     } else {
650         LOGI("credential type is asymmetric, get self identity info.");
651         return GetSelfAccountIdentityInfo(osAccountId, groupId, info, isNeedGeneratePdid);
652     }
653 }
654 
GetSharedSecretByPeerCertFromPlugin( int32_t osAccountId, const char *peerUserId, const CertInfo *peerCertInfo, Uint8Buff *sharedSecret)655 static int32_t GetSharedSecretByPeerCertFromPlugin(
656     int32_t osAccountId, const char *peerUserId, const CertInfo *peerCertInfo, Uint8Buff *sharedSecret)
657 {
658     CJson *input = CreateJson();
659     if (input == NULL) {
660         LOGE("Create input params json failed!");
661         return HC_ERR_JSON_CREATE;
662     }
663     CJson *output = CreateJson();
664     if (output == NULL) {
665         LOGE("Create output results json failed!");
666         FreeJson(input);
667         return HC_ERR_JSON_CREATE;
668     }
669     int32_t res = HC_ERR_JSON_ADD;
670     if ((peerUserId != NULL) && (AddStringToJson(input, FIELD_PEER_USER_ID, peerUserId) != HC_SUCCESS)) {
671         LOGE("peer user id eixsts, but add peer user id to json failed!");
672         goto ERR;
673     }
674     GOTO_ERR_AND_SET_RET(AddCertInfoToJson(peerCertInfo, input), res);
675     GOTO_ERR_AND_SET_RET(ExcuteCredMgrCmd(osAccountId, GET_SHARED_SECRET_BY_PEER_CERT, input, output), res);
676     res = HC_ERR_JSON_GET;
677     const char *sharedKeyAlias = GetStringFromJson(output, FIELD_SHARED_SECRET);
678     if (sharedKeyAlias == NULL) {
679         LOGE("Get alias failed!");
680         goto ERR;
681     }
682     uint32_t sharedKeyAliasLen = HcStrlen(sharedKeyAlias) + 1;
683     uint8_t *aliasVal = (uint8_t *)HcMalloc(sharedKeyAliasLen, 0);
684     GOTO_IF_CHECK_NULL(aliasVal, FIELD_SHARED_SECRET);
685     if (memcpy_s(aliasVal, sharedKeyAliasLen, sharedKeyAlias, sharedKeyAliasLen) != EOK) {
686         LOGE("parse output result set memcpy alias failed!");
687         HcFree(aliasVal);
688         aliasVal = NULL;
689         goto ERR;
690     }
691     sharedSecret->val = aliasVal;
692     sharedSecret->length = sharedKeyAliasLen;
693     res = HC_SUCCESS;
694 ERR:
695     FreeJson(input);
696     FreeJson(output);
697     return res;
698 }
699 
GetAccountAsymSharedSecret(int32_t osAccountId, const char *peerUserId, const CertInfo *peerCertInfo, Uint8Buff *sharedSecret)700 int32_t GetAccountAsymSharedSecret(int32_t osAccountId, const char *peerUserId, const CertInfo *peerCertInfo,
701     Uint8Buff *sharedSecret)
702 {
703     if (peerCertInfo == NULL || sharedSecret == NULL) {
704         LOGE("Invalid input params!");
705         return HC_ERR_INVALID_PARAMS;
706     }
707     if (HasAccountAuthPlugin() == HC_SUCCESS) {
708         return GetSharedSecretByPeerCertFromPlugin(osAccountId, peerUserId, peerCertInfo, sharedSecret);
709     }
710     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
711     if (deviceEntry == NULL) {
712         LOGE("Failed to create self device entry!");
713         return HC_ERR_ALLOC_MEMORY;
714     }
715     int32_t ret = GetSelfDeviceEntryByPeerCert(osAccountId, peerCertInfo, deviceEntry);
716     if (ret != HC_SUCCESS) {
717         LOGE("Failed to get self device entry!");
718         DestroyDeviceEntry(deviceEntry);
719         return ret;
720     }
721     const char *selfUserId = StringGet(&deviceEntry->userId);
722     const char *selfAuthId = StringGet(&deviceEntry->authId);
723     ret = VerifyPeerCertInfo(osAccountId, selfUserId, selfAuthId, peerCertInfo);
724     if (ret != HC_SUCCESS) {
725         LOGE("Failed to verify peer cert! [Res]: %d", ret);
726         DestroyDeviceEntry(deviceEntry);
727         return ret;
728     }
729     ret = GetSharedSecretForAccountInPake(osAccountId, selfUserId, selfAuthId, peerCertInfo, sharedSecret);
730     DestroyDeviceEntry(deviceEntry);
731     return ret;
732 }
733 
GetAccountSymSharedSecret(const CJson *in, const CJson *urlJson, Uint8Buff *sharedSecret)734 int32_t GetAccountSymSharedSecret(const CJson *in, const CJson *urlJson, Uint8Buff *sharedSecret)
735 {
736     if (in == NULL || urlJson == NULL || sharedSecret == NULL) {
737         LOGE("Invalid input params!");
738         return HC_ERR_INVALID_PARAMS;
739     }
740     int32_t osAccountId;
741     if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
742         LOGE("Failed to get osAccountId!");
743         return HC_ERR_JSON_GET;
744     }
745     bool isTokenStored = true;
746     Uint8Buff authToken = { NULL, 0 };
747     int32_t ret = GenerateAuthTokenByDevType(in, urlJson, &authToken, &isTokenStored);
748     if (ret != HC_SUCCESS) {
749         LOGE("Failed to generate auth token!");
750         return ret;
751     }
752     uint8_t seed[SEED_SIZE] = { 0 };
753     Uint8Buff seedBuff = { seed, SEED_SIZE };
754     ret = GetByteFromJson(in, FIELD_SEED, seed, SEED_SIZE);
755     if (ret != HC_SUCCESS) {
756         LOGE("Failed to get seed!");
757         FreeBuffData(&authToken);
758         return HC_ERR_JSON_GET;
759     }
760     sharedSecret->val = (uint8_t *)HcMalloc(ISO_PSK_LEN, 0);
761     if (sharedSecret->val == NULL) {
762         LOGE("Failed to alloc sharedSecret memory!");
763         FreeBuffData(&authToken);
764         return HC_ERR_ALLOC_MEMORY;
765     }
766     sharedSecret->length = ISO_PSK_LEN;
767     KeyParams keyParams = { { authToken.val, authToken.length, isTokenStored }, false, osAccountId };
768     ret = GetLoaderInstance()->computeHmac(&keyParams, &seedBuff, sharedSecret);
769     FreeBuffData(&authToken);
770     if (ret != HC_SUCCESS) {
771         LOGE("ComputeHmac for psk failed, ret: %d.", ret);
772         FreeBuffData(sharedSecret);
773     }
774     return ret;
775 }
776 
GetAccountAsymCredInfo(int32_t osAccountId, const CertInfo *certInfo, IdentityInfo **returnInfo)777 int32_t GetAccountAsymCredInfo(int32_t osAccountId, const CertInfo *certInfo, IdentityInfo **returnInfo)
778 {
779     if (certInfo == NULL || returnInfo == NULL) {
780         LOGE("Invalid input params!");
781         return HC_ERR_INVALID_PARAMS;
782     }
783     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
784     if (deviceEntry == NULL) {
785         LOGE("Failed to create self device entry!");
786         return HC_ERR_ALLOC_MEMORY;
787     }
788     int32_t ret = GetSelfDeviceEntryByPeerCert(osAccountId, certInfo, deviceEntry);
789     if (ret != HC_SUCCESS) {
790         LOGE("Failed to get self device entry!");
791         DestroyDeviceEntry(deviceEntry);
792         return ret;
793     }
794     IdentityInfo *info = CreateIdentityInfo();
795     if (info == NULL) {
796         LOGE("Failed to create identity info!");
797         DestroyDeviceEntry(deviceEntry);
798         return HC_ERR_ALLOC_MEMORY;
799     }
800     const char *selfUserId = StringGet(&deviceEntry->userId);
801     const char *selfAuthId = StringGet(&deviceEntry->authId);
802     bool isNeedGeneratePdid = isNeedGeneratePdidByPeerCert(osAccountId, certInfo);
803     ret = GetAccountAsymIdentityInfo(osAccountId, selfUserId, selfAuthId, info, isNeedGeneratePdid);
804     DestroyDeviceEntry(deviceEntry);
805     if (ret != HC_SUCCESS) {
806         LOGE("Failed to get account asym identity info!");
807         DestroyIdentityInfo(info);
808         return ret;
809     }
810     *returnInfo = info;
811     return HC_SUCCESS;
812 }
813 
GetAccountSymCredInfoByPeerUrl(const CJson *in, const CJson *urlJson, IdentityInfo *info)814 int32_t GetAccountSymCredInfoByPeerUrl(const CJson *in, const CJson *urlJson, IdentityInfo *info)
815 {
816     if (in == NULL || urlJson == NULL || info == NULL) {
817         LOGE("Invalid input params!");
818         return HC_ERR_INVALID_PARAMS;
819     }
820     int32_t osAccountId = INVALID_OS_ACCOUNT;
821     if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
822         LOGE("Failed to get osAccountId!");
823         return HC_ERR_JSON_GET;
824     }
825     const char *groupId = GetStringFromJson(urlJson, FIELD_GROUP_ID);
826     if (groupId == NULL) {
827         LOGE("Failed to get group id!");
828         return HC_ERR_JSON_GET;
829     }
830     int32_t ret = CheckGroupExist(osAccountId, groupId);
831     if (ret != HC_SUCCESS) {
832         LOGE("group not exist!");
833         return ret;
834     }
835     return GetIdentityInfoByType(KEY_TYPE_SYM, TRUST_TYPE_UID, groupId, info);
836 }