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