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 "pseudonym_manager.h"
17 
18 #include "string_util.h"
19 #include "hc_dev_info.h"
20 #include "hc_file.h"
21 #include "hc_log.h"
22 #include "hc_mutex.h"
23 #include "hc_time.h"
24 #include "hc_types.h"
25 #include "hc_vector.h"
26 #include "os_account_adapter.h"
27 #include "security_label_adapter.h"
28 
29 #define MAX_REFRESH_COUNT 1000
30 #define MAX_REFRESH_TIME 86400
31 #define MAX_DB_PATH_LEN 256
32 typedef struct {
33     char *pseudonymId;
34     char *indexKey;
35     char *realInfo;
36     char *deviceId;
37     int32_t refreshCount;
38     int64_t startTime;
39 } PseudonymInfo;
40 
41 DECLARE_HC_VECTOR(PseudonymInfoVec, PseudonymInfo*);
42 IMPLEMENT_HC_VECTOR(PseudonymInfoVec, PseudonymInfo*, 1);
43 
44 typedef struct {
45     int32_t osAccountId;
46     PseudonymInfoVec pseudonymInfoVec;
47 } OsAccountPseudonymInfo;
48 
49 DECLARE_HC_VECTOR(PseudonymDb, OsAccountPseudonymInfo)
50 IMPLEMENT_HC_VECTOR(PseudonymDb, OsAccountPseudonymInfo, 1)
51 
52 static PseudonymDb g_pseudonymDb;
53 static HcMutex *g_mutex = NULL;
54 static bool g_isInitial = false;
55 
DestroyPseudonymInfo(PseudonymInfo * pseudonymInfo)56 void DestroyPseudonymInfo(PseudonymInfo *pseudonymInfo)
57 {
58     if (pseudonymInfo == NULL) {
59         LOGE("Input pseudonymInfo is null");
60         return;
61     }
62     HcFree(pseudonymInfo->pseudonymId);
63     HcFree(pseudonymInfo->realInfo);
64     HcFree(pseudonymInfo->deviceId);
65     HcFree(pseudonymInfo->indexKey);
66     HcFree(pseudonymInfo);
67 }
68 
ClearPseudonymInfoVec(PseudonymInfoVec * vec)69 void ClearPseudonymInfoVec(PseudonymInfoVec *vec)
70 {
71     uint32_t index;
72     PseudonymInfo **pseudonymInfoEntry;
73     FOR_EACH_HC_VECTOR(*vec, index, pseudonymInfoEntry) {
74         DestroyPseudonymInfo(*pseudonymInfoEntry);
75     }
76     DestroyPseudonymInfoVec(vec);
77 }
78 
QueryPseudonymInfoPtrIfMatch(const PseudonymInfoVec * vec,const char * realInfo)79 static PseudonymInfo **QueryPseudonymInfoPtrIfMatch(const PseudonymInfoVec *vec, const char *realInfo)
80 {
81     if (realInfo == NULL) {
82         LOGE("Invalid input realInfo.");
83         return NULL;
84     }
85     uint32_t index;
86     PseudonymInfo **pseudonymInfo;
87     FOR_EACH_HC_VECTOR(*vec, index, pseudonymInfo) {
88         if (strcmp(realInfo, (*pseudonymInfo)->realInfo) == 0) {
89             return pseudonymInfo;
90         }
91     }
92     return NULL;
93 }
94 
CreatePseudonymInfo(void)95 PseudonymInfo *CreatePseudonymInfo(void)
96 {
97     PseudonymInfo *pseudonymInfo = (PseudonymInfo *)HcMalloc(sizeof(PseudonymInfo), 0);
98     if (pseudonymInfo == NULL) {
99         LOGE("Failed to allocate pseudonymInfo memory!");
100         return NULL;
101     }
102     pseudonymInfo->pseudonymId = NULL;
103     pseudonymInfo->indexKey = NULL;
104     pseudonymInfo->realInfo = NULL;
105     pseudonymInfo->deviceId = NULL;
106     pseudonymInfo->refreshCount = MAX_REFRESH_COUNT;
107     pseudonymInfo->startTime = HcGetCurTime();
108     return pseudonymInfo;
109 }
110 
GeneratePseudonymInfoFromJson(const CJson * pseudonymJson,PseudonymInfo * pseudonymInfoEntry)111 static int32_t GeneratePseudonymInfoFromJson(const CJson *pseudonymJson, PseudonymInfo *pseudonymInfoEntry)
112 {
113     const char *pseudonymId = GetStringFromJson(pseudonymJson, FIELD_PSEUDONYM_ID);
114     if (pseudonymId == NULL) {
115         LOGE("Failed to get pseudonymId");
116         return HC_ERR_JSON_GET;
117     }
118     GOTO_IF_ERR(DeepCopyString(pseudonymId, &pseudonymInfoEntry->pseudonymId));
119 
120     const char *indexKey = GetStringFromJson(pseudonymJson, FIELD_INDEX_KEY);
121     if (indexKey == NULL) {
122         LOGE("Failed to get indexKey");
123         return HC_ERR_JSON_GET;
124     }
125     GOTO_IF_ERR(DeepCopyString(indexKey, &pseudonymInfoEntry->indexKey));
126 
127     const char *realInfo = GetStringFromJson(pseudonymJson, FIELD_REAL_INFO);
128     if (realInfo == NULL) {
129         LOGE("Failed to get realInfo");
130         return HC_ERR_JSON_GET;
131     }
132     GOTO_IF_ERR(DeepCopyString(realInfo, &pseudonymInfoEntry->realInfo));
133 
134     const char *deviceId = GetStringFromJson(pseudonymJson, FIELD_DEVICE_ID);
135     if (deviceId == NULL) {
136         LOGE("Failed to get deviceId");
137         return HC_ERR_JSON_GET;
138     }
139     GOTO_IF_ERR(DeepCopyString(deviceId, &pseudonymInfoEntry->deviceId));
140 
141     pseudonymInfoEntry->refreshCount = 0;
142     pseudonymInfoEntry->startTime = 0;
143     return HC_SUCCESS;
144 ERR:
145     LOGE("Failed to copy string");
146     return HC_ERR_MEMORY_COPY;
147 }
148 
CreatePseudonymFromJson(CJson * pseudonymJson,PseudonymInfoVec * vec)149 static int32_t CreatePseudonymFromJson(CJson *pseudonymJson, PseudonymInfoVec *vec)
150 {
151     int32_t num = GetItemNum(pseudonymJson);
152     if (num <= 0) {
153         LOGE("No pseudonym info found.");
154         return HC_ERR_JSON_GET;
155     }
156     int32_t ret;
157     for (int32_t i = 0; i < num; i++) {
158         CJson *pseudonymEntryJson = GetItemFromArray(pseudonymJson, i);
159         if (pseudonymEntryJson == NULL) {
160             LOGE("pseudonym entry json is null");
161             return HC_ERR_JSON_GET;
162         }
163         PseudonymInfo *pseudonymInfo = CreatePseudonymInfo();
164         if (pseudonymInfo == NULL) {
165             LOGE("Failed to create pseudonymInfo");
166             return HC_ERR_ALLOC_MEMORY;
167         }
168         ret = GeneratePseudonymInfoFromJson(pseudonymEntryJson, pseudonymInfo);
169         if (ret != HC_SUCCESS) {
170             LOGE("Generate pseudonymInfo failed");
171             DestroyPseudonymInfo(pseudonymInfo);
172             return ret;
173         }
174         if (vec->pushBackT(vec, pseudonymInfo) == NULL) {
175             LOGE("Failed to push pseudonymInfo to vec");
176             DestroyPseudonymInfo(pseudonymInfo);
177             return HC_ERR_MEMORY_COPY;
178         }
179     }
180     return HC_SUCCESS;
181 }
182 
GetPseudonymPathCe(int32_t osAccountId,char * path,uint32_t pathBufferLen)183 static bool GetPseudonymPathCe(int32_t osAccountId, char *path, uint32_t pathBufferLen)
184 {
185     const char *beginPath = GetStorageDirPathCe();
186     if (beginPath == NULL) {
187         LOGE("Failed to get the storage path!");
188         return false;
189     }
190     if (sprintf_s(path, pathBufferLen, "%s/%d/deviceauth/pseudonym/pseudonym_data.dat", beginPath, osAccountId) <= 0) {
191         LOGE("Failed to generate pseudonym path!");
192         return false;
193     }
194     return true;
195 }
196 
GetPseudonymPathDe(int32_t osAccountId,char * path,uint32_t pathBufferLen)197 static bool GetPseudonymPathDe(int32_t osAccountId, char *path, uint32_t pathBufferLen)
198 {
199     const char *beginPath = GetPseudonymStoragePath();
200     if (beginPath == NULL) {
201         LOGE("Failed to get the pseudonym storage path!");
202         return false;
203     }
204     int32_t writeByteNum;
205     if (osAccountId == DEFAULT_OS_ACCOUNT) {
206         writeByteNum = sprintf_s(path, pathBufferLen, "%s/pseudonym_data.dat", beginPath);
207     } else {
208         writeByteNum = sprintf_s(path, pathBufferLen, "%s/pseudonym_data%d.dat", beginPath, osAccountId);
209     }
210     if (writeByteNum <= 0) {
211         LOGE("sprintf_s fail!");
212         return false;
213     }
214     return true;
215 }
216 
GetPseudonymPath(int32_t osAccountId,char * path,uint32_t pathBufferLen)217 static bool GetPseudonymPath(int32_t osAccountId, char *path, uint32_t pathBufferLen)
218 {
219     if (IsOsAccountSupported()) {
220         return GetPseudonymPathCe(osAccountId, path, pathBufferLen);
221     } else {
222         return GetPseudonymPathDe(osAccountId, path, pathBufferLen);
223     }
224 }
225 
OpenPseudonymFile(int32_t osAccountId,FileHandle * file,int32_t mode)226 static int32_t OpenPseudonymFile(int32_t osAccountId, FileHandle *file, int32_t mode)
227 {
228     char *pseudonymPath = (char *)HcMalloc(MAX_DB_PATH_LEN, 0);
229     if (pseudonymPath == NULL) {
230         LOGE("Malloc pseudonym Path failed");
231         return HC_ERR_ALLOC_MEMORY;
232     }
233     if (!GetPseudonymPath(osAccountId, pseudonymPath, MAX_DB_PATH_LEN)) {
234         LOGE("Get pseudonym path failed");
235         HcFree(pseudonymPath);
236         return HC_ERROR;
237     }
238     int32_t ret = HcFileOpen(pseudonymPath, mode, file);
239     if (ret == HC_SUCCESS) {
240         SetSecurityLabel(pseudonymPath, SECURITY_LABEL_S2);
241     }
242     HcFree(pseudonymPath);
243     return ret;
244 }
245 
LoadPseudonymDataFromFile(int32_t osAccountId,PseudonymInfoVec * vec)246 static int32_t LoadPseudonymDataFromFile(int32_t osAccountId, PseudonymInfoVec *vec)
247 {
248     if (vec == NULL) {
249         LOGE("Input PseudonymInfo vec is null.");
250         return HC_ERR_NULL_PTR;
251     }
252     FileHandle file = { 0 };
253     int32_t ret = OpenPseudonymFile(osAccountId, &file, MODE_FILE_READ);
254     if (ret != HC_SUCCESS) {
255         LOGE("Open pseudonym data file failed, ret:%d", ret);
256         return ret;
257     }
258     int32_t fileSize = HcFileSize(file);
259     if (fileSize <= 0) {
260         LOGE("file size stat failed");
261         HcFileClose(file);
262         return HC_ERROR;
263     }
264     char *fileData = (char *)HcMalloc(fileSize, 0);
265     if (fileData == NULL) {
266         LOGE("Malloc file data failed");
267         HcFileClose(file);
268         return HC_ERR_ALLOC_MEMORY;
269     }
270     if (HcFileRead(file, fileData, fileSize) != fileSize) {
271         LOGE("fileData read failed");
272         HcFileClose(file);
273         HcFree(fileData);
274         return HC_ERROR;
275     }
276     HcFileClose(file);
277     CJson *readJsonFile = CreateJsonFromString(fileData);
278     HcFree(fileData);
279     if (readJsonFile == NULL) {
280         LOGE("fileData parse failed");
281         return HC_ERR_JSON_CREATE;
282     }
283     ret = CreatePseudonymFromJson(readJsonFile, vec);
284     FreeJson(readJsonFile);
285     if (ret != HC_SUCCESS) {
286         LOGE("Failed to read pseudonym data from json");
287     }
288 
289     return ret;
290 }
291 
IsNeedRefresh(PseudonymInfo * pseudonymInfo)292 static bool IsNeedRefresh(PseudonymInfo *pseudonymInfo)
293 {
294     if (pseudonymInfo->refreshCount <= 0) {
295         LOGI("count is 0, need refresh pseudonymId");
296         return true;
297     }
298     int64_t curTime = HcGetCurTime();
299     if (curTime > (pseudonymInfo->startTime + MAX_REFRESH_TIME)) {
300         LOGI("time is overdue, need refresh pseudonymId");
301         return true;
302     }
303     return false;
304 }
305 
GenerateJsonFromPseudonymInfo(PseudonymInfo * pseudonymInfo,CJson * pseudonymJson)306 static int32_t GenerateJsonFromPseudonymInfo(PseudonymInfo *pseudonymInfo, CJson *pseudonymJson)
307 {
308     if (AddStringToJson(pseudonymJson, FIELD_PSEUDONYM_ID, pseudonymInfo->pseudonymId) != HC_SUCCESS) {
309         LOGE("Add pseudonymId to json failed");
310         return HC_ERR_JSON_ADD;
311     }
312     if (AddStringToJson(pseudonymJson, FIELD_INDEX_KEY, pseudonymInfo->indexKey) != HC_SUCCESS) {
313         LOGE("Add indexKey to json failed");
314         return HC_ERR_JSON_ADD;
315     }
316     if (AddStringToJson(pseudonymJson, FIELD_REAL_INFO, pseudonymInfo->realInfo) != HC_SUCCESS) {
317         LOGE("Add realInfo to json failed");
318         return HC_ERR_JSON_ADD;
319     }
320     if (AddStringToJson(pseudonymJson, FIELD_DEVICE_ID, pseudonymInfo->deviceId) != HC_SUCCESS) {
321         LOGE("Add deviceId to json failed");
322         return HC_ERR_JSON_ADD;
323     }
324     return HC_SUCCESS;
325 }
326 
WritePseudonymJsonToFile(int32_t osAccountId,CJson * Json)327 static int32_t WritePseudonymJsonToFile(int32_t osAccountId, CJson *Json)
328 {
329     char *storeJsonString = PackJsonToString(Json);
330     if (storeJsonString == NULL) {
331         LOGE("Pack stored json to string failed.");
332         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
333     }
334     FileHandle file = { 0 };
335     int32_t ret = OpenPseudonymFile(osAccountId, &file, MODE_FILE_WRITE);
336     if (ret != HC_SUCCESS) {
337         LOGE("Open pseudonym file failed.");
338         FreeJsonString(storeJsonString);
339         return ret;
340     }
341     int32_t fileSize = (int32_t)(HcStrlen(storeJsonString) + 1);
342     if (HcFileWrite(file, storeJsonString, fileSize) != fileSize) {
343         LOGE("Failed to write Pseudonym array to file.");
344         ret = HC_ERR_FILE;
345     }
346     FreeJsonString(storeJsonString);
347     HcFileClose(file);
348     return ret;
349 }
350 
SavePseudonymInfoToFile(int32_t osAccountId,const PseudonymInfoVec * vec)351 static int32_t SavePseudonymInfoToFile(int32_t osAccountId, const PseudonymInfoVec *vec)
352 {
353     CJson *storeJson = CreateJsonArray();
354     if (storeJson == NULL) {
355         LOGE("Create json failed when save Pseudonym data to file.");
356         return HC_ERR_JSON_CREATE;
357     }
358     int32_t ret;
359     uint32_t index;
360     PseudonymInfo **pseudonymInfoEntry;
361     FOR_EACH_HC_VECTOR(*vec, index, pseudonymInfoEntry) {
362         CJson *entryJson = CreateJson();
363         if (entryJson == NULL) {
364             LOGE("Create json failed.");
365             FreeJson(storeJson);
366             return HC_ERR_JSON_CREATE;
367         }
368         ret = GenerateJsonFromPseudonymInfo(*pseudonymInfoEntry, entryJson);
369         if (ret != HC_SUCCESS) {
370             LOGE("Generate json from pseudonymInfo failed");
371             FreeJson(entryJson);
372             FreeJson(storeJson);
373             return ret;
374         }
375         if (AddObjToArray(storeJson, entryJson) != HC_SUCCESS) {
376             LOGE("Add pseudonymInfoEntry json to array failed");
377             FreeJson(entryJson);
378             FreeJson(storeJson);
379             return HC_ERR_JSON_ADD;
380         }
381     }
382     ret = WritePseudonymJsonToFile(osAccountId, storeJson);
383     FreeJson(storeJson);
384     return ret;
385 }
386 
GetParamByFieldName(const char * fieldName,PseudonymInfo * pseudonymInfoEntry)387 static const char *GetParamByFieldName(const char *fieldName, PseudonymInfo *pseudonymInfoEntry)
388 {
389     if (strcmp(fieldName, FIELD_DEVICE_ID) == 0) {
390         return pseudonymInfoEntry->deviceId;
391     } else if (strcmp(fieldName, FIELD_INDEX_KEY) == 0) {
392         return pseudonymInfoEntry->indexKey;
393     } else {
394         LOGE("Not support this field!");
395         return NULL;
396     }
397 }
398 
LoadOsAccountPseudonymDb(int32_t osAccountId)399 static void LoadOsAccountPseudonymDb(int32_t osAccountId)
400 {
401     OsAccountPseudonymInfo info;
402     info.osAccountId = osAccountId;
403     info.pseudonymInfoVec = CreatePseudonymInfoVec();
404     if (LoadPseudonymDataFromFile(osAccountId, &info.pseudonymInfoVec) != HC_SUCCESS) {
405         ClearPseudonymInfoVec(&info.pseudonymInfoVec);
406         return;
407     }
408     if (g_pseudonymDb.pushBackT(&g_pseudonymDb, info) == NULL) {
409         LOGE("Failed to push osAccountInfo to database!");
410         ClearPseudonymInfoVec(&info.pseudonymInfoVec);
411     }
412     LOGI("Load pseudonym os account db successfully! [Id]: %d", osAccountId);
413 }
414 
OnOsAccountUnlocked(int32_t osAccountId)415 static void OnOsAccountUnlocked(int32_t osAccountId)
416 {
417     LOGI("Os account is unlocked, osAccountId: %d", osAccountId);
418     g_mutex->lock(g_mutex);
419     LoadOsAccountPseudonymDb(osAccountId);
420     g_mutex->unlock(g_mutex);
421 }
422 
RemoveOsAccountPseudonymInfo(int32_t osAccountId)423 static void RemoveOsAccountPseudonymInfo(int32_t osAccountId)
424 {
425     uint32_t index = 0;
426     OsAccountPseudonymInfo *info = NULL;
427     FOR_EACH_HC_VECTOR(g_pseudonymDb, index, info) {
428         if (info->osAccountId == osAccountId) {
429             OsAccountPseudonymInfo deleteInfo;
430             HC_VECTOR_POPELEMENT(&g_pseudonymDb, &deleteInfo, index);
431             ClearPseudonymInfoVec(&deleteInfo.pseudonymInfoVec);
432             return;
433         }
434     }
435 }
436 
OnOsAccountRemoved(int32_t osAccountId)437 static void OnOsAccountRemoved(int32_t osAccountId)
438 {
439     LOGI("Os account is removed, osAccountId: %d", osAccountId);
440     g_mutex->lock(g_mutex);
441     RemoveOsAccountPseudonymInfo(osAccountId);
442     g_mutex->unlock(g_mutex);
443 }
444 
IsOsAccountDataLoaded(int32_t osAccountId)445 static bool IsOsAccountDataLoaded(int32_t osAccountId)
446 {
447     uint32_t index = 0;
448     OsAccountPseudonymInfo *info = NULL;
449     FOR_EACH_HC_VECTOR(g_pseudonymDb, index, info) {
450         if (info->osAccountId == osAccountId) {
451             return true;
452         }
453     }
454     return false;
455 }
456 
LoadDataIfNotLoaded(int32_t osAccountId)457 static void LoadDataIfNotLoaded(int32_t osAccountId)
458 {
459     if (IsOsAccountDataLoaded(osAccountId)) {
460         return;
461     }
462     LOGI("Data has not been loaded, load it, osAccountId: %d", osAccountId);
463     LoadOsAccountPseudonymDb(osAccountId);
464 }
465 
GetPseudonymInfoByOsAccountId(int32_t osAccountId)466 static OsAccountPseudonymInfo *GetPseudonymInfoByOsAccountId(int32_t osAccountId)
467 {
468     if (IsOsAccountSupported()) {
469         LoadDataIfNotLoaded(osAccountId);
470     }
471     uint32_t index = 0;
472     OsAccountPseudonymInfo *info = NULL;
473     FOR_EACH_HC_VECTOR(g_pseudonymDb, index, info) {
474         if (info->osAccountId == osAccountId) {
475             return info;
476         }
477     }
478     LOGI("Create a new os account database cache! [Id]: %d", osAccountId);
479     OsAccountPseudonymInfo newInfo;
480     newInfo.osAccountId = osAccountId;
481     newInfo.pseudonymInfoVec = CreatePseudonymInfoVec();
482     OsAccountPseudonymInfo *returnInfo = g_pseudonymDb.pushBackT(&g_pseudonymDb, newInfo);
483     if (returnInfo == NULL) {
484         LOGE("Failed to push OsAccountPseudonymInfo to database!");
485         DestroyPseudonymInfoVec(&newInfo.pseudonymInfoVec);
486     }
487     return returnInfo;
488 }
489 
SaveOsAccountPseudonymDb(int32_t osAccountId)490 static int32_t SaveOsAccountPseudonymDb(int32_t osAccountId)
491 {
492     g_mutex->lock(g_mutex);
493     OsAccountPseudonymInfo *info = GetPseudonymInfoByOsAccountId(osAccountId);
494     if (info == NULL) {
495         LOGE("Get pseudonym info by os account id failed");
496         g_mutex->unlock(g_mutex);
497         return HC_ERROR;
498     }
499     int32_t ret = SavePseudonymInfoToFile(osAccountId, &info->pseudonymInfoVec);
500     if (ret != HC_SUCCESS) {
501         LOGE("Save pseudonym info to file failed");
502         g_mutex->unlock(g_mutex);
503         return ret;
504     }
505     g_mutex->unlock(g_mutex);
506     LOGI("Save an os account database successfully! [Id]: %d", osAccountId);
507     return HC_SUCCESS;
508 }
509 
DeletePseudonymInner(int32_t osAccountId,const char * dataTodelete,PseudonymInfoVec * deleteVec,const char * fieldName)510 static int32_t DeletePseudonymInner(int32_t osAccountId, const char *dataTodelete, PseudonymInfoVec *deleteVec,
511     const char *fieldName)
512 {
513     LOGI("Start to delete Pseudonym from database!");
514     g_mutex->lock(g_mutex);
515     OsAccountPseudonymInfo *info = GetPseudonymInfoByOsAccountId(osAccountId);
516     if (info == NULL) {
517         LOGE("Get pseudonym info by os account id failed");
518         g_mutex->unlock(g_mutex);
519         return HC_ERROR;
520     }
521     int32_t count = 0;
522     uint32_t index = 0;
523     PseudonymInfo **pseudonymInfoEntry = NULL;
524     while (index < HC_VECTOR_SIZE(&info->pseudonymInfoVec)) {
525         pseudonymInfoEntry = info->pseudonymInfoVec.getp(&info->pseudonymInfoVec, index);
526         if ((pseudonymInfoEntry == NULL) || (*pseudonymInfoEntry == NULL) ||
527             (strcmp(dataTodelete, GetParamByFieldName(fieldName, *pseudonymInfoEntry))) != 0) {
528             index++;
529             continue;
530         }
531         PseudonymInfo *deletepseudonymInfoEntry = NULL;
532         HC_VECTOR_POPELEMENT(&info->pseudonymInfoVec, &deletepseudonymInfoEntry, index);
533         count++;
534         LOGI("Delete pseudonymInfoEntry from database successfully!");
535         if (deleteVec->pushBackT(deleteVec, deletepseudonymInfoEntry) == NULL) {
536             LOGE("Failed to push deleted pseudonymInfoEntry to vec");
537             DestroyPseudonymInfo(deletepseudonymInfoEntry);
538         }
539     }
540     g_mutex->unlock(g_mutex);
541     if (count == 0) {
542         LOGE("No pseudonym info deleted");
543         return HC_ERROR;
544     }
545     LOGI("Number of pseudonym info deleted: %d", count);
546     return HC_SUCCESS;
547 }
548 
InitPseudonymManger(void)549 static void InitPseudonymManger(void)
550 {
551     if (g_mutex == NULL) {
552         g_mutex = (HcMutex *)HcMalloc(sizeof(HcMutex), 0);
553         if (g_mutex == NULL) {
554             LOGE("Alloc sessionMutex failed");
555             return;
556         }
557         if (InitHcMutex(g_mutex) != HC_SUCCESS) {
558             LOGE("Init mutex failed");
559             HcFree(g_mutex);
560             g_mutex = NULL;
561             return;
562         }
563     }
564     g_mutex->lock(g_mutex);
565     if (!g_isInitial) {
566         g_pseudonymDb = CREATE_HC_VECTOR(PseudonymDb);
567         AddOsAccountEventCallback(PSEUDONYM_DATA_CALLBACK, OnOsAccountUnlocked, OnOsAccountRemoved);
568         g_isInitial = true;
569     }
570     g_mutex->unlock(g_mutex);
571 }
572 
LoadPseudonymData(void)573 static void LoadPseudonymData(void)
574 {
575     InitPseudonymManger();
576     if (IsOsAccountSupported()) {
577         return;
578     }
579     g_mutex->lock(g_mutex);
580     StringVector dbNameVec = CreateStrVector();
581     HcFileGetSubFileName(GetPseudonymStoragePath(), &dbNameVec);
582     uint32_t index;
583     HcString *dbName = NULL;
584     FOR_EACH_HC_VECTOR(dbNameVec, index, dbName) {
585         int32_t osAccountId;
586         const char *name = StringGet(dbName);
587         if (name == NULL) {
588             continue;
589         }
590         if (strcmp(name, "pseudonym_data.dat") == 0) {
591             LoadOsAccountPseudonymDb(DEFAULT_OS_ACCOUNT);
592         } else if (sscanf_s(name, "pseudonym_data%d.dat", &osAccountId) == 1) {
593             LoadOsAccountPseudonymDb(osAccountId);
594         }
595     }
596     DestroyStrVector(&dbNameVec);
597     g_mutex->unlock(g_mutex);
598 }
599 
GetRealInfo(int32_t osAccountId,const char * pseudonymId,char ** realInfo)600 static int32_t GetRealInfo(int32_t osAccountId, const char *pseudonymId, char **realInfo)
601 {
602     if (pseudonymId == NULL || realInfo == NULL) {
603         LOGE("pseudonymId is null!");
604         return HC_ERR_INVALID_PARAMS;
605     }
606     InitPseudonymManger();
607     g_mutex->lock(g_mutex);
608     OsAccountPseudonymInfo *info = GetPseudonymInfoByOsAccountId(osAccountId);
609     if (info == NULL) {
610         LOGE("Failed to get Pseudonym by os account id");
611         g_mutex->unlock(g_mutex);
612         return HC_ERROR;
613     }
614     uint32_t index;
615     PseudonymInfo **pseudonymInfoEntry = NULL;
616     FOR_EACH_HC_VECTOR(info->pseudonymInfoVec, index, pseudonymInfoEntry) {
617         if ((pseudonymInfoEntry != NULL) && (*pseudonymInfoEntry != NULL) &&
618             (strcmp((*pseudonymInfoEntry)->pseudonymId, pseudonymId) == 0)) {
619             if (DeepCopyString((*pseudonymInfoEntry)->realInfo, realInfo) != HC_SUCCESS) {
620                 LOGE("Failed to deep copy realInfo!");
621                 g_mutex->unlock(g_mutex);
622                 return HC_ERR_MEMORY_COPY;
623             }
624             g_mutex->unlock(g_mutex);
625             return HC_SUCCESS;
626         }
627     }
628     g_mutex->unlock(g_mutex);
629     return HC_SUCCESS;
630 }
631 
GetPseudonymId(int32_t osAccountId,const char * indexKey,char ** pseudonymId)632 static int32_t GetPseudonymId(int32_t osAccountId, const char *indexKey, char **pseudonymId)
633 {
634     if (indexKey == NULL || pseudonymId == NULL) {
635         LOGE("input params is null!");
636         return HC_ERR_INVALID_PARAMS;
637     }
638     InitPseudonymManger();
639     g_mutex->lock(g_mutex);
640     OsAccountPseudonymInfo *info = GetPseudonymInfoByOsAccountId(osAccountId);
641     if (info == NULL) {
642         LOGE("Failed to get Pseudonym by os account id");
643         g_mutex->unlock(g_mutex);
644         return HC_ERROR;
645     }
646     uint32_t index;
647     PseudonymInfo **pseudonymInfoEntry = NULL;
648     FOR_EACH_HC_VECTOR(info->pseudonymInfoVec, index, pseudonymInfoEntry) {
649         if ((pseudonymInfoEntry != NULL) && (*pseudonymInfoEntry != NULL) &&
650             (strcmp((*pseudonymInfoEntry)->indexKey, indexKey) == 0)) {
651             if (DeepCopyString((*pseudonymInfoEntry)->pseudonymId, pseudonymId) != HC_SUCCESS) {
652                 LOGE("Failed to deep copy pseudonymId!");
653                 g_mutex->unlock(g_mutex);
654                 return HC_ERR_MEMORY_COPY;
655             }
656             g_mutex->unlock(g_mutex);
657             return HC_SUCCESS;
658         }
659     }
660     g_mutex->unlock(g_mutex);
661     return HC_SUCCESS;
662 }
663 
AddPseudonymIdInfoToMemory(int32_t osAccountId,PseudonymInfo * pseudonymInfo)664 static int32_t AddPseudonymIdInfoToMemory(int32_t osAccountId, PseudonymInfo *pseudonymInfo)
665 {
666     LOGI("Start to add a pseudonymInfo to memory!");
667     g_mutex->lock(g_mutex);
668     OsAccountPseudonymInfo *info = GetPseudonymInfoByOsAccountId(osAccountId);
669     if (info == NULL) {
670         LOGE("Failed to get Pseudonym by os account id");
671         g_mutex->unlock(g_mutex);
672         return HC_ERROR;
673     }
674     PseudonymInfo **oldPtr = QueryPseudonymInfoPtrIfMatch(&info->pseudonymInfoVec,
675         pseudonymInfo->realInfo);
676     if (oldPtr != NULL) {
677         DestroyPseudonymInfo(*oldPtr);
678         *oldPtr = pseudonymInfo;
679         g_mutex->unlock(g_mutex);
680         LOGI("Replace an old pseudonymInfo successfully!");
681         return HC_SUCCESS;
682     }
683     if (info->pseudonymInfoVec.pushBackT(&info->pseudonymInfoVec, pseudonymInfo) == NULL) {
684         g_mutex->unlock(g_mutex);
685         LOGE("Failed to push pseudonymInfo to vec!");
686         return HC_ERR_MEMORY_COPY;
687     }
688     g_mutex->unlock(g_mutex);
689     LOGI("Add pseudonymInfo to memory successfully!");
690     return HC_SUCCESS;
691 }
692 
BuildPseudonymInfoEntry(const char * realInfo,const char * pseudonymId,const char * deviceId,const char * indexKey)693 static PseudonymInfo *BuildPseudonymInfoEntry(const char *realInfo, const char *pseudonymId, const char *deviceId,
694     const char *indexKey)
695 {
696     PseudonymInfo *pseudonymInfoEntry = CreatePseudonymInfo();
697     if (pseudonymInfoEntry == NULL) {
698         LOGE("Failed to create pseudonymInfoEntry");
699         return NULL;
700     }
701     GOTO_IF_ERR(DeepCopyString(pseudonymId, &pseudonymInfoEntry->pseudonymId));
702     GOTO_IF_ERR(DeepCopyString(realInfo, &pseudonymInfoEntry->realInfo));
703     GOTO_IF_ERR(DeepCopyString(deviceId, &pseudonymInfoEntry->deviceId));
704     GOTO_IF_ERR(DeepCopyString(indexKey, &pseudonymInfoEntry->indexKey));
705     return pseudonymInfoEntry;
706 ERR:
707     DestroyPseudonymInfo(pseudonymInfoEntry);
708     return NULL;
709 }
710 
SavePseudonymId(int32_t osAccountId,const char * pseudonymId,const char * realInfo,const char * deviceId,const char * indexKey)711 static int32_t SavePseudonymId(int32_t osAccountId, const char *pseudonymId, const char *realInfo, const char *deviceId,
712     const char *indexKey)
713 {
714     if (realInfo == NULL || pseudonymId == NULL || deviceId == NULL || indexKey == NULL) {
715         LOGE("params is null!");
716         return HC_ERR_INVALID_PARAMS;
717     }
718     InitPseudonymManger();
719     PseudonymInfo *pseudonymInfo = BuildPseudonymInfoEntry(realInfo, pseudonymId, deviceId, indexKey);
720     if (pseudonymInfo == NULL) {
721         LOGE("Failed to build pseudonymInfoEntry");
722         return HC_ERROR;
723     }
724     int ret = AddPseudonymIdInfoToMemory(osAccountId, pseudonymInfo);
725     if (ret != HC_SUCCESS) {
726         LOGE("Failed to add pseudonymId info to memory");
727         DestroyPseudonymInfo(pseudonymInfo);
728         return ret;
729     }
730     ret = SaveOsAccountPseudonymDb(osAccountId);
731     if (ret != HC_SUCCESS) {
732         LOGE("Failed to add Save Pseudonym info to Database");
733         DestroyPseudonymInfo(pseudonymInfo);
734         return ret;
735     }
736     return HC_SUCCESS;
737 }
738 
DeleteAllPseudonymId(int32_t osAccountId,const char * deviceId)739 static int32_t DeleteAllPseudonymId(int32_t osAccountId, const char *deviceId)
740 {
741     if (deviceId == NULL) {
742         LOGE("deviceId is null!");
743         return HC_ERR_INVALID_PARAMS;
744     }
745     InitPseudonymManger();
746     PseudonymInfoVec deletePseudonymIdVec = CreatePseudonymInfoVec();
747     int32_t ret = DeletePseudonymInner(osAccountId, deviceId, &deletePseudonymIdVec, FIELD_DEVICE_ID);
748     if (ret != HC_SUCCESS) {
749         LOGE("Failed to delete pseudonym inner, account id is: %d", osAccountId);
750         DestroyPseudonymInfoVec(&deletePseudonymIdVec);
751         return ret;
752     }
753     ret = SaveOsAccountPseudonymDb(osAccountId);
754     if (ret != HC_SUCCESS) {
755         LOGE("Failed to save pseudonym data to db, account id is: %d", osAccountId);
756         ClearPseudonymInfoVec(&deletePseudonymIdVec);
757         return ret;
758     }
759     ClearPseudonymInfoVec(&deletePseudonymIdVec);
760     return HC_SUCCESS;
761 }
762 
DeletePseudonymId(int32_t osAccountId,const char * indexKey)763 static int32_t DeletePseudonymId(int32_t osAccountId, const char *indexKey)
764 {
765     if (indexKey == NULL) {
766         LOGE("indexKey is null!");
767         return HC_ERR_INVALID_PARAMS;
768     }
769     InitPseudonymManger();
770     PseudonymInfoVec deletePseudonymIdVec = CreatePseudonymInfoVec();
771     int32_t ret = DeletePseudonymInner(osAccountId, indexKey, &deletePseudonymIdVec, FIELD_INDEX_KEY);
772     if (ret != HC_SUCCESS) {
773         LOGE("Failed to delete pseudonym inner, account id is: %d", osAccountId);
774         DestroyPseudonymInfoVec(&deletePseudonymIdVec);
775         return ret;
776     }
777     ret = SaveOsAccountPseudonymDb(osAccountId);
778     if (ret != HC_SUCCESS) {
779         LOGE("Failed to save pseudonym data to db, account id is: %d", osAccountId);
780         ClearPseudonymInfoVec(&deletePseudonymIdVec);
781         return ret;
782     }
783     ClearPseudonymInfoVec(&deletePseudonymIdVec);
784     return HC_SUCCESS;
785 }
786 
IsNeedRefreshPseudonymId(int32_t osAccountId,const char * indexKey)787 static bool IsNeedRefreshPseudonymId(int32_t osAccountId, const char *indexKey)
788 {
789     if (indexKey == NULL) {
790         LOGE("indexKey is null");
791         return true;
792     }
793     InitPseudonymManger();
794     g_mutex->lock(g_mutex);
795     OsAccountPseudonymInfo *info = GetPseudonymInfoByOsAccountId(osAccountId);
796     if (info == NULL) {
797         LOGE("Failed to get Pseudonym by os account id");
798         g_mutex->unlock(g_mutex);
799         return true;
800     }
801     uint32_t index;
802     PseudonymInfo **pseudonymInfoEntry = NULL;
803     FOR_EACH_HC_VECTOR(info->pseudonymInfoVec, index, pseudonymInfoEntry) {
804         if ((pseudonymInfoEntry != NULL) && (*pseudonymInfoEntry != NULL) &&
805             (strcmp((*pseudonymInfoEntry)->indexKey, indexKey) == 0)) {
806             if (IsNeedRefresh(*pseudonymInfoEntry)) {
807                 g_mutex->unlock(g_mutex);
808                 return true;
809             }
810             (*pseudonymInfoEntry)->refreshCount--;
811             g_mutex->unlock(g_mutex);
812             return false;
813         }
814     }
815     g_mutex->unlock(g_mutex);
816     return true;
817 }
818 
819 static PseudonymManager g_pseudonymManager = {
820     .loadPseudonymData = LoadPseudonymData,
821     .getRealInfo = GetRealInfo,
822     .getPseudonymId = GetPseudonymId,
823     .savePseudonymId = SavePseudonymId,
824     .deleteAllPseudonymId = DeleteAllPseudonymId,
825     .deletePseudonymId = DeletePseudonymId,
826     .isNeedRefreshPseudonymId = IsNeedRefreshPseudonymId
827 };
828 
GetPseudonymInstance(void)829 PseudonymManager *GetPseudonymInstance(void)
830 {
831     return &g_pseudonymManager;
832 }
833 
DestroyPseudonymManager(void)834 void DestroyPseudonymManager(void)
835 {
836     g_mutex->lock(g_mutex);
837     RemoveOsAccountEventCallback(PSEUDONYM_DATA_CALLBACK);
838     uint32_t index;
839     OsAccountPseudonymInfo *info = NULL;
840     FOR_EACH_HC_VECTOR(g_pseudonymDb, index, info) {
841         ClearPseudonymInfoVec(&info->pseudonymInfoVec);
842     }
843     DESTROY_HC_VECTOR(PseudonymDb, &g_pseudonymDb);
844     g_mutex->unlock(g_mutex);
845     DestroyHcMutex(g_mutex);
846     HcFree(g_mutex);
847     g_mutex = NULL;
848 }