• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 "sym_token_manager.h"
17 
18 #include "alg_defs.h"
19 #include "alg_loader.h"
20 #include "common_defs.h"
21 #include "hc_dev_info.h"
22 #include "hal_error.h"
23 #include "hc_file.h"
24 #include "hc_log.h"
25 #include "hc_mutex.h"
26 #include "hc_types.h"
27 #include "string_util.h"
28 
29 IMPLEMENT_HC_VECTOR(SymTokenVec, SymToken*, 1)
30 
31 typedef struct {
32     int32_t osAccountId;
33     SymTokenVec tokens;
34 } OsSymTokensInfo;
35 
36 DECLARE_HC_VECTOR(SymTokensDb, OsSymTokensInfo)
37 IMPLEMENT_HC_VECTOR(SymTokensDb, OsSymTokensInfo, 1)
38 
39 #define FIELD_SYM_TOKENS "symTokens"
40 
41 #define MAX_DB_PATH_LEN 256
42 
43 SymTokenManager g_symTokenManager;
44 
45 static SymTokensDb g_symTokensDb;
46 static HcMutex *g_dataMutex;
47 
IsTokenMatch(const SymToken * token,const char * userId,const char * deviceId)48 static bool IsTokenMatch(const SymToken *token, const char *userId, const char *deviceId)
49 {
50     return (strcmp(userId, token->userId) == 0) && (strcmp(deviceId, token->deviceId) == 0);
51 }
52 
GetTokensFilePath(int32_t osAccountId,char * tokenPath,uint32_t pathBufferLen)53 static bool GetTokensFilePath(int32_t osAccountId, char *tokenPath, uint32_t pathBufferLen)
54 {
55     const char *beginPath = GetAccountStoragePath();
56     if (beginPath == NULL) {
57         LOGE("Failed to get the account storage path!");
58         return false;
59     }
60     int32_t writeByteNum;
61     if (osAccountId == DEFAULT_OS_ACCOUNT) {
62         writeByteNum = sprintf_s(tokenPath, pathBufferLen, "%s/account_data_sym.dat", beginPath);
63     } else {
64         writeByteNum = sprintf_s(tokenPath, pathBufferLen, "%s/account_data_sym%d.dat", beginPath, osAccountId);
65     }
66     if (writeByteNum <= 0) {
67         LOGE("sprintf_s fail!");
68         return false;
69     }
70     return true;
71 }
72 
CreateSymTokenByJson(const CJson * tokenJson)73 static SymToken *CreateSymTokenByJson(const CJson *tokenJson)
74 {
75     SymToken *token = (SymToken *)HcMalloc(sizeof(SymToken), 0);
76     if (token == NULL) {
77         LOGE("Failed to allocate token memory!");
78         return NULL;
79     }
80     const char *userId = GetStringFromJson(tokenJson, FIELD_USER_ID);
81     if (userId == NULL) {
82         LOGE("Failed to get userId from json!");
83         HcFree(token);
84         return NULL;
85     }
86     const char *deviceId = GetStringFromJson(tokenJson, FIELD_DEVICE_ID);
87     if (deviceId == NULL) {
88         LOGE("Failed to get deviceId from json!");
89         HcFree(token);
90         return NULL;
91     }
92     if (strcpy_s(token->userId, DEV_AUTH_USER_ID_SIZE, userId) != EOK) {
93         LOGE("Failed to copy userId!");
94         HcFree(token);
95         return NULL;
96     }
97     if (strcpy_s(token->deviceId, DEV_AUTH_DEVICE_ID_SIZE, deviceId) != EOK) {
98         LOGE("Failed to copy deviceId!");
99         HcFree(token);
100         return NULL;
101     }
102     return token;
103 }
104 
CreateTokensFromJson(CJson * tokensJson,SymTokenVec * vec)105 static int32_t CreateTokensFromJson(CJson *tokensJson, SymTokenVec *vec)
106 {
107     CJson *symTokensJson = GetObjFromJson(tokensJson, FIELD_SYM_TOKENS);
108     if (symTokensJson == NULL) {
109         LOGE("Failed to get symTokensJson from json!");
110         return HC_ERR_JSON_GET;
111     }
112     int32_t tokenNum = GetItemNum(symTokensJson);
113     if (tokenNum <= 0) {
114         LOGE("No token found.");
115         return HC_ERR_JSON_GET;
116     }
117     for (int32_t i = 0; i < tokenNum; i++) {
118         CJson *tokenJson = GetItemFromArray(symTokensJson, i);
119         if (tokenJson == NULL) {
120             LOGE("Token json is null");
121             ClearSymTokenVec(vec);
122             return HC_ERR_JSON_GET;
123         }
124         SymToken *symToken = CreateSymTokenByJson(tokenJson);
125         if (symToken == NULL) {
126             LOGE("Failed to create symToken from json!");
127             ClearSymTokenVec(vec);
128             return HC_ERR_ALLOC_MEMORY;
129         }
130         if (vec->pushBackT(vec, symToken) == NULL) {
131             LOGE("Failed to push symToken to vec");
132             HcFree(symToken);
133             ClearSymTokenVec(vec);
134             return HC_ERR_MEMORY_COPY;
135         }
136     }
137     return HC_SUCCESS;
138 }
139 
OpenTokenFile(int32_t osAccountId,FileHandle * file,int32_t mode)140 static int32_t OpenTokenFile(int32_t osAccountId, FileHandle *file, int32_t mode)
141 {
142     char *tokenPath = (char *)HcMalloc(MAX_DB_PATH_LEN, 0);
143     if (tokenPath == NULL) {
144         LOGE("Malloc tokenPath failed");
145         return HC_ERR_ALLOC_MEMORY;
146     }
147     if (!GetTokensFilePath(osAccountId, tokenPath, MAX_DB_PATH_LEN)) {
148         LOGE("Get token path failed");
149         HcFree(tokenPath);
150         return HC_ERROR;
151     }
152     int32_t ret = HcFileOpen(tokenPath, mode, file);
153     HcFree(tokenPath);
154     return ret;
155 }
156 
ReadTokensFromFile(int32_t osAccountId,SymTokenVec * vec)157 static int32_t ReadTokensFromFile(int32_t osAccountId, SymTokenVec *vec)
158 {
159     if (vec == NULL) {
160         LOGE("Input token vec is null.");
161         return HC_ERR_NULL_PTR;
162     }
163     FileHandle file = { 0 };
164     int32_t ret = OpenTokenFile(osAccountId, &file, MODE_FILE_READ);
165     if (ret != HC_SUCCESS) {
166         LOGE("Open token file failed");
167         return ret;
168     }
169     int32_t fileSize = HcFileSize(file);
170     if (fileSize <= 0) {
171         LOGE("file size stat failed");
172         HcFileClose(file);
173         return HC_ERROR;
174     }
175     char *fileData = (char *)HcMalloc(fileSize, 0);
176     if (fileData == NULL) {
177         LOGE("Malloc file data failed");
178         HcFileClose(file);
179         return HC_ERR_ALLOC_MEMORY;
180     }
181     if (HcFileRead(file, fileData, fileSize) != fileSize) {
182         LOGE("fileData read failed");
183         HcFileClose(file);
184         HcFree(fileData);
185         return HC_ERROR;
186     }
187     HcFileClose(file);
188     CJson *readJsonFile = CreateJsonFromString(fileData);
189     HcFree(fileData);
190     if (readJsonFile == NULL) {
191         LOGE("fileData parse failed");
192         return HC_ERR_JSON_CREATE;
193     }
194     ret = CreateTokensFromJson(readJsonFile, vec);
195     FreeJson(readJsonFile);
196     if (ret != HC_SUCCESS) {
197         LOGE("Failed to create tokens from json");
198     }
199     return ret;
200 }
201 
WriteTokensJsonToFile(int32_t osAccountId,CJson * tokensJson)202 static int32_t WriteTokensJsonToFile(int32_t osAccountId, CJson *tokensJson)
203 {
204     char *storeJsonString = PackJsonToString(tokensJson);
205     if (storeJsonString == NULL) {
206         LOGE("Pack stored json to string failed.");
207         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
208     }
209     FileHandle file = { 0 };
210     int32_t ret = OpenTokenFile(osAccountId, &file, MODE_FILE_WRITE);
211     if (ret != HC_SUCCESS) {
212         LOGE("Open token file failed.");
213         FreeJsonString(storeJsonString);
214         return ret;
215     }
216     int32_t fileSize = (int32_t)(HcStrlen(storeJsonString) + 1);
217     if (HcFileWrite(file, storeJsonString, fileSize) != fileSize) {
218         LOGE("Failed to write token array to file.");
219         ret = HC_ERR_FILE;
220     }
221     FreeJsonString(storeJsonString);
222     HcFileClose(file);
223     return ret;
224 }
225 
GenerateJsonFromToken(const SymToken * token,CJson * tokenJson)226 static int32_t GenerateJsonFromToken(const SymToken *token, CJson *tokenJson)
227 {
228     if (AddStringToJson(tokenJson, FIELD_USER_ID, token->userId) != HC_SUCCESS) {
229         LOGE("Failed to add userId to json!");
230         return HC_ERR_JSON_ADD;
231     }
232     if (AddStringToJson(tokenJson, FIELD_DEVICE_ID, token->deviceId) != HC_SUCCESS) {
233         LOGE("Failed to add deviceId to json!");
234         return HC_ERR_JSON_ADD;
235     }
236     return HC_SUCCESS;
237 }
238 
SaveTokensToFile(int32_t osAccountId,const SymTokenVec * vec)239 static int32_t SaveTokensToFile(int32_t osAccountId, const SymTokenVec *vec)
240 {
241     CJson *symTokensJson = CreateJsonArray();
242     if (symTokensJson == NULL) {
243         LOGE("Create json failed when save tokens to file.");
244         return HC_ERR_JSON_CREATE;
245     }
246     int32_t ret;
247     uint32_t index;
248     SymToken **token;
249     FOR_EACH_HC_VECTOR(*vec, index, token) {
250         CJson *tokenJson = CreateJson();
251         if (tokenJson == NULL) {
252             LOGE("Create token json failed.");
253             FreeJson(symTokensJson);
254             return HC_ERR_JSON_CREATE;
255         }
256         ret = GenerateJsonFromToken(*token, tokenJson);
257         if (ret != HC_SUCCESS) {
258             LOGE("Generate json from token failed");
259             FreeJson(tokenJson);
260             FreeJson(symTokensJson);
261             return ret;
262         }
263         if (AddObjToArray(symTokensJson, tokenJson) != HC_SUCCESS) {
264             LOGE("Add token json to array failed");
265             FreeJson(tokenJson);
266             FreeJson(symTokensJson);
267             return HC_ERR_JSON_ADD;
268         }
269     }
270     CJson *allTokensJson = CreateJson();
271     if (allTokensJson == NULL) {
272         LOGE("Failed to allocate tokensJson memory!");
273         FreeJson(symTokensJson);
274         return HC_ERR_JSON_CREATE;
275     }
276     if (AddObjToJson(allTokensJson, FIELD_SYM_TOKENS, symTokensJson) != HC_SUCCESS) {
277         LOGE("Failed to add symTokensJson to json!");
278         FreeJson(symTokensJson);
279         FreeJson(allTokensJson);
280         return HC_ERR_JSON_ADD;
281     }
282     FreeJson(symTokensJson);
283     ret = WriteTokensJsonToFile(osAccountId, allTokensJson);
284     FreeJson(allTokensJson);
285     return ret;
286 }
287 
GetTokensInfoByOsAccountId(int32_t osAccountId)288 static OsSymTokensInfo *GetTokensInfoByOsAccountId(int32_t osAccountId)
289 {
290     uint32_t index = 0;
291     OsSymTokensInfo *info = NULL;
292     FOR_EACH_HC_VECTOR(g_symTokensDb, index, info) {
293         if ((info != NULL) && (info->osAccountId == osAccountId)) {
294             return info;
295         }
296     }
297     LOGI("Create a new os account database cache! [Id]: %d", osAccountId);
298     OsSymTokensInfo newInfo;
299     newInfo.osAccountId = osAccountId;
300     newInfo.tokens = CreateSymTokenVec();
301     OsSymTokensInfo *returnInfo = g_symTokensDb.pushBackT(&g_symTokensDb, newInfo);
302     if (returnInfo == NULL) {
303         LOGE("Failed to push OsSymTokensInfo to database!");
304         DestroySymTokenVec(&newInfo.tokens);
305     }
306     return returnInfo;
307 }
308 
SaveOsSymTokensDb(int32_t osAccountId)309 static int32_t SaveOsSymTokensDb(int32_t osAccountId)
310 {
311     OsSymTokensInfo *info = GetTokensInfoByOsAccountId(osAccountId);
312     if (info == NULL) {
313         LOGE("Failed to get tokens by os account id. [OsAccountId]: %d", osAccountId);
314         return HC_ERR_INVALID_PARAMS;
315     }
316     int32_t ret = SaveTokensToFile(osAccountId, &info->tokens);
317     if (ret != HC_SUCCESS) {
318         LOGE("Save tokens to file failed");
319         return ret;
320     }
321     LOGI("Save an os account database successfully! [Id]: %d", osAccountId);
322     return HC_SUCCESS;
323 }
324 
QueryTokenPtrIfMatch(const SymTokenVec * vec,const char * userId,const char * deviceId)325 static SymToken **QueryTokenPtrIfMatch(const SymTokenVec *vec, const char *userId, const char *deviceId)
326 {
327     uint32_t index;
328     SymToken **token;
329     FOR_EACH_HC_VECTOR(*vec, index, token) {
330         if ((token != NULL) && (*token != NULL) && (IsTokenMatch(*token, userId, deviceId))) {
331             return token;
332         }
333     }
334     return NULL;
335 }
336 
AddSymTokenToVec(int32_t osAccountId,SymToken * token)337 static int32_t AddSymTokenToVec(int32_t osAccountId, SymToken *token)
338 {
339     LOGI("Start to add a token to database!");
340     OsSymTokensInfo *info = GetTokensInfoByOsAccountId(osAccountId);
341     if (info == NULL) {
342         LOGE("Failed to get tokens by os account id. [OsAccountId]: %d", osAccountId);
343         return HC_ERR_INVALID_PARAMS;
344     }
345     SymToken **oldTokenPtr = QueryTokenPtrIfMatch(&info->tokens, token->userId, token->deviceId);
346     if (oldTokenPtr != NULL) {
347         LOGI("Replace an old token successfully!");
348         HcFree(*oldTokenPtr);
349         *oldTokenPtr = token;
350         return HC_SUCCESS;
351     }
352     if (info->tokens.pushBackT(&info->tokens, token) == NULL) {
353         LOGE("Failed to push token to vec!");
354         return HC_ERR_MEMORY_COPY;
355     }
356     LOGI("Add a token to database successfully!");
357     return HC_SUCCESS;
358 }
359 
GenerateKeyAlias(const char * userId,const char * deviceId,Uint8Buff * keyAlias)360 static int32_t GenerateKeyAlias(const char *userId, const char *deviceId, Uint8Buff *keyAlias)
361 {
362     if ((userId == NULL) || (deviceId == NULL) || (keyAlias == NULL)) {
363         LOGE("Invalid input params");
364         return HC_ERR_NULL_PTR;
365     }
366     /* KeyAlias = sha256(userId + deviceId + tag). */
367     const char *authCodeTag = "authCode";
368     uint32_t authCodeTagLen = HcStrlen(authCodeTag);
369     uint32_t userIdLen = HcStrlen(userId);
370     uint32_t deviceIdLen = HcStrlen(deviceId);
371     uint32_t aliasLen = authCodeTagLen + userIdLen + deviceIdLen;
372     uint8_t *aliasVal = (uint8_t *)HcMalloc(aliasLen, 0);
373     if (aliasVal == NULL) {
374         LOGE("Failed to malloc for self key aliasStr.");
375         return HC_ERR_ALLOC_MEMORY;
376     }
377     Uint8Buff oriAliasBuff = {
378         aliasVal,
379         aliasLen
380     };
381     if (memcpy_s(oriAliasBuff.val, oriAliasBuff.length, userId, userIdLen) != EOK) {
382         LOGE("Failed to copy userId.");
383         HcFree(aliasVal);
384         return HC_ERR_MEMORY_COPY;
385     }
386     if (memcpy_s(oriAliasBuff.val + userIdLen, oriAliasBuff.length - userIdLen, deviceId, deviceIdLen) != EOK) {
387         LOGE("Failed to copy deviceId.");
388         HcFree(aliasVal);
389         return HC_ERR_MEMORY_COPY;
390     }
391     if (memcpy_s(oriAliasBuff.val + userIdLen + deviceIdLen,
392         oriAliasBuff.length - userIdLen - deviceIdLen, authCodeTag, authCodeTagLen) != EOK) {
393         LOGE("Failed to copy authCodeTag.");
394         HcFree(aliasVal);
395         return HC_ERR_MEMORY_COPY;
396     }
397     int32_t res = GetLoaderInstance()->sha256(&oriAliasBuff, keyAlias);
398     HcFree(aliasVal);
399     if (res != HAL_SUCCESS) {
400         LOGE("Compute authCode alias hash failed");
401     }
402     return res;
403 }
404 
ImportSymTokenToKeyManager(const SymToken * token,CJson * in,int32_t opCode)405 static int32_t ImportSymTokenToKeyManager(const SymToken *token, CJson *in, int32_t opCode)
406 {
407     uint8_t authCode[DEV_AUTH_AUTH_CODE_SIZE] = { 0 };
408     if (GetByteFromJson(in, FIELD_AUTH_CODE, authCode, DEV_AUTH_AUTH_CODE_SIZE) != HC_SUCCESS) {
409         LOGE("Failed to get authCode from json!");
410         return HC_ERR_JSON_GET;
411     }
412     uint8_t *keyAliasVal = (uint8_t *)HcMalloc(SHA256_LEN, 0);
413     if (keyAliasVal == NULL) {
414         LOGE("Failed to allocate keyAliasVal memory!");
415         return HC_ERR_ALLOC_MEMORY;
416     }
417     Uint8Buff keyAlias = {
418         .val = keyAliasVal,
419         .length = SHA256_LEN
420     };
421     Uint8Buff authCodeBuff = {
422         .val = authCode,
423         .length = DEV_AUTH_AUTH_CODE_SIZE
424     };
425     int32_t res = GenerateKeyAlias(token->userId, token->deviceId, &keyAlias);
426     if (res != HC_SUCCESS) {
427         LOGE("Failed to generate authCode key alias!");
428         HcFree(keyAliasVal);
429         return res;
430     }
431     KeyPurpose purpose = KEY_PURPOSE_DERIVE;
432     if (opCode == IMPORT_TRUSTED_CREDENTIALS) {
433         purpose = KEY_PURPOSE_MAC;
434     }
435     res = GetLoaderInstance()->importSymmetricKey(&keyAlias, &authCodeBuff, purpose, NULL);
436     HcFree(keyAliasVal);
437     if (res != HC_SUCCESS) {
438         LOGE("Failed to import sym token! res: %d", res);
439     } else {
440         LOGI("Import sym token success!");
441     }
442     /* Clear sensitive data: authCode. */
443     (void)memset_s(authCode, DEV_AUTH_AUTH_CODE_SIZE, 0, DEV_AUTH_AUTH_CODE_SIZE);
444     ClearSensitiveStringInJson(in, FIELD_AUTH_CODE);
445     return res;
446 }
447 
AddToken(int32_t osAccountId,int32_t opCode,CJson * in)448 static int32_t AddToken(int32_t osAccountId, int32_t opCode, CJson *in)
449 {
450     LOGI("[Token]: Add sym token starting ...");
451     if (in == NULL) {
452         LOGE("Invalid params!");
453         return HC_ERR_NULL_PTR;
454     }
455     SymToken *symToken = CreateSymTokenByJson(in);
456     if (symToken == NULL) {
457         LOGE("Failed to create symToken from json!");
458         return HC_ERR_ALLOC_MEMORY;
459     }
460     g_dataMutex->lock(g_dataMutex);
461     int32_t res = AddSymTokenToVec(osAccountId, symToken);
462     if (res != HC_SUCCESS) {
463         g_dataMutex->unlock(g_dataMutex);
464         LOGE("Failed to add sym token to vec");
465         HcFree(symToken);
466         return res;
467     }
468     res = ImportSymTokenToKeyManager(symToken, in, opCode);
469     if (res != HC_SUCCESS) {
470         g_dataMutex->unlock(g_dataMutex);
471         LOGE("Failed to import sym token!");
472         return res;
473     }
474     res = SaveOsSymTokensDb(osAccountId);
475     g_dataMutex->unlock(g_dataMutex);
476     if (res != HC_SUCCESS) {
477         LOGE("Failed to save token to db");
478         return res;
479     }
480     LOGI("[Token]: Add sym token success");
481     return HC_SUCCESS;
482 }
483 
PopSymTokenFromVec(int32_t osAccountId,const char * userId,const char * deviceId)484 static SymToken *PopSymTokenFromVec(int32_t osAccountId, const char *userId, const char *deviceId)
485 {
486     LOGI("Start to pop token from database!");
487     OsSymTokensInfo *info = GetTokensInfoByOsAccountId(osAccountId);
488     if (info == NULL) {
489         LOGE("Failed to get tokens by os account id. [OsAccountId]: %d", osAccountId);
490         return NULL;
491     }
492     uint32_t index = 0;
493     SymToken **token = NULL;
494     while (index < HC_VECTOR_SIZE(&info->tokens)) {
495         token = info->tokens.getp(&info->tokens, index);
496         if ((token == NULL) || (*token == NULL) || (!IsTokenMatch(*token, userId, deviceId))) {
497             index++;
498             continue;
499         }
500         SymToken *deleteToken = NULL;
501         HC_VECTOR_POPELEMENT(&info->tokens, &deleteToken, index);
502         LOGI("Pop a token from database successfully!");
503         return deleteToken;
504     }
505     LOGE("The token is not found!");
506     return NULL;
507 }
508 
DeleteSymTokenFromKeyManager(const SymToken * token)509 static int32_t DeleteSymTokenFromKeyManager(const SymToken *token)
510 {
511     uint8_t *keyAliasVal = (uint8_t *)HcMalloc(SHA256_LEN, 0);
512     if (keyAliasVal == NULL) {
513         LOGE("Failed to allocate keyAliasVal memory!");
514         return HC_ERR_ALLOC_MEMORY;
515     }
516     Uint8Buff keyAlias = {
517         .val = keyAliasVal,
518         .length = SHA256_LEN
519     };
520     int32_t res = GenerateKeyAlias(token->userId, token->deviceId, &keyAlias);
521     if (res != HC_SUCCESS) {
522         LOGE("Failed to generate authCode key alias!");
523         HcFree(keyAliasVal);
524         return res;
525     }
526     res = GetLoaderInstance()->deleteKey(&keyAlias);
527     HcFree(keyAliasVal);
528     if (res != HC_SUCCESS) {
529         LOGE("Failed to delete sym token! res: %d", res);
530     } else {
531         LOGI("Delete sym token success!");
532     }
533     return res;
534 }
535 
DeleteToken(int32_t osAccountId,const char * userId,const char * deviceId)536 static int32_t DeleteToken(int32_t osAccountId, const char *userId, const char *deviceId)
537 {
538     LOGI("[Token]: Delete sym token starting ...");
539     if ((userId == NULL) || (deviceId == NULL)) {
540         LOGE("Invalid params");
541         return HC_ERR_NULL_PTR;
542     }
543     g_dataMutex->lock(g_dataMutex);
544     SymToken *symToken = PopSymTokenFromVec(osAccountId, userId, deviceId);
545     if (symToken == NULL) {
546         g_dataMutex->unlock(g_dataMutex);
547         return HC_ERR_NULL_PTR;
548     }
549     int32_t res = DeleteSymTokenFromKeyManager(symToken);
550     HcFree(symToken);
551     if (res != HC_SUCCESS) {
552         g_dataMutex->unlock(g_dataMutex);
553         LOGE("Failed to delete sym token!");
554         return res;
555     }
556     res = SaveOsSymTokensDb(osAccountId);
557     g_dataMutex->unlock(g_dataMutex);
558     if (res != HC_SUCCESS) {
559         LOGE("Failed to save token to db, account id is: %d", osAccountId);
560         return res;
561     }
562     LOGI("[Token]: Delete sym token success");
563     return HC_SUCCESS;
564 }
565 
LoadOsSymTokensDb(int32_t osAccountId)566 static void LoadOsSymTokensDb(int32_t osAccountId)
567 {
568     OsSymTokensInfo info;
569     info.osAccountId = osAccountId;
570     info.tokens = CreateSymTokenVec();
571     if (ReadTokensFromFile(osAccountId, &info.tokens) != HC_SUCCESS) {
572         DestroySymTokenVec(&info.tokens);
573         return;
574     }
575     if (g_symTokensDb.pushBackT(&g_symTokensDb, info) == NULL) {
576         LOGE("Failed to push osAccountInfo to database!");
577         ClearSymTokenVec(&info.tokens);
578     }
579     LOGI("Load os account db successfully! [Id]: %d", osAccountId);
580 }
581 
LoadTokenDb(void)582 static void LoadTokenDb(void)
583 {
584     StringVector dbNameVec = CreateStrVector();
585     HcFileGetSubFileName(GetAccountStoragePath(), &dbNameVec);
586     uint32_t index;
587     HcString *dbName = NULL;
588     FOR_EACH_HC_VECTOR(dbNameVec, index, dbName) {
589         int32_t osAccountId;
590         const char *name = StringGet(dbName);
591         if (name == NULL) {
592             continue;
593         }
594         if (strcmp(name, "account_data_sym.dat") == 0) {
595             LoadOsSymTokensDb(DEFAULT_OS_ACCOUNT);
596         } else if (sscanf_s(name, "account_data_sym%d.dat", &osAccountId) == 1) {
597             LoadOsSymTokensDb(osAccountId);
598         }
599     }
600     DestroyStrVector(&dbNameVec);
601 }
602 
ClearSymTokenVec(SymTokenVec * vec)603 void ClearSymTokenVec(SymTokenVec *vec)
604 {
605     uint32_t index;
606     SymToken **token;
607     FOR_EACH_HC_VECTOR(*vec, index, token) {
608         HcFree(*token);
609     }
610     DESTROY_HC_VECTOR(SymTokenVec, vec);
611 }
612 
GetSymTokenManager(void)613 SymTokenManager *GetSymTokenManager(void)
614 {
615     return &g_symTokenManager;
616 }
617 
InitSymTokenManager(void)618 void InitSymTokenManager(void)
619 {
620     if (g_dataMutex == NULL) {
621         g_dataMutex = (HcMutex *)HcMalloc(sizeof(HcMutex), 0);
622         if (g_dataMutex == NULL) {
623             LOGE("Alloc account database mutex failed.");
624             return;
625         }
626         if (InitHcMutex(g_dataMutex) != HC_SUCCESS) {
627             LOGE("Init account mutex failed.");
628             HcFree(g_dataMutex);
629             g_dataMutex = NULL;
630             return;
631         }
632     }
633     g_dataMutex->lock(g_dataMutex);
634     (void)memset_s(&g_symTokenManager, sizeof(SymTokenManager), 0, sizeof(SymTokenManager));
635     g_symTokenManager.addToken = AddToken;
636     g_symTokenManager.deleteToken = DeleteToken;
637     g_symTokenManager.generateKeyAlias = GenerateKeyAlias;
638     g_symTokensDb = CREATE_HC_VECTOR(SymTokensDb);
639     LoadTokenDb();
640     g_dataMutex->unlock(g_dataMutex);
641 }
642 
DestroySymTokenManager(void)643 void DestroySymTokenManager(void)
644 {
645     g_dataMutex->lock(g_dataMutex);
646     (void)memset_s(&g_symTokenManager, sizeof(SymTokenManager), 0, sizeof(SymTokenManager));
647     uint32_t index;
648     OsSymTokensInfo *info = NULL;
649     FOR_EACH_HC_VECTOR(g_symTokensDb, index, info) {
650         ClearSymTokenVec(&info->tokens);
651     }
652     DESTROY_HC_VECTOR(SymTokensDb, &g_symTokensDb);
653     g_dataMutex->unlock(g_dataMutex);
654     DestroyHcMutex(g_dataMutex);
655     HcFree(g_dataMutex);
656     g_dataMutex = NULL;
657 }
658