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 "dev_session_util.h"
17 
18 #include "alg_loader.h"
19 #include "hc_log.h"
20 #include "pseudonym_manager.h"
21 
22 #define AUTH_ID_LEN 32
23 #define FIELD_AUTH_ID_CLIENT "authIdC"
24 #define FIELD_AUTH_ID_SERVER "authIdS"
25 
GetPeerDeviceEntryByContext(int32_t osAccountId,const CJson * context)26 static TrustedDeviceEntry *GetPeerDeviceEntryByContext(int32_t osAccountId, const CJson *context)
27 {
28     const char *groupId = GetStringFromJson(context, FIELD_GROUP_ID);
29     if (groupId == NULL) {
30         LOGE("Failed to get groupId!");
31         return NULL;
32     }
33     bool isUdid = false;
34     const char *peerDeviceId = GetStringFromJson(context, FIELD_PEER_UDID);
35     if (peerDeviceId != NULL) {
36         isUdid = true;
37     } else {
38         LOGW("peer udid not found, try to get peer authId!");
39         peerDeviceId = GetStringFromJson(context, FIELD_PEER_AUTH_ID);
40         if (peerDeviceId == NULL) {
41             LOGE("Failed to get peer authId!");
42             return NULL;
43         }
44     }
45     return GetDeviceEntryById(osAccountId, peerDeviceId, isUdid, groupId);
46 }
47 
GetPdidByContext(const CJson * context,char ** returnPdid)48 static int32_t GetPdidByContext(const CJson *context, char **returnPdid)
49 {
50     int32_t osAccountId;
51     if (GetIntFromJson(context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
52         LOGE("Failed to get osAccountId!");
53         return HC_ERR_JSON_GET;
54     }
55     TrustedDeviceEntry *deviceEntry = GetPeerDeviceEntryByContext(osAccountId, context);
56     if (deviceEntry == NULL) {
57         LOGE("Failed to get device entry!");
58         return HC_ERR_DEVICE_NOT_EXIST;
59     }
60     const char *userId = StringGet(&deviceEntry->userId);
61     if (userId == NULL) {
62         LOGE("userId is null!");
63         DestroyDeviceEntry(deviceEntry);
64         return HC_ERR_NULL_PTR;
65     }
66     PseudonymManager *manager = GetPseudonymInstance();
67     if (manager == NULL) {
68         LOGE("Pseudonym manager is null!");
69         DestroyDeviceEntry(deviceEntry);
70         return HC_ERR_NULL_PTR;
71     }
72     char *pdid = NULL;
73     int32_t res = manager->getPseudonymId(osAccountId, userId, &pdid);
74     DestroyDeviceEntry(deviceEntry);
75     if (res != HC_SUCCESS) {
76         LOGE("Failed to get pdid!");
77         return res;
78     }
79     if (DeepCopyString(pdid, returnPdid) != HC_SUCCESS) {
80         LOGE("Failed to copy pdid!");
81         HcFree(pdid);
82         return HC_ERR_ALLOC_MEMORY;
83     }
84     HcFree(pdid);
85     return HC_SUCCESS;
86 }
87 
BuildRealPkInfoJson(const CJson * pkInfoJson,const CJson * peerInfoJson,CJson * realPkInfoJson)88 static int32_t BuildRealPkInfoJson(const CJson *pkInfoJson, const CJson *peerInfoJson, CJson *realPkInfoJson)
89 {
90     const char *devicePk = GetStringFromJson(pkInfoJson, FIELD_DEVICE_PK);
91     if (devicePk == NULL) {
92         LOGE("Failed to get devicePk!");
93         return HC_ERR_JSON_GET;
94     }
95     const char *version = GetStringFromJson(pkInfoJson, FIELD_VERSION);
96     if (version == NULL) {
97         LOGE("Failed to get version!");
98         return HC_ERR_JSON_GET;
99     }
100     const char *userId = GetStringFromJson(peerInfoJson, FIELD_USER_ID);
101     if (userId == NULL) {
102         LOGE("Failed to get userId!");
103         return HC_ERR_JSON_GET;
104     }
105     const char *deviceId = GetStringFromJson(peerInfoJson, FIELD_DEVICE_ID);
106     if (deviceId == NULL) {
107         LOGE("Failed to get deviceId!");
108         return HC_ERR_JSON_GET;
109     }
110     if (AddStringToJson(realPkInfoJson, FIELD_DEVICE_PK, devicePk) != HC_SUCCESS) {
111         LOGE("Failed to add devicePk!");
112         return HC_ERR_JSON_ADD;
113     }
114     if (AddStringToJson(realPkInfoJson, FIELD_USER_ID, userId) != HC_SUCCESS) {
115         LOGE("Failed to add userId!");
116         return HC_ERR_JSON_ADD;
117     }
118     if (AddStringToJson(realPkInfoJson, FIELD_DEVICE_ID, deviceId) != HC_SUCCESS) {
119         LOGE("Failed to add deviceId!");
120         return HC_ERR_JSON_ADD;
121     }
122     if (AddStringToJson(realPkInfoJson, FIELD_VERSION, version) != HC_SUCCESS) {
123         LOGE("Failed to add version!");
124         return HC_ERR_JSON_ADD;
125     }
126     return HC_SUCCESS;
127 }
128 
GetRealPkInfoJson(int32_t osAccountId,CJson * pkInfoJson,CJson ** realPkInfoJson)129 static int32_t GetRealPkInfoJson(int32_t osAccountId, CJson *pkInfoJson, CJson **realPkInfoJson)
130 {
131     const char *pdid = GetStringFromJson(pkInfoJson, FIELD_PSEUDONYM_ID);
132     if (pdid == NULL) {
133         LOGE("Failed to get pdid!");
134         return HC_ERR_JSON_GET;
135     }
136     PseudonymManager *manager = GetPseudonymInstance();
137     if (manager == NULL) {
138         LOGE("Pseudonym manager is null!");
139         return HC_ERR_NULL_PTR;
140     }
141     char *peerInfo = NULL;
142     int32_t res = manager->getRealInfo(osAccountId, pdid, &peerInfo);
143     if (res != HC_SUCCESS) {
144         LOGE("Failed to get peerInfo!");
145         return res;
146     }
147     CJson *peerInfoJson = CreateJsonFromString(peerInfo);
148     HcFree(peerInfo);
149     if (peerInfoJson == NULL) {
150         LOGE("Failed to create peerInfo json!");
151         return HC_ERR_JSON_CREATE;
152     }
153     *realPkInfoJson = CreateJson();
154     if (*realPkInfoJson == NULL) {
155         LOGE("Failed to create real pkInfo json!");
156         FreeJson(peerInfoJson);
157         return HC_ERR_JSON_CREATE;
158     }
159     res = BuildRealPkInfoJson(pkInfoJson, peerInfoJson, *realPkInfoJson);
160     FreeJson(peerInfoJson);
161     if (res != HC_SUCCESS) {
162         LOGE("Failed to build real pkInfo json!");
163         FreeJson(*realPkInfoJson);
164         *realPkInfoJson = NULL;
165     }
166     return res;
167 }
168 
GeneratePeerInfoJson(const CJson * pkInfoJson,CJson ** peerInfoJson)169 static int32_t GeneratePeerInfoJson(const CJson *pkInfoJson, CJson **peerInfoJson)
170 {
171     const char *userId = GetStringFromJson(pkInfoJson, FIELD_USER_ID);
172     if (userId == NULL) {
173         LOGE("Failed to get userId!");
174         return HC_ERR_JSON_GET;
175     }
176     const char *devId = GetStringFromJson(pkInfoJson, FIELD_DEVICE_ID);
177     if (devId == NULL) {
178         LOGE("Failed to get devId!");
179         return HC_ERR_JSON_GET;
180     }
181     *peerInfoJson = CreateJson();
182     if (*peerInfoJson == NULL) {
183         LOGE("Failed to create peerInfo json!");
184         return HC_ERR_JSON_CREATE;
185     }
186     if (AddStringToJson(*peerInfoJson, FIELD_USER_ID, userId) != HC_SUCCESS) {
187         LOGE("Failed to add userId!");
188         FreeJson(*peerInfoJson);
189         *peerInfoJson = NULL;
190         return HC_ERR_JSON_ADD;
191     }
192     if (AddStringToJson(*peerInfoJson, FIELD_DEVICE_ID, devId) != HC_SUCCESS) {
193         LOGE("Failed to add devId!");
194         FreeJson(*peerInfoJson);
195         *peerInfoJson = NULL;
196         return HC_ERR_JSON_ADD;
197     }
198     return HC_SUCCESS;
199 }
200 
IsPeerPseudonym(const CJson * inputData)201 static bool IsPeerPseudonym(const CJson *inputData)
202 {
203     const char *pkInfoStr = GetStringFromJson(inputData, FIELD_PK_INFO);
204     if (pkInfoStr == NULL) {
205         LOGE("Failed to get peer pkInfo!");
206         return false;
207     }
208     CJson *pkInfoJson = CreateJsonFromString(pkInfoStr);
209     if (pkInfoJson == NULL) {
210         LOGE("Failed to create pkInfo json!");
211         return false;
212     }
213     bool res = GetStringFromJson(pkInfoJson, FIELD_PSEUDONYM_ID) != NULL;
214     FreeJson(pkInfoJson);
215     return res;
216 }
217 
SetPeerAuthIdByDb(CJson * context,const char * groupId)218 static int32_t SetPeerAuthIdByDb(CJson *context, const char *groupId)
219 {
220     int32_t osAccountId;
221     if (GetIntFromJson(context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
222         LOGE("Failed to get osAccountId!");
223         return HC_ERR_JSON_GET;
224     }
225     const char *peerUdid = GetStringFromJson(context, FIELD_PEER_UDID);
226     if (peerUdid == NULL) {
227         LOGE("Failed to get peer udid!");
228         return HC_ERR_JSON_GET;
229     }
230     TrustedDeviceEntry *entry = GetDeviceEntryById(osAccountId, peerUdid, true, groupId);
231     if (entry == NULL) {
232         LOGE("Failed to get device entry!");
233         return HC_ERR_DEVICE_NOT_EXIST;
234     }
235     const char *peerAuthId = StringGet(&entry->authId);
236     if (AddStringToJson(context, FIELD_PEER_AUTH_ID, peerAuthId) != HC_SUCCESS) {
237         LOGE("Failed to add peer authId to context!");
238         DestroyDeviceEntry(entry);
239         return HC_ERR_JSON_ADD;
240     }
241     DestroyDeviceEntry(entry);
242     return HC_SUCCESS;
243 }
244 
FillPeerAuthIdIfNeeded(bool isClient,const CJson * context,CJson * inputData)245 int32_t FillPeerAuthIdIfNeeded(bool isClient, const CJson *context, CJson *inputData)
246 {
247     const char *peerAuthId = GetStringFromJson(context, FIELD_PEER_AUTH_ID);
248     if (peerAuthId == NULL) {
249         LOGI("no peer authId in context, no need to fill!");
250         return HC_SUCCESS;
251     }
252     CJson *authData = GetObjFromJson(inputData, FIELD_AUTH_DATA);
253     if (authData == NULL) {
254         LOGE("Failed to get authData!");
255         return HC_ERR_JSON_GET;
256     }
257     Uint8Buff authIdBuff = { (uint8_t *)peerAuthId, HcStrlen(peerAuthId) + 1 };
258     if (isClient && GetStringFromJson(authData, FIELD_AUTH_ID_SERVER) != NULL) {
259         if (AddByteToJson(authData, FIELD_AUTH_ID_SERVER, authIdBuff.val, authIdBuff.length) != HC_SUCCESS) {
260             LOGE("Failed to fill server authId!");
261             return HC_ERR_JSON_ADD;
262         }
263         return HC_SUCCESS;
264     }
265     if (!isClient && GetStringFromJson(authData, FIELD_AUTH_ID_CLIENT) != NULL) {
266         if (AddByteToJson(authData, FIELD_AUTH_ID_CLIENT, authIdBuff.val, authIdBuff.length) != HC_SUCCESS) {
267             LOGE("Failed to fill client authId!");
268             return HC_ERR_JSON_ADD;
269         }
270         return HC_SUCCESS;
271     }
272     return HC_SUCCESS;
273 }
274 
IsP2pAuth(const IdentityInfo * info)275 bool IsP2pAuth(const IdentityInfo *info)
276 {
277     if (info->proofType == CERTIFICATED) {
278         return false;
279     }
280     CJson *urlJson = CreateJsonFromString((const char *)info->proof.preSharedUrl.val);
281     if (urlJson == NULL) {
282         LOGE("Failed to create urlJson!");
283         return false;
284     }
285     int32_t trustType = 0;
286     if (GetIntFromJson(urlJson, PRESHARED_URL_TRUST_TYPE, &trustType) != HC_SUCCESS) {
287         LOGE("Failed to get trust type!");
288         FreeJson(urlJson);
289         return false;
290     }
291     FreeJson(urlJson);
292     return trustType == TRUST_TYPE_P2P;
293 }
294 
SetPeerAuthIdToContextIfNeeded(CJson * context,const IdentityInfo * info)295 int32_t SetPeerAuthIdToContextIfNeeded(CJson *context, const IdentityInfo *info)
296 {
297     if (!IsP2pAuth(info)) {
298         LOGI("Not p2p auth, no need to set peer authId!");
299         return HC_SUCCESS;
300     }
301     /* auth with credentials directly no need set peer auth id here */
302     bool isDirectAuth = false;
303     (void)GetBoolFromJson(context, FIELD_IS_DIRECT_AUTH, &isDirectAuth);
304     if (isDirectAuth) {
305         return HC_SUCCESS;
306     }
307     CJson *urlJson = CreateJsonFromString((const char *)info->proof.preSharedUrl.val);
308     if (urlJson == NULL) {
309         LOGE("Failed to create urlJson!");
310         return HC_ERR_JSON_CREATE;
311     }
312     const char *groupId = GetStringFromJson(urlJson, FIELD_GROUP_ID);
313     if (groupId == NULL) {
314         LOGE("Failed to get groupId!");
315         FreeJson(urlJson);
316         return HC_ERR_JSON_GET;
317     }
318     int32_t res = SetPeerAuthIdByDb(context, groupId);
319     FreeJson(urlJson);
320     return res;
321 }
322 
SetPeerInfoToContext(CJson * context,const CJson * inputData)323 int32_t SetPeerInfoToContext(CJson *context, const CJson *inputData)
324 {
325     if (IsPeerPseudonym(inputData)) {
326         LOGI("Peer is pseudonym, no need to set peerInfo!");
327         return HC_SUCCESS;
328     }
329     const char *pkInfoStr = GetStringFromJson(inputData, FIELD_PK_INFO);
330     if (pkInfoStr == NULL) {
331         LOGE("Failed to get peer pkInfo!");
332         return HC_ERR_JSON_GET;
333     }
334     CJson *pkInfoJson = CreateJsonFromString(pkInfoStr);
335     if (pkInfoJson == NULL) {
336         LOGE("Failed to create pkInfo json!");
337         return HC_ERR_JSON_CREATE;
338     }
339     const char *userId = GetStringFromJson(pkInfoJson, FIELD_USER_ID);
340     if (userId == NULL) {
341         LOGE("Failed to get userId!");
342         FreeJson(pkInfoJson);
343         return HC_ERR_JSON_GET;
344     }
345     if (AddStringToJson(context, FIELD_INDEX_KEY, userId) != HC_SUCCESS) {
346         LOGE("Failed to add pdidIndex!");
347         FreeJson(pkInfoJson);
348         return HC_ERR_JSON_ADD;
349     }
350     CJson *peerInfoJson = NULL;
351     int32_t res = GeneratePeerInfoJson(pkInfoJson, &peerInfoJson);
352     FreeJson(pkInfoJson);
353     if (res != HC_SUCCESS) {
354         LOGE("Failed to generate peerInfo json!");
355         return res;
356     }
357     char *peerInfoStr = PackJsonToString(peerInfoJson);
358     FreeJson(peerInfoJson);
359     if (peerInfoStr == NULL) {
360         LOGE("Failed to convert peerInfo from json to string!");
361         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
362     }
363     if (AddStringToJson(context, FIELD_REAL_INFO, peerInfoStr) != HC_SUCCESS) {
364         LOGE("Failed to add peerInfo to context!");
365         FreeJsonString(peerInfoStr);
366         return HC_ERR_JSON_ADD;
367     }
368     FreeJsonString(peerInfoStr);
369     return HC_SUCCESS;
370 }
371 
ReplaceAuthIdWithRandom(CJson * authData)372 int32_t ReplaceAuthIdWithRandom(CJson *authData)
373 {
374     uint8_t authId[AUTH_ID_LEN] = { 0 };
375     Uint8Buff authIdBuff = { authId, AUTH_ID_LEN };
376     int32_t res = GetLoaderInstance()->generateRandom(&authIdBuff);
377     if (res != HC_SUCCESS) {
378         LOGI("Failed to generate random authId!");
379         return res;
380     }
381     if (GetStringFromJson(authData, FIELD_AUTH_ID_CLIENT) != NULL &&
382         AddByteToJson(authData, FIELD_AUTH_ID_CLIENT, authIdBuff.val, authIdBuff.length) != HC_SUCCESS) {
383         LOGE("Failed to replace client authId with random!");
384         return HC_ERR_JSON_ADD;
385     }
386     if (GetStringFromJson(authData, FIELD_AUTH_ID_SERVER) != NULL &&
387         AddByteToJson(authData, FIELD_AUTH_ID_SERVER, authIdBuff.val, authIdBuff.length) != HC_SUCCESS) {
388         LOGE("Failed to replace server authId with random!");
389         return HC_ERR_JSON_ADD;
390     }
391     return HC_SUCCESS;
392 }
393 
CheckPeerPkInfoForPdid(const CJson * context,const CJson * inputData)394 int32_t CheckPeerPkInfoForPdid(const CJson *context, const CJson *inputData)
395 {
396     int32_t osAccountId;
397     if (GetIntFromJson(context, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
398         LOGE("Failed to get osAccountId!");
399         return HC_ERR_JSON_GET;
400     }
401     const char *pkInfo = GetStringFromJson(inputData, FIELD_PK_INFO);
402     if (pkInfo == NULL) {
403         LOGE("Failed to get pkInfo!");
404         return HC_ERR_JSON_GET;
405     }
406     CJson *pkInfoJson = CreateJsonFromString(pkInfo);
407     if (pkInfoJson == NULL) {
408         LOGE("Failed to create pkInfo json!");
409         return HC_ERR_JSON_CREATE;
410     }
411     const char *pdid = GetStringFromJson(pkInfoJson, FIELD_PSEUDONYM_ID);
412     if (pdid == NULL) {
413         LOGI("No pdid in peer pkInfo, check success!");
414         FreeJson(pkInfoJson);
415         return HC_SUCCESS;
416     }
417     PseudonymManager *manager = GetPseudonymInstance();
418     if (manager == NULL) {
419         LOGE("Pseudonym manager is null!");
420         FreeJson(pkInfoJson);
421         return HC_ERR_NULL_PTR;
422     }
423     char *peerInfo = NULL;
424     int32_t res = manager->getRealInfo(osAccountId, pdid, &peerInfo);
425     FreeJson(pkInfoJson);
426     if (res != HC_SUCCESS) {
427         LOGE("Can not get peerInfo with pdid, check fail!");
428         return res;
429     }
430     HcFree(peerInfo);
431     return HC_SUCCESS;
432 }
433 
GetRealPkInfoStr(int32_t osAccountId,const CJson * credInfo,char ** returnPkInfoStr,bool * isPseudonym)434 int32_t GetRealPkInfoStr(int32_t osAccountId, const CJson *credInfo, char **returnPkInfoStr, bool *isPseudonym)
435 {
436     const char *pkInfoStr = GetStringFromJson(credInfo, FIELD_PK_INFO);
437     if (pkInfoStr == NULL) {
438         LOGE("Failed to get pkInfo!");
439         return HC_ERR_JSON_GET;
440     }
441     CJson *pkInfoJson = CreateJsonFromString(pkInfoStr);
442     if (pkInfoJson == NULL) {
443         LOGE("Failed to create pkInfo json!");
444         return HC_ERR_JSON_CREATE;
445     }
446     CJson *realPkInfoJson = NULL;
447     int32_t res = GetRealPkInfoJson(osAccountId, pkInfoJson, &realPkInfoJson);
448     FreeJson(pkInfoJson);
449     if (res != HC_SUCCESS) {
450         LOGW("Failed to get real pkInfo json!");
451         if (DeepCopyString(pkInfoStr, returnPkInfoStr) != HC_SUCCESS) {
452             LOGE("Failed to copy pkInfoStr!");
453             return HC_ERR_ALLOC_MEMORY;
454         }
455         *isPseudonym = false;
456         return HC_SUCCESS;
457     } else {
458         LOGI("Get real pkInfo json successfully!");
459         char *realPkInfoStr = PackJsonToString(realPkInfoJson);
460         FreeJson(realPkInfoJson);
461         if (realPkInfoStr == NULL) {
462             LOGE("Failed to convert pkInfo from json to string!");
463             return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
464         }
465         res = DeepCopyString(realPkInfoStr, returnPkInfoStr);
466         FreeJsonString(realPkInfoStr);
467         if (res != HC_SUCCESS) {
468             LOGE("Failed to copy realPkInfoStr!");
469             return HC_ERR_ALLOC_MEMORY;
470         }
471         *isPseudonym = true;
472         return HC_SUCCESS;
473     }
474 }
475 
AddPkInfoWithPdid(const CJson * context,CJson * credInfo,const char * realPkInfoStr)476 int32_t AddPkInfoWithPdid(const CJson *context, CJson *credInfo, const char *realPkInfoStr)
477 {
478     if (context == NULL || credInfo == NULL || realPkInfoStr == NULL) {
479         LOGE("Invalid input params!");
480         return HC_ERR_INVALID_PARAMS;
481     }
482     char *pdid = NULL;
483     int32_t res = GetPdidByContext(context, &pdid);
484     if (res != HC_SUCCESS) {
485         LOGE("Failed to get pdid by context!");
486         return res;
487     }
488     CJson *pkInfoJson = CreateJsonFromString(realPkInfoStr);
489     if (pkInfoJson == NULL) {
490         LOGE("Failed to create pkInfo json!");
491         HcFree(pdid);
492         return HC_ERR_JSON_CREATE;
493     }
494     DeleteItemFromJson(pkInfoJson, FIELD_USER_ID);
495     DeleteItemFromJson(pkInfoJson, FIELD_DEVICE_ID);
496     if (AddStringToJson(pkInfoJson, FIELD_PSEUDONYM_ID, pdid) != HC_SUCCESS) {
497         LOGE("Failed to add pdid to pkInfo!");
498         HcFree(pdid);
499         FreeJson(pkInfoJson);
500         return HC_ERR_JSON_ADD;
501     }
502     HcFree(pdid);
503     char *pkInfoWithPdid = PackJsonToString(pkInfoJson);
504     FreeJson(pkInfoJson);
505     if (pkInfoWithPdid == NULL) {
506         LOGE("Failed to convert pkInfo from json to string!");
507         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
508     }
509     if (AddStringToJson(credInfo, FIELD_PK_INFO, pkInfoWithPdid) != HC_SUCCESS) {
510         LOGE("Failed to add pkInfo with pdid!");
511         FreeJsonString(pkInfoWithPdid);
512         return HC_ERR_JSON_ADD;
513     }
514     FreeJsonString(pkInfoWithPdid);
515     return HC_SUCCESS;
516 }
517 
GetDeviceEntryById(int32_t osAccountId,const char * deviceId,bool isUdid,const char * groupId)518 TrustedDeviceEntry *GetDeviceEntryById(int32_t osAccountId, const char *deviceId, bool isUdid,
519     const char *groupId)
520 {
521     DeviceEntryVec deviceEntryVec = CreateDeviceEntryVec();
522     QueryDeviceParams params = InitQueryDeviceParams();
523     params.groupId = groupId;
524     if (isUdid) {
525         params.udid = deviceId;
526     } else {
527         params.authId = deviceId;
528     }
529     if (QueryDevices(osAccountId, &params, &deviceEntryVec) != HC_SUCCESS) {
530         LOGE("Failed to query trusted devices!");
531         ClearDeviceEntryVec(&deviceEntryVec);
532         return NULL;
533     }
534     uint32_t index;
535     TrustedDeviceEntry **deviceEntry;
536     FOR_EACH_HC_VECTOR(deviceEntryVec, index, deviceEntry) {
537         TrustedDeviceEntry *returnEntry = DeepCopyDeviceEntry(*deviceEntry);
538         ClearDeviceEntryVec(&deviceEntryVec);
539         return returnEntry;
540     }
541     ClearDeviceEntryVec(&deviceEntryVec);
542     return NULL;
543 }