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