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