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 }