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