• 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 "account_auth_plugin_proxy.h"
17 #include "account_related_group_auth.h"
18 #include "alg_defs.h"
19 #include "alg_loader.h"
20 #include "cert_operation.h"
21 #include "group_auth_data_operation.h"
22 #include "group_operation_common.h"
23 #include "hc_log.h"
24 #include "identity_manager.h"
25 
GetAccountRelatedCandidateGroups(int32_t osAccountId,const CJson * in,bool isDeviceLevel,GroupEntryVec * vec)26 static int32_t GetAccountRelatedCandidateGroups(
27     int32_t osAccountId, const CJson *in, bool isDeviceLevel, GroupEntryVec *vec)
28 {
29     BaseGroupAuth *groupAuth = GetAccountRelatedGroupAuth();
30     if (groupAuth == NULL) {
31         return HC_ERR_NULL_PTR;
32     }
33     QueryGroupParams queryParams = InitQueryGroupParams();
34     if (!isDeviceLevel) {
35         queryParams.groupVisibility = GROUP_VISIBILITY_PUBLIC;
36     }
37     ((AccountRelatedGroupAuth *)groupAuth)->getAccountCandidateGroup(osAccountId, in, &queryParams, vec);
38     // All return success, only notify the plugin.
39     if (HasAccountAuthPlugin() == HC_SUCCESS && vec->size(vec) == 0) {
40         CJson *input = CreateJson();
41         if (input == NULL) {
42             return HC_SUCCESS;
43         }
44         CJson *output = CreateJson();
45         if (output == NULL) {
46             FreeJson(input);
47             return HC_SUCCESS;
48         }
49         int32_t ret = ExcuteCredMgrCmd(osAccountId, QUERY_SELF_CREDENTIAL_INFO, input, output);
50         if (ret != HC_SUCCESS) {
51             LOGE("Account cred is empty.");
52         }
53         FreeJson(input);
54         FreeJson(output);
55     }
56     return HC_SUCCESS;
57 }
58 
GetAccountUnrelatedCandidateGroups(int32_t osAccountId,bool isDeviceLevel,GroupEntryVec * vec)59 static int32_t GetAccountUnrelatedCandidateGroups(int32_t osAccountId, bool isDeviceLevel, GroupEntryVec *vec)
60 {
61     QueryGroupParams queryParams = InitQueryGroupParams();
62     queryParams.groupType = PEER_TO_PEER_GROUP;
63     if (!isDeviceLevel) {
64         queryParams.groupVisibility = GROUP_VISIBILITY_PUBLIC;
65     }
66     return QueryGroups(osAccountId, &queryParams, vec);
67 }
68 
GetGroupInfoByGroupId(int32_t osAccountId,const char * groupId,GroupEntryVec * groupEntryVec)69 static void GetGroupInfoByGroupId(int32_t osAccountId, const char *groupId, GroupEntryVec *groupEntryVec)
70 {
71     QueryGroupParams queryParams = InitQueryGroupParams();
72     queryParams.groupId = groupId;
73     int32_t ret = QueryGroups(osAccountId, &queryParams, groupEntryVec);
74     if (ret != HC_SUCCESS) {
75         LOGE("Failed to query groups for groupId: %s!", groupId);
76     }
77 }
78 
GetCandidateGroups(int32_t osAccountId,const CJson * in,GroupEntryVec * groupEntryVec)79 static void GetCandidateGroups(int32_t osAccountId, const CJson *in, GroupEntryVec *groupEntryVec)
80 {
81     bool isDeviceLevel = false;
82     (void)GetBoolFromJson(in, FIELD_IS_DEVICE_LEVEL, &isDeviceLevel);
83 
84     int32_t ret = GetAccountRelatedCandidateGroups(osAccountId, in, isDeviceLevel, groupEntryVec);
85     if (ret != HC_SUCCESS) {
86         LOGE("Failed to get account related groups!");
87     }
88 
89     ret = GetAccountUnrelatedCandidateGroups(osAccountId, isDeviceLevel, groupEntryVec);
90     if (ret != HC_SUCCESS) {
91         LOGE("Failed to get p2p groups!");
92     }
93 }
94 
IsDeviceInGroup(int32_t osAccountId,int32_t groupType,const char * deviceId,const char * groupId,bool isUdid)95 static bool IsDeviceInGroup(
96     int32_t osAccountId, int32_t groupType, const char *deviceId, const char *groupId, bool isUdid)
97 {
98     if (isUdid) {
99         return GaIsDeviceInGroup(groupType, osAccountId, deviceId, NULL, groupId);
100     } else {
101         return GaIsDeviceInGroup(groupType, osAccountId, NULL, deviceId, groupId);
102     }
103 }
104 
SetProtocolsToIdentityInfo(int32_t keyType,IdentityInfo * info)105 static int32_t SetProtocolsToIdentityInfo(int32_t keyType, IdentityInfo *info)
106 {
107     if (keyType == KEY_TYPE_ASYM) {
108 #ifdef ENABLE_P2P_AUTH_EC_SPEKE
109         ProtocolEntity *entity = (ProtocolEntity *)HcMalloc(sizeof(ProtocolEntity), 0);
110         if (entity == NULL) {
111             LOGE("Failed to alloc memory for entity!");
112             return HC_ERR_ALLOC_MEMORY;
113         }
114         entity->protocolType = ALG_EC_SPEKE;
115         info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&entity);
116 #else
117         (void)info;
118 #endif
119     } else {
120 #ifdef ENABLE_P2P_AUTH_ISO
121         ProtocolEntity *entity = (ProtocolEntity *)HcMalloc(sizeof(ProtocolEntity), 0);
122         if (entity == NULL) {
123             LOGE("Failed to alloc memory for entity!");
124             return HC_ERR_ALLOC_MEMORY;
125         }
126         entity->protocolType = ALG_ISO;
127         info->protocolVec.pushBack(&info->protocolVec, (const ProtocolEntity **)&entity);
128 #else
129         (void)info;
130 #endif
131     }
132 
133     return HC_SUCCESS;
134 }
135 
IsP2pAuthTokenExist(const TrustedDeviceEntry * deviceEntry)136 static bool IsP2pAuthTokenExist(const TrustedDeviceEntry *deviceEntry)
137 {
138     Uint8Buff pkgNameBuff = { (uint8_t *)GROUP_MANAGER_PACKAGE_NAME, strlen(GROUP_MANAGER_PACKAGE_NAME) };
139 
140     const char *serviceType = StringGet(&deviceEntry->serviceType);
141     Uint8Buff serviceTypeBuff = { (uint8_t *)serviceType, strlen(serviceType) };
142 
143     const char *peerAuthId = StringGet(&deviceEntry->authId);
144     Uint8Buff peerAuthIdBuff = { (uint8_t *)peerAuthId, strlen(peerAuthId) };
145 
146     uint8_t keyAliasVal[ISO_KEY_ALIAS_LEN] = { 0 };
147     Uint8Buff keyAlias = { keyAliasVal, ISO_KEY_ALIAS_LEN };
148     int32_t ret =
149         GenerateKeyAlias(&pkgNameBuff, &serviceTypeBuff, KEY_ALIAS_AUTH_TOKEN, &peerAuthIdBuff, &keyAlias);
150     if (ret != HC_SUCCESS) {
151         LOGE("Failed to generate key alias!");
152         return false;
153     }
154 
155     ret = GetLoaderInstance()->checkKeyExist(&keyAlias);
156     if (ret != HC_SUCCESS) {
157         LOGE("auth token not exist!");
158         return false;
159     }
160     return true;
161 }
162 
GetAccountUnrelatedIdentityInfo(int32_t osAccountId,const char * groupId,const char * deviceId,bool isUdid,IdentityInfo * info)163 static int32_t GetAccountUnrelatedIdentityInfo(
164     int32_t osAccountId, const char *groupId, const char *deviceId, bool isUdid, IdentityInfo *info)
165 {
166     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
167     if (deviceEntry == NULL) {
168         LOGE("Failed to create deviceEntry!");
169         return HC_ERR_ALLOC_MEMORY;
170     }
171     int32_t ret = GaGetTrustedDeviceEntryById(osAccountId, deviceId, isUdid, groupId, deviceEntry);
172     if (ret != HC_SUCCESS) {
173         LOGE("Failed to get device entry!");
174         DestroyDeviceEntry(deviceEntry);
175         return ret;
176     }
177 
178     int32_t keyType = IsP2pAuthTokenExist(deviceEntry) ? KEY_TYPE_SYM : KEY_TYPE_ASYM;
179     DestroyDeviceEntry(deviceEntry);
180     CJson *urlJson = CreateCredUrlJson(PRE_SHARED, keyType, TRUST_TYPE_P2P);
181 
182     if (!urlJson) {
183         LOGE("Failed to create CredUrlJson info!");
184         return HC_ERR_ALLOC_MEMORY;
185     }
186     if (AddStringToJson(urlJson, FIELD_GROUP_ID, groupId) != HC_SUCCESS) {
187         LOGE("Failed to add group id!");
188         FreeJson(urlJson);
189         return HC_ERR_JSON_ADD;
190     }
191 
192     char *urlStr = PackJsonToString(urlJson);
193     FreeJson(urlJson);
194     if (urlStr == NULL) {
195         LOGE("Failed to pack url json to string!");
196         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
197     }
198 
199     ret = SetPreSharedUrlForProof(urlStr, &info->proof.preSharedUrl);
200     FreeJsonString(urlStr);
201     if (ret != HC_SUCCESS) {
202         LOGE("Failed to set preSharedUrl of proof!");
203         return ret;
204     }
205 
206     ret = SetProtocolsToIdentityInfo(keyType, info);
207     if (ret != HC_SUCCESS) {
208         LOGE("Failed to set protocols!");
209         return ret;
210     }
211 
212     info->proofType = PRE_SHARED;
213     if (ret != HC_SUCCESS) {
214         LOGE("Failed to get p2p identity by key type!");
215     }
216     return ret;
217 }
218 
GetIdentityInfo(int32_t osAccountId,const TrustedGroupEntry * groupEntry,const char * deviceId,bool isUdid,IdentityInfo ** returnInfo)219 static int32_t GetIdentityInfo(int32_t osAccountId, const TrustedGroupEntry *groupEntry, const char *deviceId,
220     bool isUdid, IdentityInfo **returnInfo)
221 {
222     IdentityInfo *info = CreateIdentityInfo();
223     if (info == NULL) {
224         LOGE("Failed to create identity info!");
225         return HC_ERR_ALLOC_MEMORY;
226     }
227     int32_t ret;
228     const char *groupId = StringGet(&groupEntry->id);
229     if (groupEntry->type == PEER_TO_PEER_GROUP) {
230         ret = GetAccountUnrelatedIdentityInfo(osAccountId, groupId, deviceId, isUdid, info);
231     } else {
232         ret = GetAccountRelatedCredInfo(osAccountId, groupId, deviceId, isUdid, info);
233     }
234     if (ret != HC_SUCCESS) {
235         LOGE("Failed to get identity info!");
236         DestroyIdentityInfo(info);
237         return ret;
238     }
239     *returnInfo = info;
240     return HC_SUCCESS;
241 }
242 
AddNoPseudonymIdentityInfo(int32_t osAccountId,const TrustedGroupEntry * groupEntry,const char * deviceId,bool isUdid,IdentityInfoVec * identityInfoVec)243 static void AddNoPseudonymIdentityInfo(int32_t osAccountId, const TrustedGroupEntry *groupEntry,
244     const char *deviceId, bool isUdid, IdentityInfoVec *identityInfoVec)
245 {
246     IdentityInfo *info = NULL;
247     if (GetIdentityInfo(osAccountId, groupEntry, deviceId, isUdid, &info) != HC_SUCCESS) {
248         return;
249     }
250     info->proof.certInfo.isPseudonym = false;
251     identityInfoVec->pushBack(identityInfoVec, (const IdentityInfo **)&info);
252 }
253 
GetIdentityInfos(int32_t osAccountId,const CJson * in,const GroupEntryVec * groupEntryVec,IdentityInfoVec * identityInfoVec)254 static int32_t GetIdentityInfos(
255     int32_t osAccountId, const CJson *in, const GroupEntryVec *groupEntryVec, IdentityInfoVec *identityInfoVec)
256 {
257     const char *pkgName = GetStringFromJson(in, FIELD_SERVICE_PKG_NAME);
258     if (pkgName == NULL) {
259         LOGE("Failed to get service package name!");
260         return HC_ERR_JSON_GET;
261     }
262     bool isUdid = false;
263     const char *deviceId = GetPeerDevIdFromJson(in, &isUdid);
264     if (deviceId == NULL) {
265         LOGE("Failed to get peer device id!");
266         return HC_ERR_JSON_GET;
267     }
268     uint32_t index;
269     TrustedGroupEntry **ptr = NULL;
270     FOR_EACH_HC_VECTOR(*groupEntryVec, index, ptr)
271     {
272         const TrustedGroupEntry *groupEntry = (TrustedGroupEntry *)(*ptr);
273         const char *groupId = StringGet(&(groupEntry->id));
274         if (groupId == NULL) {
275             continue;
276         }
277         if (!GaIsGroupAccessible(osAccountId, groupId, pkgName)) {
278             continue;
279         }
280         if (!IsDeviceInGroup(osAccountId, groupEntry->type, deviceId, groupId, isUdid)) {
281             continue;
282         }
283         IdentityInfo *info = NULL;
284         if (GetIdentityInfo(osAccountId, groupEntry, deviceId, isUdid, &info) != HC_SUCCESS) {
285             continue;
286         }
287         if (info->proofType == CERTIFICATED) {
288             info->proof.certInfo.isPseudonym = true;
289         }
290         identityInfoVec->pushBack(identityInfoVec, (const IdentityInfo **)&info);
291         if (info->proofType == CERTIFICATED) {
292             AddNoPseudonymIdentityInfo(osAccountId, groupEntry, deviceId, isUdid, identityInfoVec);
293         }
294     }
295     LOGI("The identity info size is: %u", identityInfoVec->size(identityInfoVec));
296     return HC_SUCCESS;
297 }
298 
GetCredInfosByPeerIdentity(const CJson * in,IdentityInfoVec * identityInfoVec)299 static int32_t GetCredInfosByPeerIdentity(const CJson *in, IdentityInfoVec *identityInfoVec)
300 {
301     int32_t osAccountId = INVALID_OS_ACCOUNT;
302     int32_t ret;
303     if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
304         LOGE("Failed to get osAccountId!");
305         return HC_ERR_JSON_GET;
306     }
307     const char *groupId = GetStringFromJson(in, FIELD_GROUP_ID);
308     if (groupId == NULL) {
309         groupId = GetStringFromJson(in, FIELD_SERVICE_TYPE);
310     }
311     GroupEntryVec groupEntryVec = CreateGroupEntryVec();
312     if (groupId == NULL) {
313         GetCandidateGroups(osAccountId, in, &groupEntryVec);
314     } else {
315         GetGroupInfoByGroupId(osAccountId, groupId, &groupEntryVec);
316     }
317 
318     bool isDeviceLevel = false;
319     (void)GetBoolFromJson(in, FIELD_IS_DEVICE_LEVEL, &isDeviceLevel);
320     if (groupEntryVec.size(&groupEntryVec) == 0) {
321         if (isDeviceLevel) {
322             // device level auth still has the chance to try p2p direct auth
323             // so, do not report error here.
324             LOGI("No satisfied candidate group!");
325         } else {
326             LOGE("No satisfied candidate group!");
327         }
328         ClearGroupEntryVec(&groupEntryVec);
329         return HC_ERR_NO_CANDIDATE_GROUP;
330     }
331     ret = GetIdentityInfos(osAccountId, in, &groupEntryVec, identityInfoVec);
332     ClearGroupEntryVec(&groupEntryVec);
333     return ret;
334 }
335 
SetIdentityInfoByUrl(const CJson * urlJson,IdentityInfo * info)336 static int32_t SetIdentityInfoByUrl(const CJson *urlJson, IdentityInfo *info)
337 {
338     if (urlJson == NULL || info == NULL) {
339         LOGE("Need urlJson and IdentityInfo is not NULL!");
340         return HC_ERR_INVALID_PARAMS;
341     }
342 
343     int32_t keyType = 0;
344     if (GetIntFromJson(urlJson, PRESHARED_URL_KEY_TYPE, &keyType) != HC_SUCCESS) {
345         LOGE("Failed to get trust type!");
346         return HC_ERR_JSON_GET;
347     }
348 
349     char *urlStr = PackJsonToString(urlJson);
350     if (urlStr == NULL) {
351         LOGE("Failed to pack url json to string!");
352         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
353     }
354     int32_t ret = SetPreSharedUrlForProof(urlStr, &info->proof.preSharedUrl);
355     FreeJsonString(urlStr);
356     if (ret != HC_SUCCESS) {
357         LOGE("Failed to set preSharedUrl of proof!");
358         return ret;
359     }
360 
361     ret = SetProtocolsToIdentityInfo(keyType, info);
362     if (ret != HC_SUCCESS) {
363         LOGE("Failed to set protocols!");
364         return ret;
365     }
366 
367     info->proofType = PRE_SHARED;
368     return ret;
369 }
370 
CheckAndGetP2pCredInfo(const CJson * in,const CJson * urlJson,IdentityInfo * info)371 static int32_t CheckAndGetP2pCredInfo(const CJson *in, const CJson *urlJson, IdentityInfo *info)
372 {
373     int32_t osAccountId = INVALID_OS_ACCOUNT;
374     if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
375         LOGE("Failed to get osAccountId!");
376         return HC_ERR_JSON_GET;
377     }
378 
379     const char *groupId = GetStringFromJson(urlJson, FIELD_GROUP_ID);
380     if (groupId == NULL) {
381         LOGE("Failed to get groupId!");
382         return HC_ERR_JSON_GET;
383     }
384     int32_t ret = CheckGroupExist(osAccountId, groupId);
385     if (ret != HC_SUCCESS) {
386         LOGE("group not exist!");
387         return ret;
388     }
389     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
390     if (deviceEntry == NULL) {
391         LOGE("Failed to create device entry!");
392         return HC_ERR_ALLOC_MEMORY;
393     }
394     ret = GetPeerDeviceEntry(osAccountId, in, groupId, deviceEntry);
395     DestroyDeviceEntry(deviceEntry);
396     if (ret != HC_SUCCESS) {
397         LOGE("peer device not found!");
398         return ret;
399     }
400 
401     ret = SetIdentityInfoByUrl(urlJson, info);
402     if (ret != HC_SUCCESS) {
403         LOGE("Failed to get p2p identity info by key type!");
404     }
405     return ret;
406 }
407 
GetCredInfoByPeerUrl(const CJson * in,const Uint8Buff * presharedUrl,IdentityInfo ** returnInfo)408 static int32_t GetCredInfoByPeerUrl(const CJson *in, const Uint8Buff *presharedUrl, IdentityInfo **returnInfo)
409 {
410     if (in == NULL || presharedUrl == NULL || returnInfo == NULL) {
411         LOGE("Invalid input params!");
412         return HC_ERR_INVALID_PARAMS;
413     }
414 
415     CJson *urlJson = CreateJsonFromString((const char *)presharedUrl->val);
416     if (urlJson == NULL) {
417         LOGE("Failed to create url json!");
418         return HC_ERR_JSON_CREATE;
419     }
420 
421     int32_t trustType = 0;
422     if (GetIntFromJson(urlJson, PRESHARED_URL_TRUST_TYPE, &trustType) != HC_SUCCESS) {
423         LOGE("Failed to get trust type!");
424         FreeJson(urlJson);
425         return HC_ERR_JSON_GET;
426     }
427 
428     IdentityInfo *info = CreateIdentityInfo();
429     if (info == NULL) {
430         LOGE("Failed to create identity info!");
431         FreeJson(urlJson);
432         return HC_ERR_ALLOC_MEMORY;
433     }
434     int32_t ret;
435     switch (trustType) {
436         case TRUST_TYPE_UID:
437             ret = GetAccountSymCredInfoByPeerUrl(in, urlJson, info);
438             break;
439         case TRUST_TYPE_P2P:
440             ret = CheckAndGetP2pCredInfo(in, urlJson, info);
441             break;
442         default:
443             LOGE("Invalid trust type!");
444             ret = HC_ERR_INVALID_PARAMS;
445             break;
446     }
447     FreeJson(urlJson);
448 
449     *returnInfo = info;
450     return ret;
451 }
452 
GenerateKeyAliasInIso(const CJson * in,const char * groupId,uint8_t * keyAlias,uint32_t keyAliasLen)453 static int32_t GenerateKeyAliasInIso(const CJson *in, const char *groupId, uint8_t *keyAlias, uint32_t keyAliasLen)
454 {
455     int32_t osAccountId = INVALID_OS_ACCOUNT;
456     if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
457         LOGE("Failed to get osAccountId!");
458         return HC_ERR_JSON_GET;
459     }
460     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
461     if (deviceEntry == NULL) {
462         LOGE("Failed to create device entry!");
463         return HC_ERR_ALLOC_MEMORY;
464     }
465     int32_t ret = GetPeerDeviceEntry(osAccountId, in, groupId, deviceEntry);
466     if (ret != HC_SUCCESS) {
467         LOGE("Failed to get peer device entry!");
468         DestroyDeviceEntry(deviceEntry);
469         return ret;
470     }
471     Uint8Buff pkgNameBuff = { (uint8_t *)GROUP_MANAGER_PACKAGE_NAME,
472         (uint32_t)strlen(GROUP_MANAGER_PACKAGE_NAME) };
473     const char *serviceType = StringGet(&deviceEntry->serviceType);
474     Uint8Buff serviceTypeBuff = { (uint8_t *)serviceType, (uint32_t)strlen(serviceType) };
475     const char *peerAuthId = StringGet(&deviceEntry->authId);
476     Uint8Buff peerAuthIdBuff = { (uint8_t *)peerAuthId, (uint32_t)strlen(peerAuthId) };
477     Uint8Buff outKeyAlias = { keyAlias, keyAliasLen };
478     ret = GenerateKeyAlias(&pkgNameBuff, &serviceTypeBuff, KEY_ALIAS_AUTH_TOKEN, &peerAuthIdBuff, &outKeyAlias);
479     DestroyDeviceEntry(deviceEntry);
480     return ret;
481 }
482 
AuthGeneratePsk(const CJson * in,const char * groupId,const Uint8Buff * seed,Uint8Buff * sharedSecret)483 static int32_t AuthGeneratePsk(
484     const CJson *in, const char *groupId, const Uint8Buff *seed, Uint8Buff *sharedSecret)
485 {
486     uint8_t keyAlias[ISO_KEY_ALIAS_LEN] = { 0 };
487     int ret = GenerateKeyAliasInIso(in, groupId, keyAlias, sizeof(keyAlias));
488     if (ret != HC_SUCCESS) {
489         LOGE("Failed to generate key alias in iso!");
490         return ret;
491     }
492     Uint8Buff keyAliasBuf = { keyAlias, sizeof(keyAlias) };
493     return GetLoaderInstance()->computeHmac(&keyAliasBuf, seed, sharedSecret, true);
494 }
495 
GetSharedSecretForP2pInIso(const CJson * in,const char * groupId,Uint8Buff * sharedSecret)496 static int32_t GetSharedSecretForP2pInIso(const CJson *in, const char *groupId, Uint8Buff *sharedSecret)
497 {
498     uint8_t *seedVal = (uint8_t *)HcMalloc(SEED_LEN, 0);
499     if (seedVal == NULL) {
500         LOGE("Failed to alloc memory for seed!");
501         return HC_ERR_ALLOC_MEMORY;
502     }
503     Uint8Buff seedBuff = { seedVal, SEED_LEN };
504     int32_t ret = GetByteFromJson(in, FIELD_SEED, seedBuff.val, seedBuff.length);
505     if (ret != HC_SUCCESS) {
506         LOGE("Failed to get seed!");
507         HcFree(seedVal);
508         return HC_ERR_JSON_GET;
509     }
510     uint8_t *pskVal = (uint8_t *)HcMalloc(ISO_PSK_LEN, 0);
511     if (pskVal == NULL) {
512         LOGE("Failed to alloc memory for psk!");
513         HcFree(seedVal);
514         return HC_ERR_ALLOC_MEMORY;
515     }
516     sharedSecret->val = pskVal;
517     sharedSecret->length = ISO_PSK_LEN;
518     ret = AuthGeneratePsk(in, groupId, &seedBuff, sharedSecret);
519     HcFree(seedVal);
520     if (ret != HC_SUCCESS) {
521         LOGE("Failed to generate psk!");
522         FreeBuffData(sharedSecret);
523     }
524     return ret;
525 }
526 
GetSelfAuthIdAndUserType(int32_t osAccountId,const char * groupId,Uint8Buff * authIdBuff,int32_t * userType)527 static int32_t GetSelfAuthIdAndUserType(
528     int32_t osAccountId, const char *groupId, Uint8Buff *authIdBuff, int32_t *userType)
529 {
530     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
531     if (deviceEntry == NULL) {
532         LOGE("Failed to create device entry!");
533         return HC_ERR_ALLOC_MEMORY;
534     }
535     int32_t ret = GetSelfDeviceEntry(osAccountId, groupId, deviceEntry);
536     if (ret != HC_SUCCESS) {
537         LOGE("Failed to get self device entry!");
538         DestroyDeviceEntry(deviceEntry);
539         return ret;
540     }
541     const char *selfAuthId = StringGet(&deviceEntry->authId);
542     uint32_t authIdLen = strlen(selfAuthId);
543     authIdBuff->val = (uint8_t *)HcMalloc(authIdLen + 1, 0);
544     if (authIdBuff->val == NULL) {
545         LOGE("Failed to alloc memory for authId!");
546         DestroyDeviceEntry(deviceEntry);
547         return HC_ERR_ALLOC_MEMORY;
548     }
549     if (memcpy_s(authIdBuff->val, authIdLen + 1, selfAuthId, authIdLen) != EOK) {
550         LOGE("Failed to copy authId!");
551         HcFree(authIdBuff->val);
552         authIdBuff->val = NULL;
553         DestroyDeviceEntry(deviceEntry);
554         return HC_ERR_MEMORY_COPY;
555     }
556     authIdBuff->length = authIdLen;
557     *userType = deviceEntry->devType;
558     DestroyDeviceEntry(deviceEntry);
559     return HC_SUCCESS;
560 }
561 
ComputeAndSavePsk(int32_t osAccountId,const char * groupId,const TrustedDeviceEntry * peerDeviceEntry,const Uint8Buff * sharedKeyAlias)562 static int32_t ComputeAndSavePsk(int32_t osAccountId, const char *groupId,
563     const TrustedDeviceEntry *peerDeviceEntry, const Uint8Buff *sharedKeyAlias)
564 {
565     Uint8Buff selfAuthIdBuff = { NULL, 0 };
566     int32_t selfUserType = 0;
567     int32_t ret = GetSelfAuthIdAndUserType(osAccountId, groupId, &selfAuthIdBuff, &selfUserType);
568     if (ret != HC_SUCCESS) {
569         LOGE("Failed to get self auth id and user type!");
570         return ret;
571     }
572 
573     Uint8Buff pkgNameBuff = { (uint8_t *)GROUP_MANAGER_PACKAGE_NAME, strlen(GROUP_MANAGER_PACKAGE_NAME) };
574     const char *serviceType = StringGet(&peerDeviceEntry->serviceType);
575     Uint8Buff serviceTypeBuff = { (uint8_t *)serviceType, strlen(serviceType) };
576     KeyAliasType keyType = (KeyAliasType)selfUserType;
577     uint8_t selfKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
578     Uint8Buff selfKeyAlias = { selfKeyAliasVal, PAKE_KEY_ALIAS_LEN };
579     ret = GenerateKeyAlias(&pkgNameBuff, &serviceTypeBuff, keyType, &selfAuthIdBuff, &selfKeyAlias);
580     HcFree(selfAuthIdBuff.val);
581     if (ret != HC_SUCCESS) {
582         LOGE("Failed to generate self key alias!");
583         return ret;
584     }
585 
586 #ifdef DEV_AUTH_FUNC_TEST
587     KeyAliasType keyTypePeer = KEY_ALIAS_LT_KEY_PAIR;
588 #else
589     KeyAliasType keyTypePeer = (KeyAliasType)peerDeviceEntry->devType;
590 #endif
591     const char *peerAuthId = StringGet(&peerDeviceEntry->authId);
592     Uint8Buff peerAuthIdBuff = { (uint8_t *)peerAuthId, strlen(peerAuthId) };
593     uint8_t peerKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
594     Uint8Buff peerKeyAlias = { peerKeyAliasVal, PAKE_KEY_ALIAS_LEN };
595     ret = GenerateKeyAlias(&pkgNameBuff, &serviceTypeBuff, keyTypePeer, &peerAuthIdBuff, &peerKeyAlias);
596     if (ret != HC_SUCCESS) {
597         LOGE("Failed to generate peer key alias!");
598         return ret;
599     }
600 
601     ret = GetLoaderInstance()->checkKeyExist(&selfKeyAlias);
602     if (ret != HC_SUCCESS) {
603         LOGE("self auth keyPair not exist!");
604         return ret;
605     }
606     ret = GetLoaderInstance()->checkKeyExist(&peerKeyAlias);
607     if (ret != HC_SUCCESS) {
608         LOGE("peer auth pubKey not exist!");
609         return ret;
610     }
611 
612     KeyBuff selfKeyAliasBuff = { selfKeyAlias.val, selfKeyAlias.length, true };
613     KeyBuff peerKeyAliasBuff = { peerKeyAlias.val, peerKeyAlias.length, true };
614     return GetLoaderInstance()->agreeSharedSecretWithStorage(
615         &selfKeyAliasBuff, &peerKeyAliasBuff, ED25519, PAKE_PSK_LEN, sharedKeyAlias);
616 }
617 
GeneratePskAliasAndCheckExist(const CJson * in,const char * groupId,Uint8Buff * pskKeyAlias)618 static int32_t GeneratePskAliasAndCheckExist(const CJson *in, const char *groupId, Uint8Buff *pskKeyAlias)
619 {
620     int32_t osAccountId = INVALID_OS_ACCOUNT;
621     if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
622         LOGE("Failed to get osAccountId!");
623         return HC_ERR_JSON_GET;
624     }
625     TrustedDeviceEntry *deviceEntry = CreateDeviceEntry();
626     if (deviceEntry == NULL) {
627         LOGE("Failed to create device entry!");
628         return HC_ERR_ALLOC_MEMORY;
629     }
630     int32_t ret = GetPeerDeviceEntry(osAccountId, in, groupId, deviceEntry);
631     if (ret != HC_SUCCESS) {
632         LOGE("Failed to get peer device entry!");
633         DestroyDeviceEntry(deviceEntry);
634         return ret;
635     }
636     Uint8Buff pkgNameBuff = { (uint8_t *)GROUP_MANAGER_PACKAGE_NAME, strlen(GROUP_MANAGER_PACKAGE_NAME) };
637     const char *serviceType = StringGet(&deviceEntry->serviceType);
638     Uint8Buff serviceTypeBuff = { (uint8_t *)serviceType, strlen(serviceType) };
639     const char *peerAuthId = StringGet(&deviceEntry->authId);
640     Uint8Buff peerAuthIdBuff = { (uint8_t *)peerAuthId, strlen(peerAuthId) };
641     ret = GenerateKeyAlias(&pkgNameBuff, &serviceTypeBuff, KEY_ALIAS_PSK, &peerAuthIdBuff, pskKeyAlias);
642     if (ret != HC_SUCCESS) {
643         LOGE("Failed to generate psk key alias!");
644         DestroyDeviceEntry(deviceEntry);
645         return ret;
646     }
647     LOGI("psk alias: %x %x %x %x****.", pskKeyAlias->val[DEV_AUTH_ZERO], pskKeyAlias->val[DEV_AUTH_ONE],
648         pskKeyAlias->val[DEV_AUTH_TWO], pskKeyAlias->val[DEV_AUTH_THREE]);
649     if (GetLoaderInstance()->checkKeyExist(pskKeyAlias) != HC_SUCCESS) {
650         ret = ComputeAndSavePsk(osAccountId, groupId, deviceEntry, pskKeyAlias);
651     }
652     DestroyDeviceEntry(deviceEntry);
653     return ret;
654 }
655 
GetSharedSecretForP2pInPake(const CJson * in,const char * groupId,Uint8Buff * sharedSecret)656 static int32_t GetSharedSecretForP2pInPake(const CJson *in, const char *groupId, Uint8Buff *sharedSecret)
657 {
658     uint8_t pskKeyAliasVal[PAKE_KEY_ALIAS_LEN] = { 0 };
659     Uint8Buff pskKeyAlias = { pskKeyAliasVal, PAKE_KEY_ALIAS_LEN };
660     int32_t ret = GeneratePskAliasAndCheckExist(in, groupId, &pskKeyAlias);
661     if (ret != HC_SUCCESS) {
662         LOGE("Failed to generate key alias for psk!");
663         return ret;
664     }
665     uint8_t *pskVal = (uint8_t *)HcMalloc(PAKE_PSK_LEN, 0);
666     if (pskVal == NULL) {
667         LOGE("Failed to alloc memory for psk!");
668         return HC_ERR_ALLOC_MEMORY;
669     }
670     Uint8Buff pskBuff = { pskVal, PAKE_PSK_LEN };
671     uint8_t *nonceVal = (uint8_t *)HcMalloc(PAKE_NONCE_LEN, 0);
672     if (nonceVal == NULL) {
673         LOGE("Failed to alloc memory for nonce!");
674         HcFree(pskVal);
675         return HC_ERR_ALLOC_MEMORY;
676     }
677     Uint8Buff nonceBuff = { nonceVal, PAKE_NONCE_LEN };
678     ret = GetByteFromJson(in, FIELD_NONCE, nonceBuff.val, nonceBuff.length);
679     if (ret != HC_SUCCESS) {
680         LOGE("Failed to get nonce!");
681         HcFree(pskVal);
682         HcFree(nonceVal);
683         return HC_ERR_JSON_GET;
684     }
685     Uint8Buff keyInfo = { (uint8_t *)TMP_AUTH_KEY_FACTOR, strlen(TMP_AUTH_KEY_FACTOR) };
686     ret = GetLoaderInstance()->computeHkdf(&pskKeyAlias, &nonceBuff, &keyInfo, &pskBuff, true);
687     HcFree(nonceVal);
688     if (ret != HC_SUCCESS) {
689         LOGE("Failed to compute hkdf for psk!");
690         HcFree(pskVal);
691         return ret;
692     }
693 
694     ret = ConvertPsk(&pskBuff, sharedSecret);
695     HcFree(pskVal);
696     if (ret != HC_SUCCESS) {
697         LOGE("Failed to convert psk!");
698     }
699     return ret;
700 }
701 
GetSharedSecretForP2p(const CJson * in,const CJson * urlJson,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)702 static int32_t GetSharedSecretForP2p(
703     const CJson *in, const CJson *urlJson, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
704 {
705     const char *groupId = GetStringFromJson(urlJson, FIELD_GROUP_ID);
706     if (groupId == NULL) {
707         LOGE("Failed to get groupId!");
708         return HC_ERR_JSON_GET;
709     }
710     int32_t ret;
711     if (protocolType == ALG_ISO) {
712         ret = GetSharedSecretForP2pInIso(in, groupId, sharedSecret);
713         LOGI("get shared secret for p2p in iso result: %d", ret);
714     } else {
715         ret = GetSharedSecretForP2pInPake(in, groupId, sharedSecret);
716         LOGI("get shared secret for p2p in pake result: %d", ret);
717     }
718     return ret;
719 }
720 
GetSharedSecretByUrl(const CJson * in,const Uint8Buff * presharedUrl,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)721 static int32_t GetSharedSecretByUrl(
722     const CJson *in, const Uint8Buff *presharedUrl, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
723 {
724     if (in == NULL || presharedUrl == NULL || sharedSecret == NULL) {
725         LOGE("Invalid input params!");
726         return HC_ERR_INVALID_PARAMS;
727     }
728 
729     CJson *urlJson = CreateJsonFromString((const char *)presharedUrl->val);
730     if (urlJson == NULL) {
731         LOGE("Failed to create url json!");
732         return HC_ERR_JSON_CREATE;
733     }
734 
735     int32_t trustType = 0;
736     if (GetIntFromJson(urlJson, PRESHARED_URL_TRUST_TYPE, &trustType) != HC_SUCCESS) {
737         LOGE("Failed to get trust type!");
738         FreeJson(urlJson);
739         return HC_ERR_JSON_GET;
740     }
741 
742     int32_t ret;
743     switch (trustType) {
744         case TRUST_TYPE_P2P:
745             ret = GetSharedSecretForP2p(in, urlJson, protocolType, sharedSecret);
746             break;
747         case TRUST_TYPE_UID:
748             if (protocolType != ALG_ISO) {
749                 LOGE("protocol type is not iso, not supported!");
750                 ret = HC_ERR_INVALID_PARAMS;
751             } else {
752                 ret = GetAccountSymSharedSecret(in, urlJson, sharedSecret);
753             }
754             break;
755         default:
756             LOGE("Invalid trust type!");
757             ret = HC_ERR_INVALID_PARAMS;
758             break;
759     }
760     FreeJson(urlJson);
761 
762     return ret;
763 }
764 
GetCredInfoByPeerCert(const CJson * in,const CertInfo * certInfo,IdentityInfo ** returnInfo)765 static int32_t GetCredInfoByPeerCert(const CJson *in, const CertInfo *certInfo, IdentityInfo **returnInfo)
766 {
767     if (in == NULL || certInfo == NULL || returnInfo == NULL) {
768         LOGE("Invalid input params!");
769         return HC_ERR_INVALID_PARAMS;
770     }
771     int32_t osAccountId = INVALID_OS_ACCOUNT;
772     if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
773         LOGE("Failed to get osAccountId!");
774         return HC_ERR_JSON_GET;
775     }
776     int32_t res = GetAccountAsymCredInfo(osAccountId, certInfo, returnInfo);
777     if (res != HC_SUCCESS) {
778         LOGE("Failed to get account asym cred info!");
779         return res;
780     }
781     if (certInfo->isPseudonym) {
782         (*returnInfo)->proof.certInfo.isPseudonym = true;
783     } else {
784         (*returnInfo)->proof.certInfo.isPseudonym = false;
785     }
786     return HC_SUCCESS;
787 }
788 
GetSharedSecretByPeerCert(const CJson * in,const CertInfo * peerCertInfo,ProtocolAlgType protocolType,Uint8Buff * sharedSecret)789 static int32_t GetSharedSecretByPeerCert(
790     const CJson *in, const CertInfo *peerCertInfo, ProtocolAlgType protocolType, Uint8Buff *sharedSecret)
791 {
792     if (in == NULL || peerCertInfo == NULL || sharedSecret == NULL) {
793         LOGE("Invalid input params!");
794         return HC_ERR_INVALID_PARAMS;
795     }
796     if (protocolType != ALG_EC_SPEKE) {
797         LOGE("protocol type is not ec speke, not support!");
798         return HC_ERR_INVALID_PARAMS;
799     }
800     int32_t osAccountId = INVALID_OS_ACCOUNT;
801     if (GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
802         LOGE("Failed to get osAccountId!");
803         return HC_ERR_JSON_GET;
804     }
805     return GetAccountAsymSharedSecret(osAccountId, peerCertInfo, sharedSecret);
806 }
807 
808 static const AuthIdentity g_authIdentity = {
809     .getCredInfosByPeerIdentity = GetCredInfosByPeerIdentity,
810     .getCredInfoByPeerUrl = GetCredInfoByPeerUrl,
811     .getSharedSecretByUrl = GetSharedSecretByUrl,
812     .getCredInfoByPeerCert = GetCredInfoByPeerCert,
813     .getSharedSecretByPeerCert = GetSharedSecretByPeerCert,
814 };
815 
GetGroupAuthIdentity(void)816 const AuthIdentity *GetGroupAuthIdentity(void)
817 {
818     return &g_authIdentity;
819 }