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 }