1 /*
2  * Copyright (C) 2022-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 "asy_token_manager.h"
17 
18 #include "account_auth_plugin_proxy.h"
19 #include "account_module_defines.h"
20 #include "account_related_cred_plugin.h"
21 #include "alg_loader.h"
22 #include "common_defs.h"
23 #include "hc_dev_info.h"
24 #include "hal_error.h"
25 #include "hc_file.h"
26 #include "hc_log.h"
27 #include "hc_mutex.h"
28 #include "hc_types.h"
29 #include "os_account_adapter.h"
30 #include "security_label_adapter.h"
31 #include "string_util.h"
32 
33 IMPLEMENT_HC_VECTOR(AccountTokenVec, AccountToken*, 1)
34 
35 typedef struct {
36     int32_t osAccountId;
37     AccountTokenVec tokens;
38 } OsAccountTokenInfo;
39 
40 DECLARE_HC_VECTOR(AccountTokenDb, OsAccountTokenInfo)
41 IMPLEMENT_HC_VECTOR(AccountTokenDb, OsAccountTokenInfo, 1)
42 
43 #define MAX_DB_PATH_LEN 256
44 #define SELF_ECC_KEY_LEN 32
45 
46 AccountAuthTokenManager g_asyTokenManager;
47 
48 static const AlgLoader *g_algLoader = NULL;
49 static bool g_isInitial = false;
50 static AccountTokenDb g_accountTokenDb;
51 static HcMutex *g_accountDbMutex;
52 
GeneratePkInfoFromJson(PkInfo * info,const CJson * pkInfoJson)53 static int32_t GeneratePkInfoFromJson(PkInfo *info, const CJson *pkInfoJson)
54 {
55     if (GetByteFromJson(pkInfoJson, FIELD_DEVICE_PK, info->devicePk.val, info->devicePk.length) != HC_SUCCESS) {
56         LOGE("get devicePk failed");
57         return HC_ERR_JSON_GET;
58     }
59     const char *devicePk = GetStringFromJson(pkInfoJson, FIELD_DEVICE_PK);
60     info->devicePk.length = HcStrlen(devicePk) / BYTE_TO_HEX_OPER_LENGTH;
61     const char *version = GetStringFromJson(pkInfoJson, FIELD_VERSION);
62     if (version == NULL) {
63         LOGE("get version failed");
64         return HC_ERR_JSON_GET;
65     }
66     if (memcpy_s(info->version.val, info->version.length, version, HcStrlen(version) + 1) != EOK) {
67         LOGE("memcpy_s version failed");
68         return HC_ERR_MEMORY_COPY;
69     }
70     info->version.length = HcStrlen(version) + 1;
71     const char *deviceId = GetStringFromJson(pkInfoJson, FIELD_DEVICE_ID);
72     if (deviceId == NULL) {
73         LOGE("get deviceId failed");
74         return HC_ERR_JSON_GET;
75     }
76     if (memcpy_s(info->deviceId.val, info->deviceId.length, deviceId, HcStrlen(deviceId) + 1) != EOK) {
77         LOGE("memcpy_s deviceId failed");
78         return HC_ERR_MEMORY_COPY;
79     }
80     info->deviceId.length = HcStrlen(deviceId) + 1;
81     const char *userId = GetStringFromJson(pkInfoJson, FIELD_USER_ID);
82     if (userId == NULL) {
83         LOGE("get userId failed");
84         return HC_ERR_JSON_GET;
85     }
86     if (memcpy_s(info->userId.val, info->userId.length, userId, HcStrlen(userId) + 1) != EOK) {
87         LOGE("memcpy_s userId failed");
88         return HC_ERR_MEMORY_COPY;
89     }
90     info->userId.length = HcStrlen(userId) + 1;
91     return HC_SUCCESS;
92 }
93 
GetTokenPathCe(int32_t osAccountId,char * tokenPath,uint32_t pathBufferLen)94 static bool GetTokenPathCe(int32_t osAccountId, char *tokenPath, uint32_t pathBufferLen)
95 {
96     const char *beginPath = GetStorageDirPathCe();
97     if (beginPath == NULL) {
98         LOGE("Failed to get the storage path!");
99         return false;
100     }
101     if (sprintf_s(tokenPath, pathBufferLen, "%s/%d/deviceauth/account/account_data_asy.dat",
102         beginPath, osAccountId) <= 0) {
103         LOGE("Failed to generate token path!");
104         return false;
105     }
106     return true;
107 }
108 
GetTokenPathDe(int32_t osAccountId,char * tokenPath,uint32_t pathBufferLen)109 static bool GetTokenPathDe(int32_t osAccountId, char *tokenPath, uint32_t pathBufferLen)
110 {
111     const char *beginPath = GetAccountStoragePath();
112     if (beginPath == NULL) {
113         LOGE("Failed to get the account storage path!");
114         return false;
115     }
116     int32_t writeByteNum;
117     if (osAccountId == DEFAULT_OS_ACCOUNT) {
118         writeByteNum = sprintf_s(tokenPath, pathBufferLen, "%s/account_data_asy.dat", beginPath);
119     } else {
120         writeByteNum = sprintf_s(tokenPath, pathBufferLen, "%s/account_data_asy%d.dat", beginPath, osAccountId);
121     }
122     if (writeByteNum <= 0) {
123         LOGE("sprintf_s fail!");
124         return false;
125     }
126     return true;
127 }
128 
GetTokenPath(int32_t osAccountId,char * tokenPath,uint32_t pathBufferLen)129 static bool GetTokenPath(int32_t osAccountId, char *tokenPath, uint32_t pathBufferLen)
130 {
131     if (IsOsAccountSupported()) {
132         return GetTokenPathCe(osAccountId, tokenPath, pathBufferLen);
133     } else {
134         return GetTokenPathDe(osAccountId, tokenPath, pathBufferLen);
135     }
136 }
137 
GenerateTokenFromJson(const CJson * tokenJson,AccountToken * token)138 static int32_t GenerateTokenFromJson(const CJson *tokenJson, AccountToken *token)
139 {
140     CJson *pkInfoJson = GetObjFromJson(tokenJson, FIELD_PK_INFO);
141     if (pkInfoJson == NULL) {
142         LOGE("Failed to get pkInfoJson");
143         return HC_ERR_JSON_GET;
144     }
145     char *pkInfoStr = PackJsonToString(pkInfoJson);
146     if (pkInfoStr == NULL) {
147         LOGE("Pack pkInfoStr failed");
148         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
149     }
150     if (memcpy_s(token->pkInfoStr.val, token->pkInfoStr.length, pkInfoStr, HcStrlen(pkInfoStr) + 1) != EOK) {
151         LOGE("Memcpy failed for pkInfoStr");
152         FreeJsonString(pkInfoStr);
153         return HC_ERR_MEMORY_COPY;
154     }
155     token->pkInfoStr.length = HcStrlen(pkInfoStr) + 1;
156     FreeJsonString(pkInfoStr);
157     if (GetByteFromJson(tokenJson, FIELD_PK_INFO_SIGNATURE, token->pkInfoSignature.val,
158         token->pkInfoSignature.length) != HC_SUCCESS) {
159         LOGE("Get pkInfoSignature failed");
160         return HC_ERR_JSON_GET;
161     }
162     const char *signatureStr = GetStringFromJson(tokenJson, FIELD_PK_INFO_SIGNATURE);
163     token->pkInfoSignature.length = HcStrlen(signatureStr) / BYTE_TO_HEX_OPER_LENGTH;
164     if (GetByteFromJson(tokenJson, FIELD_SERVER_PK, token->serverPk.val,
165         token->serverPk.length) != HC_SUCCESS) {
166         LOGE("Get serverPk failed");
167         return HC_ERR_JSON_GET;
168     }
169     const char *serverPkStr = GetStringFromJson(tokenJson, FIELD_SERVER_PK);
170     token->serverPk.length = HcStrlen(serverPkStr) / BYTE_TO_HEX_OPER_LENGTH;
171     int32_t ret = GeneratePkInfoFromJson(&token->pkInfo, pkInfoJson);
172     if (ret != HC_SUCCESS) {
173         LOGE("Generate pkInfo failed");
174         return ret;
175     }
176     return HC_SUCCESS;
177 }
178 
CreateTokensFromJson(CJson * tokensJson,AccountTokenVec * vec)179 static int32_t CreateTokensFromJson(CJson *tokensJson, AccountTokenVec *vec)
180 {
181     int32_t tokenNum = GetItemNum(tokensJson);
182     int32_t ret;
183     for (int32_t i = 0; i < tokenNum; i++) {
184         CJson *tokenJson = GetItemFromArray(tokensJson, i);
185         if (tokenJson == NULL) {
186             LOGE("Token json is null");
187             ClearAccountTokenVec(vec);
188             return HC_ERR_JSON_GET;
189         }
190         AccountToken *token = CreateAccountToken();
191         if (token == NULL) {
192             LOGE("Failed to create token");
193             ClearAccountTokenVec(vec);
194             return HC_ERR_ALLOC_MEMORY;
195         }
196         ret = GenerateTokenFromJson(tokenJson, token);
197         if (ret != HC_SUCCESS) {
198             LOGE("Generate token failed");
199             DestroyAccountToken(token);
200             ClearAccountTokenVec(vec);
201             return ret;
202         }
203         if (vec->pushBackT(vec, token) == NULL) {
204             LOGE("Failed to push token to vec");
205             DestroyAccountToken(token);
206             ClearAccountTokenVec(vec);
207             return HC_ERR_MEMORY_COPY;
208         }
209     }
210     return HC_SUCCESS;
211 }
212 
ReadTokensFromFile(AccountTokenVec * vec,const char * tokenPath)213 static int32_t ReadTokensFromFile(AccountTokenVec *vec, const char *tokenPath)
214 {
215     FileHandle file = { 0 };
216     int32_t ret = HcFileOpen(tokenPath, MODE_FILE_READ, &file);
217     if (ret != HC_SUCCESS) {
218         LOGE("Open token file failed");
219         return ret;
220     }
221     SetSecurityLabel(tokenPath, SECURITY_LABEL_S2);
222     int32_t fileSize = HcFileSize(file);
223     if (fileSize <= 0) {
224         LOGE("file size stat failed");
225         HcFileClose(file);
226         return HC_ERROR;
227     }
228     char *fileData = (char *)HcMalloc(fileSize, 0);
229     if (fileData == NULL) {
230         LOGE("Malloc file data failed");
231         HcFileClose(file);
232         return HC_ERR_ALLOC_MEMORY;
233     }
234     if (HcFileRead(file, fileData, fileSize) != fileSize) {
235         LOGE("fileData read failed");
236         HcFileClose(file);
237         HcFree(fileData);
238         return HC_ERROR;
239     }
240     HcFileClose(file);
241     CJson *readJsonFile = CreateJsonFromString(fileData);
242     HcFree(fileData);
243     if (readJsonFile == NULL) {
244         LOGE("fileData parse failed");
245         return HC_ERR_JSON_CREATE;
246     }
247     ret = CreateTokensFromJson(readJsonFile, vec);
248     FreeJson(readJsonFile);
249     if (ret != HC_SUCCESS) {
250         LOGE("Failed to create tokens from json");
251     }
252     return ret;
253 }
254 
WriteTokensJsonToFile(CJson * tokensJson,const char * tokenPath)255 static int32_t WriteTokensJsonToFile(CJson *tokensJson, const char *tokenPath)
256 {
257     char *storeJsonString = PackJsonToString(tokensJson);
258     if (storeJsonString == NULL) {
259         LOGE("Pack stored json to string failed.");
260         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
261     }
262     FileHandle file = { 0 };
263     int32_t ret = HcFileOpen(tokenPath, MODE_FILE_WRITE, &file);
264     if (ret != HC_SUCCESS) {
265         LOGE("Open token file failed.");
266         FreeJsonString(storeJsonString);
267         return ret;
268     }
269     SetSecurityLabel(tokenPath, SECURITY_LABEL_S2);
270     int32_t fileSize = (int32_t)(HcStrlen(storeJsonString) + 1);
271     if (HcFileWrite(file, storeJsonString, fileSize) != fileSize) {
272         LOGE("Failed to write token array to file.");
273         ret = HC_ERR_FILE;
274     }
275     FreeJsonString(storeJsonString);
276     HcFileClose(file);
277     return ret;
278 }
279 
GenerateJsonFromToken(AccountToken * token,CJson * tokenJson)280 static int32_t GenerateJsonFromToken(AccountToken *token, CJson *tokenJson)
281 {
282     CJson *pkInfoJson = CreateJsonFromString((const char *)token->pkInfoStr.val);
283     if (pkInfoJson == NULL) {
284         LOGE("Failed to create pkInfoJson");
285         return HC_ERR_JSON_CREATE;
286     }
287     if (AddObjToJson(tokenJson, FIELD_PK_INFO, pkInfoJson) != HC_SUCCESS) {
288         LOGE("Add pkInfoJson to json failed");
289         FreeJson(pkInfoJson);
290         return HC_ERR_JSON_ADD;
291     }
292     FreeJson(pkInfoJson);
293     if (AddByteToJson(tokenJson, FIELD_PK_INFO_SIGNATURE, token->pkInfoSignature.val,
294         token->pkInfoSignature.length) != HC_SUCCESS) {
295         LOGE("Add pkInfoSignature to json failed");
296         return HC_ERR_JSON_ADD;
297     }
298     if (AddByteToJson(tokenJson, FIELD_SERVER_PK, token->serverPk.val,
299         token->serverPk.length) != HC_SUCCESS) {
300         LOGE("Add serverPk to json failed");
301         return HC_ERR_JSON_ADD;
302     }
303     return HC_SUCCESS;
304 }
305 
SaveTokensToFile(const AccountTokenVec * vec,const char * tokenPath)306 static int32_t SaveTokensToFile(const AccountTokenVec *vec, const char *tokenPath)
307 {
308     CJson *storeJson = CreateJsonArray();
309     if (storeJson == NULL) {
310         LOGE("Create json failed when save tokens to file.");
311         return HC_ERR_JSON_CREATE;
312     }
313     int32_t ret;
314     uint32_t index;
315     AccountToken **token;
316     FOR_EACH_HC_VECTOR(*vec, index, token) {
317         CJson *tokenJson = CreateJson();
318         if (tokenJson == NULL) {
319             LOGE("Create token json failed.");
320             FreeJson(storeJson);
321             return HC_ERR_JSON_CREATE;
322         }
323         ret = GenerateJsonFromToken(*token, tokenJson);
324         if (ret != HC_SUCCESS) {
325             LOGE("Generate json from token failed");
326             FreeJson(tokenJson);
327             FreeJson(storeJson);
328             return ret;
329         }
330         if (AddObjToArray(storeJson, tokenJson) != HC_SUCCESS) {
331             LOGE("Add token json to array failed");
332             FreeJson(tokenJson);
333             FreeJson(storeJson);
334             return HC_ERR_JSON_ADD;
335         }
336     }
337     ret = WriteTokensJsonToFile(storeJson, tokenPath);
338     FreeJson(storeJson);
339     return ret;
340 }
341 
GenerateKeyAlias(const char * userId,const char * deviceId,Uint8Buff * alias,bool isServerPkAlias)342 static int32_t GenerateKeyAlias(const char *userId, const char *deviceId, Uint8Buff *alias,
343     bool isServerPkAlias)
344 {
345     if ((userId == NULL) || (deviceId == NULL) || (alias == NULL)) {
346         LOGE("Invalid input params");
347         return HC_ERR_NULL_PTR;
348     }
349     uint32_t userIdLen = HcStrlen(userId);
350     uint32_t deviceIdLen = HcStrlen(deviceId);
351     const char *serverPkTag = "serverPk";
352     uint32_t serverPkTagLen = HcStrlen(serverPkTag);
353     uint32_t aliasStrLen;
354     if (isServerPkAlias) {
355         aliasStrLen = userIdLen + deviceIdLen + serverPkTagLen;
356     } else {
357         aliasStrLen = userIdLen + deviceIdLen;
358     }
359     uint8_t *aliasStr = (uint8_t *)HcMalloc(aliasStrLen, 0);
360     if (aliasStr == NULL) {
361         LOGE("Failed to malloc for self key aliasStr.");
362         return HC_ERR_ALLOC_MEMORY;
363     }
364     Uint8Buff aliasBuff = {
365         aliasStr,
366         aliasStrLen
367     };
368     if (memcpy_s(aliasBuff.val, aliasBuff.length, userId, userIdLen) != EOK) {
369         LOGE("Failed to copy userId.");
370         HcFree(aliasStr);
371         return HC_ERR_MEMORY_COPY;
372     }
373     if (memcpy_s(aliasBuff.val + userIdLen, aliasBuff.length - userIdLen,
374         deviceId, deviceIdLen) != EOK) {
375         LOGE("Failed to copy deviceId.");
376         HcFree(aliasStr);
377         return HC_ERR_MEMORY_COPY;
378     }
379     if (isServerPkAlias && (memcpy_s(aliasBuff.val + userIdLen + deviceIdLen,
380         aliasBuff.length - userIdLen - deviceIdLen, serverPkTag, serverPkTagLen) != EOK)) {
381         LOGE("Failed to copy serverPkTag.");
382         HcFree(aliasStr);
383         return HC_ERR_MEMORY_COPY;
384     }
385     int32_t ret = g_algLoader->sha256(&aliasBuff, alias);
386     HcFree(aliasStr);
387     if (ret != HAL_SUCCESS) {
388         LOGE("Compute alias failed");
389     }
390     return ret;
391 }
392 
GenerateServerPkAlias(CJson * pkInfoJson,Uint8Buff * alias)393 static int32_t GenerateServerPkAlias(CJson *pkInfoJson, Uint8Buff *alias)
394 {
395     const char *userId = GetStringFromJson(pkInfoJson, FIELD_USER_ID);
396     if (userId == NULL) {
397         LOGE("Failed to get userId");
398         return HC_ERR_JSON_GET;
399     }
400     const char *deviceId = GetStringFromJson(pkInfoJson, FIELD_DEVICE_ID);
401     if (deviceId == NULL) {
402         LOGE("Failed to get deviceId");
403         return HC_ERR_JSON_GET;
404     }
405     return GenerateKeyAlias(userId, deviceId, alias, true);
406 }
407 
ImportServerPk(int32_t osAccountId,const CJson * credJson,Uint8Buff * keyAlias,uint8_t * serverPk,Algorithm alg)408 static int32_t ImportServerPk(int32_t osAccountId, const CJson *credJson, Uint8Buff *keyAlias, uint8_t *serverPk,
409     Algorithm alg)
410 {
411     const char *serverPkStr = GetStringFromJson(credJson, FIELD_SERVER_PK);
412     if (serverPkStr == NULL) {
413         LOGE("Failed to get serverPkStr");
414         return HC_ERR_JSON_GET;
415     }
416     uint32_t serverPkLen = HcStrlen(serverPkStr) / BYTE_TO_HEX_OPER_LENGTH;
417     Uint8Buff keyBuff = {
418         .val = serverPk,
419         .length = serverPkLen
420     };
421     int32_t authId = 0;
422     Uint8Buff authIdBuff = { (uint8_t *)&authId, sizeof(int32_t) };
423     ExtraInfo extInfo = { authIdBuff, -1, -1 };
424     KeyParams keyParams = { { keyAlias->val, keyAlias->length, true }, false, osAccountId };
425     return g_algLoader->importPublicKey(&keyParams, &keyBuff, alg, &extInfo);
426 }
427 
VerifyPkInfoSignature(int32_t osAccountId,const CJson * credJson,CJson * pkInfoJson,uint8_t * signature,Uint8Buff * keyAlias)428 static int32_t VerifyPkInfoSignature(int32_t osAccountId, const CJson *credJson, CJson *pkInfoJson,
429     uint8_t *signature, Uint8Buff *keyAlias)
430 {
431     char *pkInfoStr = PackJsonToString(pkInfoJson);
432     if (pkInfoStr == NULL) {
433         LOGE("Failed to pack pkInfoStr");
434         return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
435     }
436     Uint8Buff messageBuff = {
437         .val = (uint8_t *)pkInfoStr,
438         .length = HcStrlen(pkInfoStr) + 1
439     };
440     const char *signatureStr = GetStringFromJson(credJson, FIELD_PK_INFO_SIGNATURE);
441     if (signatureStr == NULL) {
442         LOGE("Failed to get signatureStr");
443         FreeJsonString(pkInfoStr);
444         return HC_ERR_JSON_GET;
445     }
446     uint32_t signatureLen = HcStrlen(signatureStr) / BYTE_TO_HEX_OPER_LENGTH;
447     Uint8Buff signatureBuff = {
448         .val = signature,
449         .length = signatureLen
450     };
451     KeyParams keyParams = { { keyAlias->val, keyAlias->length, true }, false, osAccountId };
452     int32_t ret = g_algLoader->verify(&keyParams, &messageBuff, P256, &signatureBuff);
453     FreeJsonString(pkInfoStr);
454     return ret;
455 }
456 
DoImportServerPkAndVerify(int32_t osAccountId,const CJson * credJson,uint8_t * signature,uint8_t * serverPk,CJson * pkInfoJson)457 static int32_t DoImportServerPkAndVerify(int32_t osAccountId, const CJson *credJson, uint8_t *signature,
458     uint8_t *serverPk, CJson *pkInfoJson)
459 {
460     uint8_t *keyAliasValue = (uint8_t *)HcMalloc(SHA256_LEN, 0);
461     if (keyAliasValue == NULL) {
462         LOGE("Malloc keyAliasValue failed");
463         return HC_ERR_ALLOC_MEMORY;
464     }
465     Uint8Buff keyAlias = {
466         .val = keyAliasValue,
467         .length = SHA256_LEN
468     };
469     g_accountDbMutex->lock(g_accountDbMutex);
470     int32_t ret = GenerateServerPkAlias(pkInfoJson, &keyAlias);
471     if (ret != HC_SUCCESS) {
472         LOGE("Failed to generate serverPk alias");
473         g_accountDbMutex->unlock(g_accountDbMutex);
474         HcFree(keyAliasValue);
475         return ret;
476     }
477     const char *version = GetStringFromJson(pkInfoJson, FIELD_VERSION);
478     if (version == NULL) {
479         LOGE("Failed to get version from pkInfo");
480         g_accountDbMutex->unlock(g_accountDbMutex);
481         HcFree(keyAliasValue);
482         return HC_ERR_JSON_GET;
483     }
484     ret = ImportServerPk(osAccountId, credJson, &keyAlias, serverPk, P256);
485     if (ret != HAL_SUCCESS) {
486         LOGE("Import server public key failed");
487         g_accountDbMutex->unlock(g_accountDbMutex);
488         HcFree(keyAliasValue);
489         return ret;
490     }
491     LOGI("Import server public key success, start to verify");
492     ret = VerifyPkInfoSignature(osAccountId, credJson, pkInfoJson, signature, &keyAlias);
493     g_accountDbMutex->unlock(g_accountDbMutex);
494     HcFree(keyAliasValue);
495     if (ret != HC_SUCCESS) {
496         LOGE("Verify pkInfoSignature failed");
497     }
498     return ret;
499 }
500 
VerifySignature(int32_t osAccountId,const CJson * credJson)501 static int32_t VerifySignature(int32_t osAccountId, const CJson *credJson)
502 {
503     LOGI("start verify server message!");
504     uint8_t *signature = (uint8_t *)HcMalloc(SIGNATURE_SIZE, 0);
505     if (signature == NULL) {
506         LOGE("malloc signature fail!");
507         return HC_ERR_ALLOC_MEMORY;
508     }
509     if (GetByteFromJson(credJson, FIELD_PK_INFO_SIGNATURE, signature, SIGNATURE_SIZE) != EOK) {
510         LOGE("get pkInfoSignature fail");
511         HcFree(signature);
512         return HC_ERR_JSON_GET;
513     }
514     uint8_t *serverPk = (uint8_t *)HcMalloc(SERVER_PK_SIZE, 0);
515     if (serverPk == NULL) {
516         LOGE("malloc serverPk fail!");
517         HcFree(signature);
518         return HC_ERR_ALLOC_MEMORY;
519     }
520     if (GetByteFromJson(credJson, FIELD_SERVER_PK, serverPk, SERVER_PK_SIZE) != EOK) {
521         LOGE("get serverPk fail!");
522         HcFree(signature);
523         HcFree(serverPk);
524         return HC_ERR_JSON_GET;
525     }
526     CJson *pkInfoJson = GetObjFromJson(credJson, FIELD_PK_INFO);
527     if (pkInfoJson == NULL) {
528         LOGE("Failed to get pkInfoJson");
529         HcFree(signature);
530         HcFree(serverPk);
531         return HC_ERR_JSON_GET;
532     }
533     int32_t ret = DoImportServerPkAndVerify(osAccountId, credJson, signature, serverPk, pkInfoJson);
534     HcFree(signature);
535     HcFree(serverPk);
536     if (ret != HC_SUCCESS) {
537         LOGE("Verify pkInfoSignature failed");
538     } else {
539         LOGI("Verify pkInfoSignature success");
540     }
541     return ret;
542 }
543 
GeneratePkInfoFromInfo(const PkInfo * srcInfo,PkInfo * desInfo)544 static int32_t GeneratePkInfoFromInfo(const PkInfo *srcInfo, PkInfo *desInfo)
545 {
546     if (memcpy_s(desInfo->userId.val, desInfo->userId.length,
547         srcInfo->userId.val, srcInfo->userId.length) != EOK) {
548         LOGE("Memcpy for userId failed.");
549         return HC_ERR_MEMORY_COPY;
550     }
551     desInfo->userId.length = srcInfo->userId.length;
552     if (memcpy_s(desInfo->deviceId.val, desInfo->deviceId.length,
553         srcInfo->deviceId.val, srcInfo->deviceId.length) != EOK) {
554         LOGE("Memcpy for deviceId failed.");
555         return HC_ERR_MEMORY_COPY;
556     }
557     desInfo->deviceId.length = srcInfo->deviceId.length;
558     if (memcpy_s(desInfo->devicePk.val, desInfo->devicePk.length,
559         srcInfo->devicePk.val, srcInfo->devicePk.length) != EOK) {
560         LOGE("Memcpy for devicePk failed.");
561         return HC_ERR_MEMORY_COPY;
562     }
563     desInfo->devicePk.length = srcInfo->devicePk.length;
564     if (memcpy_s(desInfo->version.val, desInfo->version.length,
565         srcInfo->version.val, srcInfo->version.length) != EOK) {
566         LOGE("Memcpy for version failed.");
567         return HC_ERR_MEMORY_COPY;
568     }
569     desInfo->version.length = srcInfo->version.length;
570     return HC_SUCCESS;
571 }
572 
GenerateAccountTokenFromToken(const AccountToken * token,AccountToken * returnToken)573 static bool GenerateAccountTokenFromToken(const AccountToken *token, AccountToken *returnToken)
574 {
575     if (memcpy_s(returnToken->pkInfoStr.val, returnToken->pkInfoStr.length,
576         token->pkInfoStr.val, token->pkInfoStr.length) != EOK) {
577         LOGE("Memcpy for pkInfoStr failed.");
578         return false;
579     }
580     returnToken->pkInfoStr.length = token->pkInfoStr.length;
581     if (GeneratePkInfoFromInfo(&token->pkInfo, &returnToken->pkInfo) != HC_SUCCESS) {
582         LOGE("Failed to generate pkInfo");
583         return false;
584     }
585     if (memcpy_s(returnToken->serverPk.val, returnToken->serverPk.length,
586         token->serverPk.val, token->serverPk.length) != EOK) {
587         LOGE("Memcpy for serverPk failed.");
588         return false;
589     }
590     returnToken->serverPk.length = token->serverPk.length;
591     if (memcpy_s(returnToken->pkInfoSignature.val, returnToken->pkInfoSignature.length,
592         token->pkInfoSignature.val, token->pkInfoSignature.length) != EOK) {
593         LOGE("Memcpy for pkInfoSignature failed.");
594         return false;
595     }
596     returnToken->pkInfoSignature.length = token->pkInfoSignature.length;
597     return true;
598 }
599 
DeepCopyToken(const AccountToken * token)600 static AccountToken *DeepCopyToken(const AccountToken *token)
601 {
602     AccountToken *returnToken = CreateAccountToken();
603     if (returnToken == NULL) {
604         LOGE("Failed to create token");
605         return NULL;
606     }
607     if (!GenerateAccountTokenFromToken(token, returnToken)) {
608         LOGE("Generate token from exist token failed");
609         DestroyAccountToken(returnToken);
610         return NULL;
611     }
612     return returnToken;
613 }
614 
QueryTokenPtrIfMatch(const AccountTokenVec * vec,const char * userId,const char * deviceId)615 static AccountToken **QueryTokenPtrIfMatch(const AccountTokenVec *vec, const char *userId, const char *deviceId)
616 {
617     uint32_t index;
618     AccountToken **token;
619     FOR_EACH_HC_VECTOR(*vec, index, token) {
620         if ((strcmp(userId, (const char *)((*token)->pkInfo.userId.val)) == 0) &&
621             (strcmp(deviceId, (const char *)((*token)->pkInfo.deviceId.val)) == 0)) {
622             return token;
623         }
624     }
625     return NULL;
626 }
627 
GetTokenFromPlugin(int32_t osAccountId,AccountToken * token,const char * userId,const char * deviceId)628 static int32_t GetTokenFromPlugin(int32_t osAccountId, AccountToken *token, const char *userId, const char *deviceId)
629 {
630     CJson *input = CreateJson();
631     if (input == NULL) {
632         LOGE("Create input params json failed!");
633         return HC_ERR_JSON_CREATE;
634     }
635     CJson *output = CreateJson();
636     if (output == NULL) {
637         LOGE("Create output results json failed!");
638         FreeJson(input);
639         return HC_ERR_JSON_CREATE;
640     }
641     int32_t res = HC_ERR_JSON_ADD;
642     if (AddStringToJson(input, FIELD_USER_ID, userId) != HC_SUCCESS) {
643         goto ERR;
644     }
645     if (AddStringToJson(input, FIELD_DEVICE_ID, deviceId) != HC_SUCCESS) {
646         goto ERR;
647     }
648     GOTO_ERR_AND_SET_RET(ExcuteCredMgrCmd(osAccountId, QUERY_SELF_CREDENTIAL_INFO, input, output), res);
649     GOTO_ERR_AND_SET_RET(GenerateTokenFromJson(output, token), res);
650 ERR:
651     FreeJson(input);
652     FreeJson(output);
653     return res;
654 }
655 
DoExportPkAndCompare(int32_t osAccountId,const char * userId,const char * deviceId,const char * devicePk,Uint8Buff * keyAlias)656 static int32_t DoExportPkAndCompare(int32_t osAccountId, const char *userId, const char *deviceId,
657     const char *devicePk, Uint8Buff *keyAlias)
658 {
659     g_accountDbMutex->lock(g_accountDbMutex);
660     int32_t ret = GenerateKeyAlias(userId, deviceId, keyAlias, false);
661     if (ret != HC_SUCCESS) {
662         LOGE("Generate key alias failed.");
663         g_accountDbMutex->unlock(g_accountDbMutex);
664         return ret;
665     }
666     ret = g_algLoader->checkKeyExist(keyAlias, false, osAccountId);
667     if (ret != HAL_SUCCESS) {
668         LOGE("Key pair not exist.");
669         g_accountDbMutex->unlock(g_accountDbMutex);
670         return ret;
671     }
672     uint8_t *publicKeyVal = (uint8_t *)HcMalloc(PK_SIZE, 0);
673     if (publicKeyVal == NULL) {
674         LOGE("Malloc publicKeyVal failed");
675         g_accountDbMutex->unlock(g_accountDbMutex);
676         return HC_ERR_ALLOC_MEMORY;
677     }
678     Uint8Buff publicKey = {
679         .val = publicKeyVal,
680         .length = PK_SIZE
681     };
682     KeyParams keyParams = { { keyAlias->val, keyAlias->length, true }, false, osAccountId };
683     ret = g_algLoader->exportPublicKey(&keyParams, &publicKey);
684     if (ret != HAL_SUCCESS) {
685         LOGE("Failed to export public key");
686         HcFree(publicKeyVal);
687         g_accountDbMutex->unlock(g_accountDbMutex);
688         return ret;
689     }
690     g_accountDbMutex->unlock(g_accountDbMutex);
691     if (strcmp((const char *)devicePk, (const char *)publicKeyVal) == 0) {
692         HcFree(publicKeyVal);
693         return HC_SUCCESS;
694     }
695     HcFree(publicKeyVal);
696     return HC_ERROR;
697 }
698 
CheckDevicePk(int32_t osAccountId,const CJson * credJson)699 static int32_t CheckDevicePk(int32_t osAccountId, const CJson *credJson)
700 {
701     CJson *pkInfoJson = GetObjFromJson(credJson, FIELD_PK_INFO);
702     if (pkInfoJson == NULL) {
703         LOGE("Failed to get pkInfoJson");
704         return HC_ERR_JSON_GET;
705     }
706     const char *userId = GetStringFromJson(pkInfoJson, FIELD_USER_ID);
707     if (userId == NULL) {
708         LOGE("Failed to get userId");
709         return HC_ERR_JSON_GET;
710     }
711     const char *deviceId = GetStringFromJson(pkInfoJson, FIELD_DEVICE_ID);
712     if (deviceId == NULL) {
713         LOGE("Failed to get deviceId");
714         return HC_ERR_JSON_GET;
715     }
716     uint8_t *devicePk = (uint8_t *)HcMalloc(PK_SIZE, 0);
717     if (devicePk == NULL) {
718         LOGE("Malloc devicePk failed");
719         return HC_ERR_ALLOC_MEMORY;
720     }
721     if (GetByteFromJson(pkInfoJson, FIELD_DEVICE_PK, devicePk, PK_SIZE) != HC_SUCCESS) {
722         LOGE("Failed to get devicePk");
723         HcFree(devicePk);
724         return HC_ERR_JSON_GET;
725     }
726     uint8_t *keyAliasValue = (uint8_t *)HcMalloc(SHA256_LEN, 0);
727     if (keyAliasValue == NULL) {
728         LOGE("Malloc keyAliasValue failed");
729         HcFree(devicePk);
730         return HC_ERR_ALLOC_MEMORY;
731     }
732     Uint8Buff keyAlias = {
733         .val = keyAliasValue,
734         .length = SHA256_LEN
735     };
736     int32_t ret = DoExportPkAndCompare(osAccountId, userId, deviceId, (const char *)devicePk, &keyAlias);
737     HcFree(devicePk);
738     HcFree(keyAliasValue);
739     if (ret == HC_SUCCESS) {
740         LOGI("Check devicePk success");
741     } else {
742         LOGE("Check devicePk failed");
743     }
744     return ret;
745 }
746 
CheckUserId(const char * userId,const CJson * in)747 static int32_t CheckUserId(const char *userId, const CJson *in)
748 {
749     CJson *pkInfoJson = GetObjFromJson(in, FIELD_PK_INFO);
750     if (pkInfoJson == NULL) {
751         LOGE("Failed to get pkInfoJson");
752         return HC_ERR_JSON_GET;
753     }
754     const char *userIdFromPk = GetStringFromJson(pkInfoJson, FIELD_USER_ID);
755     if (userIdFromPk == NULL) {
756         LOGE("Failed to get userIdFromPk");
757         return HC_ERR_JSON_GET;
758     }
759     if (strcmp(userId, userIdFromPk) == 0) {
760         return HC_SUCCESS;
761     }
762     return HC_ERROR;
763 }
764 
CheckCredValidity(int32_t osAccountId,int32_t opCode,const CJson * in)765 static int32_t CheckCredValidity(int32_t osAccountId, int32_t opCode, const CJson *in)
766 {
767     const char *userId = GetStringFromJson(in, FIELD_USER_ID);
768     if (userId == NULL) {
769         LOGE("Failed to get userId");
770         return HC_ERR_JSON_GET;
771     }
772     int32_t ret = VerifySignature(osAccountId, in);
773     if (ret != HC_SUCCESS) {
774         LOGE("Verify server credential failed!");
775         return ret;
776     }
777     if (opCode == IMPORT_TRUSTED_CREDENTIALS) {
778         return HC_SUCCESS;
779     }
780     ret = CheckDevicePk(osAccountId, in);
781     if (ret != HC_SUCCESS) {
782         LOGE("Check devicePk failed!");
783         return ret;
784     }
785     ret = CheckUserId(userId, in);
786     if (ret != HC_SUCCESS) {
787         LOGE("Check userId failed!");
788     }
789     return ret;
790 }
791 
DoGenerateAndExportPk(int32_t osAccountId,const char * userId,const char * deviceId,Uint8Buff * keyAlias,Uint8Buff * publicKey)792 static int32_t DoGenerateAndExportPk(int32_t osAccountId, const char *userId, const char *deviceId,
793     Uint8Buff *keyAlias, Uint8Buff *publicKey)
794 {
795     g_accountDbMutex->lock(g_accountDbMutex);
796     int32_t ret = GenerateKeyAlias(userId, deviceId, keyAlias, false);
797     if (ret != HC_SUCCESS) {
798         LOGE("Generate key alias failed");
799         g_accountDbMutex->unlock(g_accountDbMutex);
800         return ret;
801     }
802     ret = g_algLoader->checkKeyExist(keyAlias, false, osAccountId);
803     KeyParams keyParams = { { keyAlias->val, keyAlias->length, true }, false, osAccountId };
804     if (ret != HAL_SUCCESS) {
805         LOGI("Key pair not exist, start to generate");
806         int32_t authId = 0;
807         Uint8Buff authIdBuff = { (uint8_t *)&authId, sizeof(int32_t) };
808         ExtraInfo extInfo = { authIdBuff, -1, -1 };
809         ret = g_algLoader->generateKeyPairWithStorage(&keyParams, SELF_ECC_KEY_LEN, P256,
810             KEY_PURPOSE_KEY_AGREE, &extInfo);
811     } else {
812         LOGI("Key pair already exists");
813     }
814     if (ret != HAL_SUCCESS) {
815         LOGE("Generate key pair failed");
816         g_accountDbMutex->unlock(g_accountDbMutex);
817         return ret;
818     }
819     ret = g_algLoader->exportPublicKey(&keyParams, publicKey);
820     g_accountDbMutex->unlock(g_accountDbMutex);
821     return ret;
822 }
823 
GetRegisterProof(int32_t osAccountId,const CJson * in,CJson * out)824 static int32_t GetRegisterProof(int32_t osAccountId, const CJson *in, CJson *out)
825 {
826     const char *userId = GetStringFromJson(in, FIELD_USER_ID);
827     if (userId == NULL) {
828         LOGE("Failed to get userId!");
829         return HC_ERR_JSON_GET;
830     }
831     const char *version = GetStringFromJson(in, FIELD_VERSION);
832     if (version == NULL) {
833         LOGE("Failed to get version!");
834         return HC_ERR_JSON_GET;
835     }
836     const char *deviceId = GetStringFromJson(in, FIELD_DEVICE_ID);
837     if (deviceId == NULL) {
838         LOGE("Failed to get deviceId!");
839         return HC_ERR_JSON_GET;
840     }
841     uint8_t *keyAliasValue = (uint8_t *)HcMalloc(SHA256_LEN, 0);
842     if (keyAliasValue == NULL) {
843         LOGE("Malloc keyAliasValue failed");
844         return HC_ERR_ALLOC_MEMORY;
845     }
846     Uint8Buff keyAlias = {
847         .val = keyAliasValue,
848         .length = SHA256_LEN
849     };
850     uint8_t *publicKeyVal = (uint8_t *)HcMalloc(PK_SIZE, 0);
851     if (publicKeyVal == NULL) {
852         LOGE("Malloc publicKeyVal failed");
853         HcFree(keyAliasValue);
854         return HC_ERR_ALLOC_MEMORY;
855     }
856     Uint8Buff publicKey = {
857         .val = publicKeyVal,
858         .length = PK_SIZE
859     };
860     int32_t ret = DoGenerateAndExportPk(osAccountId, userId, deviceId, &keyAlias, &publicKey);
861     HcFree(keyAliasValue);
862     if (ret != HC_SUCCESS) {
863         LOGE("exportPublicKey failed");
864         goto ERR;
865     }
866     GOTO_ERR_AND_SET_RET(AddByteToJson(out, FIELD_DEVICE_PK, publicKeyVal, publicKey.length), ret);
867     GOTO_ERR_AND_SET_RET(AddStringToJson(out, FIELD_USER_ID, userId), ret);
868     GOTO_ERR_AND_SET_RET(AddStringToJson(out, FIELD_DEVICE_ID, deviceId), ret);
869     GOTO_ERR_AND_SET_RET(AddStringToJson(out, FIELD_VERSION, version), ret);
870     LOGI("Generate register proof successfully!");
871 ERR:
872     HcFree(publicKeyVal);
873     return ret;
874 }
875 
DeleteKeyPair(int32_t osAccountId,AccountToken * token)876 static void DeleteKeyPair(int32_t osAccountId, AccountToken *token)
877 {
878     uint8_t *keyAliasValue = (uint8_t *)HcMalloc(SHA256_LEN, 0);
879     if (keyAliasValue == NULL) {
880         LOGE("Malloc keyAliasValue failed");
881         return;
882     }
883     Uint8Buff keyAlias = {
884         .val = keyAliasValue,
885         .length = SHA256_LEN
886     };
887     g_accountDbMutex->lock(g_accountDbMutex);
888     if (GenerateKeyAlias((const char *)token->pkInfo.userId.val,
889         (const char *)token->pkInfo.deviceId.val, &keyAlias, false) != HC_SUCCESS) {
890         LOGE("Failed to generate key alias");
891         HcFree(keyAliasValue);
892         g_accountDbMutex->unlock(g_accountDbMutex);
893         return;
894     }
895     if (g_algLoader->deleteKey(&keyAlias, false, osAccountId) != HAL_SUCCESS) {
896         LOGE("Failed to delete key pair");
897     } else {
898         LOGI("Delete key pair success");
899     }
900     HcFree(keyAliasValue);
901     g_accountDbMutex->unlock(g_accountDbMutex);
902 }
903 
LoadOsAccountTokenDb(int32_t osAccountId)904 static void LoadOsAccountTokenDb(int32_t osAccountId)
905 {
906     char tokenPath[MAX_DB_PATH_LEN] = { 0 };
907     if (!GetTokenPath(osAccountId, tokenPath, MAX_DB_PATH_LEN)) {
908         LOGE("Failed to get token path!");
909         return;
910     }
911     OsAccountTokenInfo info;
912     info.osAccountId = osAccountId;
913     info.tokens = CreateAccountTokenVec();
914     if (ReadTokensFromFile(&info.tokens, tokenPath) != HC_SUCCESS) {
915         DestroyAccountTokenVec(&info.tokens);
916         return;
917     }
918     if (g_accountTokenDb.pushBackT(&g_accountTokenDb, info) == NULL) {
919         LOGE("Failed to push osAccountInfo to database!");
920         ClearAccountTokenVec(&info.tokens);
921     }
922     LOGI("Load os account db successfully! [Id]: %d", osAccountId);
923 }
924 
TryMoveDeDataToCe(int32_t osAccountId)925 static void TryMoveDeDataToCe(int32_t osAccountId)
926 {
927     char tokenPathDe[MAX_DB_PATH_LEN] = { 0 };
928     if (!GetTokenPathDe(osAccountId, tokenPathDe, MAX_DB_PATH_LEN)) {
929         LOGE("Failed to get de file path!");
930         return;
931     }
932     char tokenPathCe[MAX_DB_PATH_LEN] = { 0 };
933     if (!GetTokenPathCe(osAccountId, tokenPathCe, MAX_DB_PATH_LEN)) {
934         LOGE("Failed to get ce file path!");
935         return;
936     }
937     OsAccountTokenInfo info;
938     info.osAccountId = osAccountId;
939     info.tokens = CreateAccountTokenVec();
940     if (ReadTokensFromFile(&info.tokens, tokenPathCe) == HC_SUCCESS) {
941         LOGI("Ce data exists, no need to move!");
942         ClearAccountTokenVec(&info.tokens);
943         return;
944     }
945     ClearAccountTokenVec(&info.tokens);
946     info.tokens = CreateAccountTokenVec();
947     if (ReadTokensFromFile(&info.tokens, tokenPathDe) != HC_SUCCESS) {
948         LOGI("De data not exist, no need to move!");
949         ClearAccountTokenVec(&info.tokens);
950         return;
951     }
952     if (SaveTokensToFile(&info.tokens, tokenPathCe) != HC_SUCCESS) {
953         LOGE("Failed to save tokens to ce file!");
954         ClearAccountTokenVec(&info.tokens);
955         return;
956     }
957     ClearAccountTokenVec(&info.tokens);
958     info.tokens = CreateAccountTokenVec();
959     if (ReadTokensFromFile(&info.tokens, tokenPathCe) != HC_SUCCESS) {
960         LOGE("Failed to read ce file data!");
961         ClearAccountTokenVec(&info.tokens);
962         return;
963     }
964     ClearAccountTokenVec(&info.tokens);
965     LOGI("Move de data to ce successfully, remove the de file!");
966     HcFileRemove(tokenPathDe);
967 }
968 
RemoveOsAccountTokenInfo(int32_t osAccountId)969 static void RemoveOsAccountTokenInfo(int32_t osAccountId)
970 {
971     uint32_t index = 0;
972     OsAccountTokenInfo *info = NULL;
973     FOR_EACH_HC_VECTOR(g_accountTokenDb, index, info) {
974         if (info->osAccountId == osAccountId) {
975             OsAccountTokenInfo deleteInfo;
976             HC_VECTOR_POPELEMENT(&g_accountTokenDb, &deleteInfo, index);
977             ClearAccountTokenVec(&deleteInfo.tokens);
978             return;
979         }
980     }
981 }
982 
LoadOsAccountTokenDbCe(int32_t osAccountId)983 static void LoadOsAccountTokenDbCe(int32_t osAccountId)
984 {
985     TryMoveDeDataToCe(osAccountId);
986     RemoveOsAccountTokenInfo(osAccountId);
987     LoadOsAccountTokenDb(osAccountId);
988 }
989 
OnOsAccountUnlocked(int32_t osAccountId)990 static void OnOsAccountUnlocked(int32_t osAccountId)
991 {
992     LOGI("Os account is unlocked, osAccountId: %d", osAccountId);
993     g_accountDbMutex->lock(g_accountDbMutex);
994     LoadOsAccountTokenDbCe(osAccountId);
995     g_accountDbMutex->unlock(g_accountDbMutex);
996 }
997 
OnOsAccountRemoved(int32_t osAccountId)998 static void OnOsAccountRemoved(int32_t osAccountId)
999 {
1000     LOGI("Os account is removed, osAccountId: %d", osAccountId);
1001     g_accountDbMutex->lock(g_accountDbMutex);
1002     RemoveOsAccountTokenInfo(osAccountId);
1003     g_accountDbMutex->unlock(g_accountDbMutex);
1004 }
1005 
IsOsAccountDataLoaded(int32_t osAccountId)1006 static bool IsOsAccountDataLoaded(int32_t osAccountId)
1007 {
1008     uint32_t index = 0;
1009     OsAccountTokenInfo *info = NULL;
1010     FOR_EACH_HC_VECTOR(g_accountTokenDb, index, info) {
1011         if (info->osAccountId == osAccountId) {
1012             return true;
1013         }
1014     }
1015     return false;
1016 }
1017 
LoadDataIfNotLoaded(int32_t osAccountId)1018 static void LoadDataIfNotLoaded(int32_t osAccountId)
1019 {
1020     if (IsOsAccountDataLoaded(osAccountId)) {
1021         return;
1022     }
1023     LOGI("Data has not been loaded, load it, osAccountId: %d", osAccountId);
1024     LoadOsAccountTokenDbCe(osAccountId);
1025 }
1026 
GetTokenInfoByOsAccountId(int32_t osAccountId)1027 static OsAccountTokenInfo *GetTokenInfoByOsAccountId(int32_t osAccountId)
1028 {
1029     if (IsOsAccountSupported()) {
1030         LoadDataIfNotLoaded(osAccountId);
1031     }
1032     uint32_t index = 0;
1033     OsAccountTokenInfo *info = NULL;
1034     FOR_EACH_HC_VECTOR(g_accountTokenDb, index, info) {
1035         if (info->osAccountId == osAccountId) {
1036             return info;
1037         }
1038     }
1039     LOGI("Create a new os account database cache! [Id]: %d", osAccountId);
1040     OsAccountTokenInfo newInfo;
1041     newInfo.osAccountId = osAccountId;
1042     newInfo.tokens = CreateAccountTokenVec();
1043     OsAccountTokenInfo *returnInfo = g_accountTokenDb.pushBackT(&g_accountTokenDb, newInfo);
1044     if (returnInfo == NULL) {
1045         LOGE("Failed to push OsAccountTokenInfo to database!");
1046         DestroyAccountTokenVec(&newInfo.tokens);
1047     }
1048     return returnInfo;
1049 }
1050 
SaveOsAccountTokenDb(int32_t osAccountId)1051 static int32_t SaveOsAccountTokenDb(int32_t osAccountId)
1052 {
1053     char tokenPath[MAX_DB_PATH_LEN] = { 0 };
1054     if (!GetTokenPath(osAccountId, tokenPath, MAX_DB_PATH_LEN)) {
1055         LOGE("Failed to get token path!");
1056         return HC_ERROR;
1057     }
1058     g_accountDbMutex->lock(g_accountDbMutex);
1059     OsAccountTokenInfo *info = GetTokenInfoByOsAccountId(osAccountId);
1060     if (info == NULL) {
1061         LOGE("Get token info by os account id failed");
1062         g_accountDbMutex->unlock(g_accountDbMutex);
1063         return HC_ERROR;
1064     }
1065     int32_t ret = SaveTokensToFile(&info->tokens, tokenPath);
1066     if (ret != HC_SUCCESS) {
1067         LOGE("Save tokens to file failed");
1068         g_accountDbMutex->unlock(g_accountDbMutex);
1069         return ret;
1070     }
1071     g_accountDbMutex->unlock(g_accountDbMutex);
1072     LOGI("Save an os account database successfully! [Id]: %d", osAccountId);
1073     return HC_SUCCESS;
1074 }
1075 
GetAccountToken(int32_t osAccountId,const char * userId,const char * deviceId)1076 static AccountToken *GetAccountToken(int32_t osAccountId, const char *userId, const char *deviceId)
1077 {
1078     g_accountDbMutex->lock(g_accountDbMutex);
1079     OsAccountTokenInfo *info = GetTokenInfoByOsAccountId(osAccountId);
1080     if (info == NULL) {
1081         LOGE("Failed to get token by osAccountId");
1082         g_accountDbMutex->unlock(g_accountDbMutex);
1083         return NULL;
1084     }
1085     AccountToken **token = QueryTokenPtrIfMatch(&info->tokens, userId, deviceId);
1086     if ((token == NULL) || (*token == NULL)) {
1087         LOGE("Query token failed");
1088         g_accountDbMutex->unlock(g_accountDbMutex);
1089         return NULL;
1090     }
1091     g_accountDbMutex->unlock(g_accountDbMutex);
1092     return *token;
1093 }
1094 
GetToken(int32_t osAccountId,AccountToken * token,const char * userId,const char * deviceId)1095 static int32_t GetToken(int32_t osAccountId, AccountToken *token, const char *userId, const char *deviceId)
1096 {
1097     if ((token == NULL) || (userId == NULL) || (deviceId == NULL)) {
1098         LOGE("Invalid input params");
1099         return HC_ERR_NULL_PTR;
1100     }
1101     if (HasAccountAuthPlugin() == HC_SUCCESS) {
1102         return GetTokenFromPlugin(osAccountId, token, userId, deviceId);
1103     }
1104     AccountToken *existToken = GetAccountToken(osAccountId, userId, deviceId);
1105     if (existToken == NULL) {
1106         LOGE("Token not exist");
1107         return HC_ERROR;
1108     }
1109     int32_t ret = GeneratePkInfoFromInfo(&existToken->pkInfo, &token->pkInfo);
1110     if (ret != HC_SUCCESS) {
1111         LOGE("Generate pkInfo failed");
1112         return ret;
1113     }
1114     GOTO_ERR_AND_SET_RET(memcpy_s(token->pkInfoStr.val, token->pkInfoStr.length,
1115         existToken->pkInfoStr.val, existToken->pkInfoStr.length), ret);
1116     token->pkInfoStr.length = existToken->pkInfoStr.length;
1117     GOTO_ERR_AND_SET_RET(memcpy_s(token->pkInfoSignature.val, token->pkInfoSignature.length,
1118         existToken->pkInfoSignature.val, existToken->pkInfoSignature.length), ret);
1119     token->pkInfoSignature.length = existToken->pkInfoSignature.length;
1120     GOTO_ERR_AND_SET_RET(memcpy_s(token->serverPk.val, token->serverPk.length,
1121         existToken->serverPk.val, existToken->serverPk.length), ret);
1122     token->serverPk.length = existToken->serverPk.length;
1123 
1124     ret = HC_SUCCESS;
1125     LOGI("GetToken successfully!");
1126 ERR:
1127     return ret;
1128 }
1129 
DeleteTokenInner(int32_t osAccountId,const char * userId,const char * deviceId,AccountTokenVec * deleteTokens)1130 static int32_t DeleteTokenInner(int32_t osAccountId, const char *userId, const char *deviceId,
1131     AccountTokenVec *deleteTokens)
1132 {
1133     LOGI("Start to delete tokens from database!");
1134     g_accountDbMutex->lock(g_accountDbMutex);
1135     OsAccountTokenInfo *info = GetTokenInfoByOsAccountId(osAccountId);
1136     if (info == NULL) {
1137         LOGE("Failed to get token by os account id");
1138         g_accountDbMutex->unlock(g_accountDbMutex);
1139         return HC_ERROR;
1140     }
1141     int32_t count = 0;
1142     uint32_t index = 0;
1143     AccountToken **token = NULL;
1144     while (index < HC_VECTOR_SIZE(&info->tokens)) {
1145         token = info->tokens.getp(&info->tokens, index);
1146         if ((token == NULL) || (*token == NULL) ||
1147             (strcmp(userId, (const char *)((*token)->pkInfo.userId.val)) != 0) ||
1148             (strcmp(deviceId, (const char *)((*token)->pkInfo.deviceId.val)) != 0)) {
1149             index++;
1150             continue;
1151         }
1152         AccountToken *deleteToken = NULL;
1153         HC_VECTOR_POPELEMENT(&info->tokens, &deleteToken, index);
1154         count++;
1155         LOGI("Delete a token from database successfully!");
1156         if (deleteTokens->pushBackT(deleteTokens, deleteToken) == NULL) {
1157             LOGE("Failed to push deleted token to vec");
1158             DestroyAccountToken(deleteToken);
1159         }
1160     }
1161     g_accountDbMutex->unlock(g_accountDbMutex);
1162     if (count == 0) {
1163         LOGE("No token deleted");
1164         return HC_ERROR;
1165     }
1166     LOGI("Number of tokens deleted: %d", count);
1167     return HC_SUCCESS;
1168 }
1169 
AddTokenInner(int32_t osAccountId,const AccountToken * token)1170 static int32_t AddTokenInner(int32_t osAccountId, const AccountToken *token)
1171 {
1172     LOGI("Start to add a token to database!");
1173     g_accountDbMutex->lock(g_accountDbMutex);
1174     OsAccountTokenInfo *info = GetTokenInfoByOsAccountId(osAccountId);
1175     if (info == NULL) {
1176         LOGE("Failed to get token by os account id");
1177         g_accountDbMutex->unlock(g_accountDbMutex);
1178         return HC_ERROR;
1179     }
1180     AccountToken *newToken = DeepCopyToken(token);
1181     if (newToken == NULL) {
1182         LOGE("Deep copy token failed");
1183         g_accountDbMutex->unlock(g_accountDbMutex);
1184         return HC_ERR_MEMORY_COPY;
1185     }
1186     AccountToken **oldTokenPtr = QueryTokenPtrIfMatch(&info->tokens, (const char *)(newToken->pkInfo.userId.val),
1187         (const char *)(newToken->pkInfo.deviceId.val));
1188     if (oldTokenPtr != NULL) {
1189         DestroyAccountToken(*oldTokenPtr);
1190         *oldTokenPtr = newToken;
1191         g_accountDbMutex->unlock(g_accountDbMutex);
1192         LOGI("Replace an old token successfully!");
1193         return HC_SUCCESS;
1194     }
1195     if (info->tokens.pushBackT(&info->tokens, newToken) == NULL) {
1196         DestroyAccountToken(newToken);
1197         g_accountDbMutex->unlock(g_accountDbMutex);
1198         LOGE("Failed to push token to vec!");
1199         return HC_ERR_MEMORY_COPY;
1200     }
1201     g_accountDbMutex->unlock(g_accountDbMutex);
1202     LOGI("Add a token to database successfully!");
1203     return HC_SUCCESS;
1204 }
1205 
AddToken(int32_t osAccountId,int32_t opCode,const CJson * in)1206 static int32_t AddToken(int32_t osAccountId, int32_t opCode, const CJson *in)
1207 {
1208     if (in == NULL) {
1209         LOGE("Input param is null!");
1210         return HC_ERR_NULL_PTR;
1211     }
1212     int32_t ret = CheckCredValidity(osAccountId, opCode, in);
1213     if (ret != HC_SUCCESS) {
1214         LOGE("Invalid credential");
1215         return ret;
1216     }
1217     AccountToken *token = CreateAccountToken();
1218     if (token == NULL) {
1219         LOGE("Failed to allocate token memory!");
1220         return HC_ERR_ALLOC_MEMORY;
1221     }
1222     ret = GenerateTokenFromJson(in, token);
1223     if (ret != HC_SUCCESS) {
1224         LOGE("Failed to generate token");
1225         DestroyAccountToken(token);
1226         return ret;
1227     }
1228     ret = AddTokenInner(osAccountId, token);
1229     DestroyAccountToken(token);
1230     if (ret != HC_SUCCESS) {
1231         LOGE("Failed to add token inner");
1232         return ret;
1233     }
1234     ret = SaveOsAccountTokenDb(osAccountId);
1235     if (ret != HC_SUCCESS) {
1236         LOGE("Failed to save token to db");
1237     }
1238     return ret;
1239 }
1240 
DeleteToken(int32_t osAccountId,const char * userId,const char * deviceId)1241 static int32_t DeleteToken(int32_t osAccountId, const char *userId, const char *deviceId)
1242 {
1243     if ((userId == NULL) || (deviceId == NULL)) {
1244         LOGE("Invalid input params!");
1245         return HC_ERR_NULL_PTR;
1246     }
1247     AccountTokenVec deleteTokens = CreateAccountTokenVec();
1248     int32_t ret = DeleteTokenInner(osAccountId, userId, deviceId, &deleteTokens);
1249     if (ret != HC_SUCCESS) {
1250         LOGE("Failed to delete token inner, account id is: %d", osAccountId);
1251         DestroyAccountTokenVec(&deleteTokens);
1252         return ret;
1253     }
1254     ret = SaveOsAccountTokenDb(osAccountId);
1255     if (ret != HC_SUCCESS) {
1256         LOGE("Failed to save token to db, account id is: %d", osAccountId);
1257         ClearAccountTokenVec(&deleteTokens);
1258         return ret;
1259     }
1260     uint32_t index;
1261     AccountToken **token;
1262     FOR_EACH_HC_VECTOR(deleteTokens, index, token) {
1263         DeleteKeyPair(osAccountId, *token);
1264     }
1265     ClearAccountTokenVec(&deleteTokens);
1266     return HC_SUCCESS;
1267 }
1268 
LoadTokenDb(void)1269 static void LoadTokenDb(void)
1270 {
1271     if (IsOsAccountSupported()) {
1272         return;
1273     }
1274     StringVector dbNameVec = CreateStrVector();
1275     HcFileGetSubFileName(GetAccountStoragePath(), &dbNameVec);
1276     uint32_t index;
1277     HcString *dbName = NULL;
1278     FOR_EACH_HC_VECTOR(dbNameVec, index, dbName) {
1279         int32_t osAccountId;
1280         const char *name = StringGet(dbName);
1281         if (name == NULL) {
1282             continue;
1283         }
1284         if (strcmp(name, "account_data_asy.dat") == 0) {
1285             LoadOsAccountTokenDb(DEFAULT_OS_ACCOUNT);
1286         } else if (sscanf_s(name, "account_data_asy%d.dat", &osAccountId) == 1) {
1287             LoadOsAccountTokenDb(osAccountId);
1288         }
1289     }
1290     DestroyStrVector(&dbNameVec);
1291 }
1292 
InitTokenManager(void)1293 void InitTokenManager(void)
1294 {
1295     if (g_accountDbMutex == NULL) {
1296         g_accountDbMutex = (HcMutex *)HcMalloc(sizeof(HcMutex), 0);
1297         if (g_accountDbMutex == NULL) {
1298             LOGE("Alloc account database mutex failed.");
1299             return;
1300         }
1301         if (InitHcMutex(g_accountDbMutex) != HC_SUCCESS) {
1302             LOGE("Init account mutex failed.");
1303             HcFree(g_accountDbMutex);
1304             g_accountDbMutex = NULL;
1305             return;
1306         }
1307     }
1308     g_accountDbMutex->lock(g_accountDbMutex);
1309     (void)memset_s(&g_asyTokenManager, sizeof(AccountAuthTokenManager), 0, sizeof(AccountAuthTokenManager));
1310     g_asyTokenManager.addToken = AddToken;
1311     g_asyTokenManager.getToken = GetToken;
1312     g_asyTokenManager.deleteToken = DeleteToken;
1313     g_asyTokenManager.getRegisterProof = GetRegisterProof;
1314     g_asyTokenManager.generateKeyAlias = GenerateKeyAlias;
1315     if (!g_isInitial) {
1316         g_accountTokenDb = CREATE_HC_VECTOR(AccountTokenDb);
1317         AddOsAccountEventCallback(ASY_TOKEN_DATA_CALLBACK, OnOsAccountUnlocked, OnOsAccountRemoved);
1318         g_isInitial = true;
1319     }
1320 
1321     LoadTokenDb();
1322     g_algLoader = GetLoaderInstance();
1323     if (g_algLoader == NULL) {
1324         LOGE("Get loader failed.");
1325         g_accountDbMutex->unlock(g_accountDbMutex);
1326         return;
1327     }
1328     int32_t res = g_algLoader->initAlg();
1329     if (res != HAL_SUCCESS) {
1330         LOGE("Failed to init algorithm!");
1331     }
1332     g_accountDbMutex->unlock(g_accountDbMutex);
1333 }
1334 
ClearAccountTokenVec(AccountTokenVec * vec)1335 void ClearAccountTokenVec(AccountTokenVec *vec)
1336 {
1337     uint32_t index;
1338     AccountToken **token;
1339     FOR_EACH_HC_VECTOR(*vec, index, token) {
1340         DestroyAccountToken(*token);
1341     }
1342     DESTROY_HC_VECTOR(AccountTokenVec, vec);
1343 }
1344 
InitTokenData(AccountToken * token)1345 static void InitTokenData(AccountToken *token)
1346 {
1347     token->pkInfoStr.val = NULL;
1348     token->pkInfoSignature.val = NULL;
1349     token->serverPk.val = NULL;
1350     token->pkInfo.deviceId.val = NULL;
1351     token->pkInfo.userId.val = NULL;
1352     token->pkInfo.version.val = NULL;
1353     token->pkInfo.devicePk.val = NULL;
1354 }
1355 
CreateAccountToken(void)1356 AccountToken *CreateAccountToken(void)
1357 {
1358     AccountToken *token = (AccountToken *)HcMalloc(sizeof(AccountToken), 0);
1359     if (token == NULL) {
1360         LOGE("Failed to allocate accountToken memory!");
1361         return NULL;
1362     }
1363     InitTokenData(token);
1364     token->pkInfoStr.val = (uint8_t *)HcMalloc(PUBLIC_KEY_INFO_SIZE, 0);
1365     GOTO_IF_CHECK_NULL(token->pkInfoStr.val, "pkInfoStr");
1366     token->pkInfoStr.length = PUBLIC_KEY_INFO_SIZE;
1367     token->pkInfoSignature.val = (uint8_t *)HcMalloc(SIGNATURE_SIZE, 0);
1368     GOTO_IF_CHECK_NULL(token->pkInfoSignature.val, "pkInfoSignature");
1369     token->pkInfoSignature.length = SIGNATURE_SIZE;
1370     token->serverPk.val = (uint8_t *)HcMalloc(SERVER_PK_SIZE, 0);
1371     GOTO_IF_CHECK_NULL(token->serverPk.val, "serverPk");
1372     token->serverPk.length = SERVER_PK_SIZE;
1373     token->pkInfo.deviceId.val = (uint8_t *)HcMalloc(DEV_AUTH_DEVICE_ID_SIZE, 0);
1374     GOTO_IF_CHECK_NULL(token->pkInfo.deviceId.val, "deviceId");
1375     token->pkInfo.deviceId.length = DEV_AUTH_DEVICE_ID_SIZE;
1376     token->pkInfo.userId.val = (uint8_t *)HcMalloc(DEV_AUTH_USER_ID_SIZE, 0);
1377     GOTO_IF_CHECK_NULL(token->pkInfo.userId.val, "userId");
1378     token->pkInfo.userId.length = DEV_AUTH_USER_ID_SIZE;
1379     token->pkInfo.version.val = (uint8_t *)HcMalloc(PK_VERSION_SIZE, 0);
1380     GOTO_IF_CHECK_NULL(token->pkInfo.version.val, "version");
1381     token->pkInfo.version.length = PK_VERSION_SIZE;
1382     token->pkInfo.devicePk.val = (uint8_t *)HcMalloc(PK_SIZE, 0);
1383     GOTO_IF_CHECK_NULL(token->pkInfo.devicePk.val, "devicePk");
1384     token->pkInfo.devicePk.length = PK_SIZE;
1385     return token;
1386 ERR:
1387     DestroyAccountToken(token);
1388     return NULL;
1389 }
1390 
DestroyAccountToken(AccountToken * token)1391 void DestroyAccountToken(AccountToken *token)
1392 {
1393     if (token == NULL) {
1394         LOGE("Input token is null");
1395         return;
1396     }
1397     HcFree(token->pkInfoStr.val);
1398     token->pkInfoStr.length = 0;
1399     HcFree(token->pkInfoSignature.val);
1400     token->pkInfoSignature.length = 0;
1401     HcFree(token->serverPk.val);
1402     token->serverPk.length = 0;
1403     HcFree(token->pkInfo.deviceId.val);
1404     token->pkInfo.deviceId.length = 0;
1405     HcFree(token->pkInfo.userId.val);
1406     token->pkInfo.userId.length = 0;
1407     HcFree(token->pkInfo.version.val);
1408     token->pkInfo.version.length = 0;
1409     HcFree(token->pkInfo.devicePk.val);
1410     token->pkInfo.devicePk.length = 0;
1411     HcFree(token);
1412 }
1413 
GetAccountAuthTokenManager(void)1414 AccountAuthTokenManager *GetAccountAuthTokenManager(void)
1415 {
1416     return &g_asyTokenManager;
1417 }
1418 
DestroyTokenManager(void)1419 void DestroyTokenManager(void)
1420 {
1421     g_accountDbMutex->lock(g_accountDbMutex);
1422     RemoveOsAccountEventCallback(ASY_TOKEN_DATA_CALLBACK);
1423     g_algLoader = NULL;
1424     (void)memset_s(&g_asyTokenManager, sizeof(AccountAuthTokenManager), 0, sizeof(AccountAuthTokenManager));
1425     uint32_t index;
1426     OsAccountTokenInfo *info = NULL;
1427     FOR_EACH_HC_VECTOR(g_accountTokenDb, index, info) {
1428         ClearAccountTokenVec(&info->tokens);
1429     }
1430     DESTROY_HC_VECTOR(AccountTokenDb, &g_accountTokenDb);
1431     g_isInitial = false;
1432     g_accountDbMutex->unlock(g_accountDbMutex);
1433     DestroyHcMutex(g_accountDbMutex);
1434     HcFree(g_accountDbMutex);
1435     g_accountDbMutex = NULL;
1436 }