* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "identity_operation.h"
#include "alg_defs.h"
#include "alg_loader.h"
#include "clib_error.h"
#include "cred_listener.h"
#include "device_auth.h"
#include "device_auth_defines.h"
#include "hal_error.h"
#include "hc_log.h"
#include "hc_time.h"
#include "identity_service_defines.h"
#include "permission_adapter.h"
#include "string_util.h"
#include "account_task_manager.h"
#include "common_defs.h"
int32_t GetCredentialById(int32_t osAccountId, const char *credId, Credential **returnEntry)
{
if (credId == NULL) {
LOGE("The input credId is NULL!");
return IS_ERR_INVALID_PARAMS;
}
uint32_t index;
CredentialVec credentialVec = CreateCredentialVec();
QueryCredentialParams params = InitQueryCredentialParams();
params.credId = credId;
int32_t ret = QueryCredentials(osAccountId, ¶ms, &credentialVec);
if (ret != IS_SUCCESS) {
LOGE("Failed to query credentials!");
ClearCredentialVec(&credentialVec);
return ret;
}
Credential **credential = NULL;
FOR_EACH_HC_VECTOR(credentialVec, index, credential) {
*returnEntry = DeepCopyCredential(*credential);
ClearCredentialVec(&credentialVec);
if (*returnEntry == NULL) {
LOGE("Failed to copy credential!");
return IS_ERR_ALLOC_MEMORY;
}
return IS_SUCCESS;
}
ClearCredentialVec(&credentialVec);
LOGI("This credId does not exist!");
return IS_ERR_LOCAL_CRED_NOT_EXIST;
}
static int32_t Int64ToString(int64_t num, char **result)
{
const int bufferSize = MAX_INT64_SIZE + 1;
char *tempStr = (char *)HcMalloc(bufferSize, 0);
if (tempStr == NULL) {
LOGE("Failed to allocate memory!");
return IS_ERR_ALLOC_MEMORY;
}
if (sprintf_s(tempStr, bufferSize, "%" PRId64, num) < 0) {
LOGE("Failed to convert int64 to string!");
HcFree(tempStr);
return IS_ERR_CONVERT_FAILED;
}
*result = tempStr;
return IS_SUCCESS;
}
static int32_t CombineBaseCredId(const char *credentialOwner, const char *deviceId, char **baseCredIdStr)
{
if (credentialOwner == NULL || deviceId == NULL) {
LOGE("Invalid input parameters!");
return IS_ERR_INVALID_PARAMS;
}
char *timeStr = NULL;
int32_t ret = Int64ToString(HcGetCurTimeInMillis(), &timeStr);
if (ret != IS_SUCCESS) {
LOGE("Failed to convert time to string!");
return ret;
}
size_t totalLength = HcStrlen(credentialOwner) + HcStrlen(deviceId) + HcStrlen(timeStr) + 1;
char *tempCredId = (char *)HcMalloc(totalLength, 0);
if (tempCredId == NULL) {
LOGE("Failed to allocate memory for tempCredId!");
HcFree(timeStr);
return IS_ERR_ALLOC_MEMORY;
}
if (strcpy_s(tempCredId, totalLength, credentialOwner) != EOK) {
LOGE("Failed to copy credentialOwner to tempCredId!");
HcFree(timeStr);
HcFree(tempCredId);
return IS_ERR_CONVERT_FAILED;
}
if (strcat_s(tempCredId, totalLength, deviceId) != EOK) {
LOGE("Failed to concatenate deviceId to tempCredId!");
HcFree(timeStr);
HcFree(tempCredId);
return IS_ERR_CONVERT_FAILED;
}
if (strcat_s(tempCredId, totalLength, timeStr) != EOK) {
LOGE("Failed to concatenate timeStr to tempCredId!");
HcFree(timeStr);
HcFree(tempCredId);
return IS_ERR_CONVERT_FAILED;
}
HcFree(timeStr);
*baseCredIdStr = tempCredId;
return IS_SUCCESS;
}
static int32_t Uint8BuffToString(Uint8Buff *byte, char **str)
{
uint32_t strLen = byte->length * BYTE_TO_HEX_OPER_LENGTH + 1;
char *tempStr = (char *)HcMalloc(strLen, 0);
if (tempStr == NULL) {
LOGE("Failed to malloc tempStr");
return IS_ERR_ALLOC_MEMORY;
}
int32_t ret = ByteToHexString(byte->val, byte->length, tempStr, strLen);
if (ret != IS_SUCCESS) {
LOGE("Failed to convert byte to hex string");
HcFree(tempStr);
return ret;
}
*str = tempStr;
return IS_SUCCESS;
}
static int32_t Sha256BaseCredId(const char *baseCredIdStr, Uint8Buff *credIdByte, char **credIdStr)
{
Uint8Buff returnCredIdByte = { NULL, SHA256_LEN };
returnCredIdByte.val = (uint8_t *)HcMalloc(SHA256_LEN, 0);
if (returnCredIdByte.val == NULL) {
LOGE("Failed to malloc memory for returnCredIdByte");
return IS_ERR_ALLOC_MEMORY;
}
Uint8Buff baseCredIdBuff = { (uint8_t *)baseCredIdStr, (uint32_t)HcStrlen(baseCredIdStr) };
int32_t ret = GetLoaderInstance()->sha256(&baseCredIdBuff, &returnCredIdByte);
if (ret == HAL_ERR_HUKS) {
LOGE("Huks sha256 error");
HcFree(returnCredIdByte.val);
return IS_ERR_HUKS_SHA256_FAILED;
}
if (ret != IS_SUCCESS) {
LOGE("Failed to sha256 credId, ret = %" LOG_PUB "d", ret);
HcFree(returnCredIdByte.val);
return ret;
}
char *returnCredIdStr = NULL;
ret = Uint8BuffToString(&returnCredIdByte, &returnCredIdStr);
if (ret != IS_SUCCESS) {
LOGE("Failed to convert credIdByte to credIdStr, ret = %" LOG_PUB "d", ret);
HcFree(returnCredIdByte.val);
return ret;
}
*credIdStr = returnCredIdStr;
credIdByte->val = returnCredIdByte.val;
credIdByte->length = SHA256_LEN;
return IS_SUCCESS;
}
static int32_t GenerateCredIdInner(const char *credentialOwner, const char *deviceId,
Uint8Buff *credIdByte, char **credIdStr)
{
char *baseCredIdStr = NULL;
int32_t ret = CombineBaseCredId(credentialOwner, deviceId, &baseCredIdStr);
if (ret != IS_SUCCESS) {
LOGE("Failed to combine credId!");
return ret;
}
ret = Sha256BaseCredId(baseCredIdStr, credIdByte, credIdStr);
HcFree(baseCredIdStr);
return ret;
}
static bool IsCredIdExist(int32_t osAccountId, const char *credIdStr)
{
Credential *existedCredential = NULL;
int32_t ret = GetCredentialById(osAccountId, credIdStr, &existedCredential);
DestroyCredential(existedCredential);
return ret == IS_SUCCESS;
}
static int32_t UseImportedCredId(int32_t osAccountId, Credential *credential, Uint8Buff *credIdByte)
{
if (IsCredIdExist(osAccountId, StringGet(&credential->credId))) {
LOGE("Imported credId existed");
return IS_ERR_IMPORTED_CRED_ID_EXISTED;
}
LOGI("Imported credId not existed in DB, use imported credId");
uint32_t credIdByteLen = HcStrlen(StringGet(&credential->credId)) / BYTE_TO_HEX_OPER_LENGTH;
credIdByte->length = credIdByteLen;
uint8_t *returnCredIdByteVal = (uint8_t *)HcMalloc(credIdByteLen, 0);
if (returnCredIdByteVal == NULL) {
LOGE("Failed to malloc memory for credIdByte");
return IS_ERR_ALLOC_MEMORY;
}
int32_t ret = HexStringToByte(StringGet(&credential->credId), returnCredIdByteVal, credIdByte->length);
if (ret != IS_SUCCESS) {
LOGE("Failed to convert credId to byte, ret = %" LOG_PUB "d", ret);
HcFree(returnCredIdByteVal);
return IS_ERR_INVALID_HEX_STRING;
}
credIdByte->val = returnCredIdByteVal;
return IS_SUCCESS;
}
static int32_t GenerateUniqueCredId(int32_t osAccountId,
Credential *credential, Uint8Buff *credIdByte, char **credIdStr)
{
char *returnCredId = NULL;
const char *credOwner = StringGet(&credential->credOwner);
const char *deviceId = StringGet(&credential->deviceId);
int32_t ret = GenerateCredIdInner(credOwner, deviceId, credIdByte, &returnCredId);
if (ret != IS_SUCCESS) {
return ret;
}
if (IsCredIdExist(osAccountId, returnCredId)) {
LOGW("CredId already exists, regenerate credId");
HcFree(returnCredId);
returnCredId = NULL;
ret = GenerateCredIdInner(credOwner, deviceId, credIdByte, &returnCredId);
if (ret != IS_SUCCESS) {
return ret;
}
}
*credIdStr = returnCredId;
return IS_SUCCESS;
}
int32_t GenerateCredId(int32_t osAccountId, Credential *credential, Uint8Buff *credIdByte)
{
if (HcStrlen(StringGet(&credential->credId)) > 0) {
return UseImportedCredId(osAccountId, credential, credIdByte);
}
char *credIdStr = NULL;
int32_t ret = GenerateUniqueCredId(osAccountId, credential, credIdByte, &credIdStr);
if (ret != IS_SUCCESS) {
return ret;
}
if (!StringSetPointer(&credential->credId, credIdStr)) {
LOGE("Failed to set credId");
HcFree(credIdByte->val);
HcFree(credIdStr);
return IS_ERR_MEMORY_COPY;
}
HcFree(credIdStr);
LOGI("Generate credId success");
return IS_SUCCESS;
}
static int32_t CheckOutMaxCredSize(int32_t osAccountId, const char *credOwner)
{
QueryCredentialParams queryParams = InitQueryCredentialParams();
queryParams.credOwner = credOwner;
CredentialVec credentialVec = CreateCredentialVec();
int32_t ret = QueryCredentials(osAccountId, &queryParams, &credentialVec);
if (ret != IS_SUCCESS) {
LOGE("Failed to query credentials");
ClearCredentialVec(&credentialVec);
return ret;
}
if (credentialVec.size(&credentialVec) > MAX_CRED_SIZE) {
LOGE("The number of credentials exceeds the maximum limit");
ClearCredentialVec(&credentialVec);
return IS_ERR_BEYOND_LIMIT;
}
ClearCredentialVec(&credentialVec);
return IS_SUCCESS;
}
static Algorithm GetAlgoFromCred(uint8_t algorithmType)
{
switch (algorithmType) {
case ALGO_TYPE_P256:
return P256;
case ALGO_TYPE_ED25519:
return ED25519;
default:
return AES;
}
}
static int32_t GenerateKeyValue(int32_t osAccountId,
Credential *credential, KeyParams keyParams, Algorithm algo, ExtraInfo exInfo)
{
Uint8Buff keyAlias = { keyParams.keyBuff.key, keyParams.keyBuff.keyLen };
if (GetLoaderInstance()->checkKeyExist(&keyAlias, false, osAccountId) != HAL_ERR_KEY_NOT_EXIST) {
LOGI("The keyValue corresponding to the credId already exists in HUKS, no need to generate.");
return IS_SUCCESS;
}
LOGI("The keyValue corresponding to the credId does not exist in HUKS, generate keyValue.");
uint32_t keyLen = (credential->algorithmType == ALGO_TYPE_AES_128) ? AES_128_KEY_LEN : ALGO_KEY_LEN;
int32_t ret = GetLoaderInstance()->generateKeyPairWithStorage(&keyParams, keyLen, algo,
KEY_PURPOSE_KEY_AGREE, &exInfo);
if (ret == HAL_ERR_HUKS) {
LOGE("Huks generateKeyPair failed!");
return IS_ERR_HUKS_GENERATE_KEY_FAILED;
}
if (ret != IS_SUCCESS) {
LOGE("Failed to generate key pair!");
return ret;
}
LOGI("Generate key pair success!");
return IS_SUCCESS;
}
static int32_t ImportKeyValue(KeyParams keyParams,
Uint8Buff *keyValue, Algorithm algo, ExtraInfo exInfo, uint8_t subject)
{
int32_t ret;
if (algo == AES) {
KeyPurpose keyPurpose = subject == SUBJECT_MASTER_CONTROLLER ? KEY_PURPOSE_MAC : KEY_PURPOSE_DERIVE;
ret = GetLoaderInstance()->importSymmetricKey(&keyParams, keyValue, keyPurpose, &exInfo);
} else {
ret = GetLoaderInstance()->importPublicKey(&keyParams, keyValue, algo, &exInfo);
}
if (ret == HAL_ERR_HUKS) {
LOGE("Huks import key failed!");
return IS_ERR_HUKS_IMPORT_KEY_FAILED;
}
if (ret != IS_SUCCESS) {
LOGE("Failed to import key pair!");
return ret;
}
LOGI("Import key pair success!");
return IS_SUCCESS;
}
int32_t AddKeyValueToHuks(int32_t osAccountId, Uint8Buff *credIdByte, Credential *credential, uint8_t method,
Uint8Buff *keyValue)
{
if (credential->credType == ACCOUNT_SHARED && keyValue->val == NULL) {
return IS_SUCCESS;
}
if (credential->ownerUid == DEV_AUTH_UID) {
return IS_SUCCESS;
}
KeyParams keyParams = { { credIdByte->val, credIdByte->length, true }, false, osAccountId };
int32_t authId = 0;
Uint8Buff authIdBuff = { (uint8_t *)&authId, sizeof(int32_t) };
ExtraInfo exInfo = { authIdBuff, DEFAULT_EX_INFO_VAL, DEFAULT_EX_INFO_VAL };
Algorithm algo = GetAlgoFromCred(credential->algorithmType);
switch (method) {
case METHOD_GENERATE:
return GenerateKeyValue(osAccountId, credential, keyParams, algo, exInfo);
case METHOD_IMPORT:
return ImportKeyValue(keyParams, keyValue, algo, exInfo, credential->subject);
default:
return IS_ERR_INVALID_PARAMS;
}
}
int32_t GetValidKeyAlias(int32_t osAccountId, const char *credId, Uint8Buff *credIdHashBuff)
{
uint32_t credIdByteLen = HcStrlen(credId) / BYTE_TO_HEX_OPER_LENGTH;
Uint8Buff returnCredIdByte = { NULL, credIdByteLen };
returnCredIdByte.val = (uint8_t *)HcMalloc(credIdByteLen, 0);
if (returnCredIdByte.val == NULL) {
LOGE("Failed to malloc credIdByteLen");
return IS_ERR_ALLOC_MEMORY;
}
int32_t ret = HexStringToByte(credId, returnCredIdByte.val, returnCredIdByte.length);
if (ret != IS_SUCCESS) {
LOGE("Failed to convert credId to byte, invalid credId, ret = %" LOG_PUB "d", ret);
HcFree(returnCredIdByte.val);
return IS_ERR_INVALID_HEX_STRING;
}
ret = GetLoaderInstance()->checkKeyExist(&returnCredIdByte, false, osAccountId);
if (ret != IS_SUCCESS) {
HcFree(returnCredIdByte.val);
return ret;
}
credIdHashBuff->val = returnCredIdByte.val;
credIdHashBuff->length = credIdByteLen;
return IS_SUCCESS;
}
int32_t AddCredAndSaveDb(int32_t osAccountId, Credential *credential)
{
int32_t ret = AddCredToDb(osAccountId, credential);
if (ret != IS_SUCCESS) {
LOGE("Failed to add credential to database");
return ret;
}
ret = SaveOsAccountCredDb(osAccountId);
if (ret != IS_SUCCESS) {
LOGE("Failed to save CredDb, ret: %" LOG_PUB "d", ret);
return ret;
}
return IS_SUCCESS;
}
static bool IsValueInArray(uint8_t value, uint8_t *array, uint32_t length)
{
for (uint32_t i = 0; i < length; i++) {
if (array[i] == value) {
return true;
}
}
return false;
}
static int32_t SetVectorFromList(StringVector *dataVector, CJson *dataList)
{
int32_t dataListNum = GetItemNum(dataList);
for (int32_t i = 0; i < dataListNum; i++) {
CJson *item = GetItemFromArray(dataList, i);
if (item == NULL) {
LOGE("item is null.");
return IS_ERR_JSON_GET;
}
const char *data = GetStringValue(item);
if (data == NULL) {
LOGE("the data of list is null.");
return IS_ERR_JSON_GET;
}
HcString strData = CreateString();
if (!StringSetPointer(&strData, data)) {
LOGE("Failed to set strData!");
DeleteString(&strData);
return IS_ERR_MEMORY_COPY;
}
if (dataVector->pushBackT(dataVector, strData) == NULL) {
LOGE("Failed to push strData to vector!");
DeleteString(&strData);
return IS_ERR_MEMORY_COPY;
}
}
return IS_SUCCESS;
}
static int32_t SetMethodFromJson(CJson *json, uint8_t *method)
{
int32_t methodInt32 = DEFAULT_VAL;
if (GetIntFromJson(json, FIELD_METHOD, &methodInt32) != IS_SUCCESS) {
LOGE("Failed to get method from credReqParam");
return IS_ERR_JSON_GET;
}
*method = (uint8_t)methodInt32;
uint8_t methodRange[] = { METHOD_GENERATE, METHOD_IMPORT };
uint32_t length = sizeof(methodRange) / sizeof(methodRange[0]);
if (!IsValueInArray(*method, methodRange, length)) {
LOGE("method is invalid.");
return IS_ERR_INVALID_PARAMS;
}
return IS_SUCCESS;
}
static int32_t SetCredType(Credential *credential, CJson *json)
{
if (GetUint8FromJson(json, FIELD_CRED_TYPE, &credential->credType) != IS_SUCCESS) {
LOGE("Failed to get credential type from credReqParam");
return IS_ERR_JSON_GET;
}
uint8_t credTypeRange[] = { ACCOUNT_RELATED, ACCOUNT_UNRELATED, ACCOUNT_SHARED };
uint32_t length = sizeof(credTypeRange) / sizeof(credTypeRange[0]);
if (!IsValueInArray(credential->credType, credTypeRange, length)) {
LOGE("credential type is invalid.");
return IS_ERR_INVALID_PARAMS;
}
return IS_SUCCESS;
}
static int32_t SetKeyFormat(Credential *credential, CJson *json, uint8_t method)
{
if (GetUint8FromJson(json, FIELD_KEY_FORMAT, &credential->keyFormat) != IS_SUCCESS) {
LOGE("Failed to get key format from credReqParam");
return IS_ERR_JSON_GET;
}
uint8_t keyFormatRange[] = { SYMMETRIC_KEY, ASYMMETRIC_PUB_KEY, ASYMMETRIC_KEY, X509_CERT};
uint32_t length = sizeof(keyFormatRange) / sizeof(keyFormatRange[0]);
if (!IsValueInArray(credential->keyFormat, keyFormatRange, length)) {
LOGE("key format is invalid.");
return IS_ERR_INVALID_PARAMS;
}
if (credential->keyFormat == SYMMETRIC_KEY && method != METHOD_IMPORT) {
LOGE("Symmetric key is only supported for import");
return IS_ERR_INVALID_PARAMS;
}
if (credential->keyFormat == ASYMMETRIC_PUB_KEY && method != METHOD_IMPORT) {
LOGE("Asymmetric public key is only supported for import");
return IS_ERR_INVALID_PARAMS;
}
if (credential->keyFormat == ASYMMETRIC_KEY && method != METHOD_GENERATE) {
LOGE("Asymmetric key is only supported for generate");
return IS_ERR_INVALID_PARAMS;
}
return IS_SUCCESS;
}
static int32_t SetAuthorizedScope(Credential *credential, CJson *json)
{
if (GetUint8FromJson(json, FIELD_AUTHORIZED_SCOPE, &credential->authorizedScope) != IS_SUCCESS) {
LOGE("Failed to get authorizedScope from credReqParam");
return IS_ERR_JSON_GET;
}
uint8_t scopeRange[] = { SCOPE_DEVICE, SCOPE_USER, SCOPE_APP };
uint32_t length = sizeof(scopeRange) / sizeof(scopeRange[0]);
if (!IsValueInArray(credential->authorizedScope, scopeRange, length)) {
LOGE("Invalid authorizedScope");
return IS_ERR_INVALID_PARAMS;
}
return IS_SUCCESS;
}
static int32_t SetAlgorithmType(Credential *credential, CJson *json)
{
if (GetUint8FromJson(json, FIELD_ALGORITHM_TYPE, &credential->algorithmType) != IS_SUCCESS) {
LOGE("Failed to get algorithm type from credReqParam");
return IS_ERR_JSON_GET;
}
uint8_t algorithmTypeRange[] = { ALGO_TYPE_AES_256, ALGO_TYPE_P256, ALGO_TYPE_ED25519 };
uint32_t length = sizeof(algorithmTypeRange) / sizeof(algorithmTypeRange[0]);
if (!IsValueInArray(credential->algorithmType, algorithmTypeRange, length)) {
LOGE("Invalid algorithm type");
return IS_ERR_INVALID_PARAMS;
}
return IS_SUCCESS;
}
static int32_t SetSubject(Credential *credential, CJson *json)
{
if (GetUint8FromJson(json, FIELD_SUBJECT, &credential->subject) != IS_SUCCESS) {
LOGE("Failed to get subject from credReqParam");
return IS_ERR_JSON_GET;
}
uint8_t subjectRange[] = { SUBJECT_MASTER_CONTROLLER, SUBJECT_ACCESSORY_DEVICE };
uint32_t length = sizeof(subjectRange) / sizeof(subjectRange[0]);
if (!IsValueInArray(credential->subject, subjectRange, length)) {
LOGE("Invalid subject");
return IS_ERR_INVALID_PARAMS;
}
return IS_SUCCESS;
}
static int32_t SetIssuer(Credential *credential, CJson *json)
{
if (GetUint8FromJson(json, FIELD_ISSUER, &credential->issuer) != IS_SUCCESS) {
LOGW("Failed to get issuer from credReqParam");
}
if (credential->credType == ACCOUNT_UNRELATED) {
return IS_SUCCESS;
}
uint8_t issuerRange[] = { SYSTEM_ACCOUNT, APP_ACCOUNT, DOMANIN_ACCOUNT };
uint32_t length = sizeof(issuerRange) / sizeof(issuerRange[0]);
if (credential->issuer == DEFAULT_VAL || !IsValueInArray(credential->issuer, issuerRange, length)) {
LOGE("Invalid issuer");
return IS_ERR_INVALID_PARAMS;
}
return IS_SUCCESS;
}
static int32_t SetDeviceId(Credential *credential, CJson *json)
{
const char *deviceId = GetStringFromJson(json, FIELD_DEVICE_ID);
if (deviceId == NULL || IsStrEqual(deviceId, "")) {
LOGE("Failed to get deviceId from credReqParam");
return IS_ERR_JSON_GET;
}
if (!StringSetPointer(&credential->deviceId, deviceId)) {
LOGE("Failed to set deviceId");
return IS_ERR_MEMORY_COPY;
}
return IS_SUCCESS;
}
static int32_t SetCredOwner(Credential *credential, CJson *json)
{
const char *credOwner = GetStringFromJson(json, FIELD_CRED_OWNER);
if (credOwner == NULL || IsStrEqual(credOwner, "")) {
LOGE("Failed to get credOwner from credReqParam");
return IS_ERR_JSON_GET;
}
if (!StringSetPointer(&credential->credOwner, credOwner)) {
LOGE("Failed to set credOwner");
return IS_ERR_MEMORY_COPY;
}
return IS_SUCCESS;
}
static int32_t SetProofType(Credential *credential, CJson *json)
{
if (GetUint8FromJson(json, FIELD_PROOF_TYPE, &credential->proofType) != IS_SUCCESS) {
LOGE("Failed to get proofType from credReqParam");
return IS_ERR_JSON_GET;
}
uint8_t proofTypeRange[] = { PROOF_TYPE_PSK, PROOF_TYPE_PKI };
uint32_t length = sizeof(proofTypeRange) / sizeof(proofTypeRange[0]);
if (!IsValueInArray(credential->proofType, proofTypeRange, length)) {
LOGE("Invalid proofType");
return IS_ERR_INVALID_PARAMS;
}
return IS_SUCCESS;
}
static int32_t SetUserId(Credential *credential, CJson *json)
{
const char *userId = GetStringFromJson(json, FIELD_USER_ID);
if (credential->credType == ACCOUNT_RELATED && (userId == NULL || IsStrEqual(userId, ""))) {
LOGE("Invalid params, when credType is account, userId is NULL");
return IS_ERR_INVALID_PARAMS;
}
if (userId == NULL) {
return IS_SUCCESS;
}
if (!StringSetPointer(&credential->userId, userId)) {
LOGW("Failed to set userId");
}
return IS_SUCCESS;
}
static int32_t SetKeyValueFromJson(CJson *json, Credential *credential, uint8_t method, Uint8Buff *keyValue)
{
const char *keyValueStr = GetStringFromJson(json, FIELD_KEY_VALUE);
if (credential->credType == ACCOUNT_SHARED && keyValueStr == NULL) {
return IS_SUCCESS;
}
if (method == METHOD_GENERATE) {
if (HcStrlen(keyValueStr) > 0) {
LOGE("Invalid params, when method is generate, keyValue should not be passed in");
return IS_ERR_KEYVALUE_METHOD_CONFLICT;
}
return IS_SUCCESS;
}
if (keyValueStr == NULL || HcStrlen(keyValueStr) <= 0) {
LOGE("Invalid params, when method is imoprt, keyValue is NULL");
return IS_ERR_INVALID_PARAMS;
}
uint32_t keyValueLen = HcStrlen(keyValueStr) / BYTE_TO_HEX_OPER_LENGTH;
keyValue->length = keyValueLen;
uint8_t *returnKeyVal = (uint8_t *)HcMalloc(keyValueLen, 0);
if (returnKeyVal == NULL) {
LOGE("Failed to malloc memory for keyValue");
return IS_ERR_ALLOC_MEMORY;
}
if (GetByteFromJson(json, FIELD_KEY_VALUE, returnKeyVal, keyValue->length) != IS_SUCCESS) {
LOGE("set keyValue fail.");
HcFree(returnKeyVal);
return IS_ERR_JSON_GET;
}
keyValue->val = returnKeyVal;
return IS_SUCCESS;
}
static int32_t SetPeerUserSpaceId(Credential *credential, CJson *json, uint8_t method)
{
const char *peerUserSpaceId = GetStringFromJson(json, FIELD_PEER_USER_SPACE_ID);
if (credential->credType == ACCOUNT_UNRELATED && method == METHOD_IMPORT &&
(peerUserSpaceId == NULL || IsStrEqual(peerUserSpaceId, ""))) {
LOGE("Invalid params, when credType is not account and method is import, peer osaccount id is NULL");
return IS_ERR_INVALID_PARAMS;
}
if (peerUserSpaceId == NULL) {
return IS_SUCCESS;
}
if (!StringSetPointer(&credential->peerUserSpaceId, peerUserSpaceId)) {
LOGW("Failed to set peerUserSpaceId");
}
return IS_SUCCESS;
}
static int32_t SetAppList(Credential *credential, CJson *json)
{
CJson *appList = GetObjFromJson(json, FIELD_AUTHORIZED_APP_LIST);
if (appList == NULL) {
if (credential->authorizedScope == SCOPE_APP) {
LOGE("when authorizedScope is APP, authorizedAppList is required");
return IS_ERR_INVALID_PARAMS;
}
return IS_SUCCESS;
}
int32_t ret = SetVectorFromList(&credential->authorizedAppList, appList);
if (ret != IS_SUCCESS) {
LOGE("Failed to set authorized app list from credReqParam");
return ret;
}
return IS_SUCCESS;
}
static int32_t SetExtendInfo(Credential *credential, CJson *json)
{
const char *extendInfo = GetStringFromJson(json, FIELD_EXTEND_INFO);
if (extendInfo == NULL || IsStrEqual(extendInfo, "")) {
LOGW("Failed to get extendInfo from credReqParam");
}
if (extendInfo == NULL) {
LOGW("Failed to get extendInfo from credReqParam");
return IS_SUCCESS;
}
if (!StringSetPointer(&credential->extendInfo, extendInfo)) {
LOGW("Failed to set extendInfo!");
}
return IS_SUCCESS;
}
static int32_t SetCredIdFromJson(Credential *credential, CJson *json)
{
const char *credIdStr = GetStringFromJson(json, FIELD_CRED_ID);
if (credIdStr == NULL || HcStrlen(credIdStr) == 0) {
LOGI("No imported credId in credReqParam, credId will be generated by IS.");
return IS_SUCCESS;
}
if (!StringSetPointer(&credential->credId, credIdStr)) {
LOGE("Failed to set credId");
return IS_ERR_ALLOC_MEMORY;
}
return IS_SUCCESS;
}
static int32_t SetRequiredField(Credential *credential, CJson *json, uint8_t *method)
{
int32_t ret = SetMethodFromJson(json, method);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetCredType(credential, json);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetKeyFormat(credential, json, *method);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetAuthorizedScope(credential, json);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetAlgorithmType(credential, json);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetSubject(credential, json);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetDeviceId(credential, json);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetCredOwner(credential, json);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetProofType(credential, json);
if (ret != IS_SUCCESS) {
return ret;
}
credential->ownerUid = GetCallingUid();
LOGI("UID: %" LOG_PUB "d", credential->ownerUid);
return IS_SUCCESS;
}
static int32_t SetSpecialRequiredField(Credential *credential, CJson *json, uint8_t *method, Uint8Buff *keyValue)
{
int32_t ret = SetUserId(credential, json);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetIssuer(credential, json);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetKeyValueFromJson(json, credential, *method, keyValue);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetPeerUserSpaceId(credential, json, *method);
if (ret != IS_SUCCESS) {
HcFree(keyValue->val);
return ret;
}
ret = SetAppList(credential, json);
if (ret != IS_SUCCESS) {
HcFree(keyValue->val);
return ret;
}
return IS_SUCCESS;
}
static int32_t SetOptionalField(Credential *credential, CJson *json)
{
int32_t ret = SetExtendInfo(credential, json);
if (ret != IS_SUCCESS) {
return ret;
}
return SetCredIdFromJson(credential, json);
}
int32_t CheckAndSetCredInfo(int32_t osAccountId,
Credential *credential, CJson *json, uint8_t *method, Uint8Buff *keyValue)
{
int32_t ret = SetRequiredField(credential, json, method);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetSpecialRequiredField(credential, json, method, keyValue);
if (ret != IS_SUCCESS) {
return ret;
}
ret = SetOptionalField(credential, json);
if (ret != IS_SUCCESS) {
HcFree(keyValue->val);
return ret;
}
ret = CheckOutMaxCredSize(osAccountId, StringGet(&credential->credOwner));
if (ret != IS_SUCCESS) {
HcFree(keyValue->val);
}
return ret;
}
int32_t SetQueryParamsFromJson(QueryCredentialParams *queryParams, CJson *json)
{
queryParams->credId = GetStringFromJson(json, FIELD_CRED_ID);
queryParams->deviceId = GetStringFromJson(json, FIELD_DEVICE_ID);
queryParams->peerUserSpaceId = GetStringFromJson(json, FIELD_PEER_USER_SPACE_ID);
queryParams->userId = GetStringFromJson(json, FIELD_USER_ID);
queryParams->credOwner = GetStringFromJson(json, FIELD_CRED_OWNER);
if (GetUint8FromJson(json, FIELD_SUBJECT, &queryParams->subject) == IS_SUCCESS) {
LOGI("Set query params: subject");
}
if (GetUint8FromJson(json, FIELD_ISSUER, &queryParams->issuer) == IS_SUCCESS) {
LOGI("Set query params: issuer");
}
if (GetUint8FromJson(json, FIELD_CRED_TYPE, &queryParams->credType) == IS_SUCCESS) {
LOGI("Set query params: credType");
}
if (GetUint8FromJson(json, FIELD_KEY_FORMAT, &queryParams->keyFormat) == IS_SUCCESS) {
LOGI("Set query params: keyFormat");
}
if (GetUint8FromJson(json, FIELD_ALGORITHM_TYPE, &queryParams->algorithmType) == IS_SUCCESS) {
LOGI("Set query params: algorithmType");
}
if (GetUint8FromJson(json, FIELD_PROOF_TYPE, &queryParams->proofType) == IS_SUCCESS) {
LOGI("Set query params: proofType");
}
if (GetUint8FromJson(json, FIELD_AUTHORIZED_SCOPE, &queryParams->authorizedScope) == IS_SUCCESS) {
LOGI("Set query params: authorizedScope");
}
return IS_SUCCESS;
}
static int32_t IsOriginalStrHashMatch(const char *originalStr, const char *subHashedStr)
{
Uint8Buff originalStrBuffer = { (uint8_t *)originalStr, (uint32_t)HcStrlen(originalStr) };
uint8_t hashedStrBytes[SHA256_LEN] = { 0 };
Uint8Buff hashedStrBuffer = { hashedStrBytes, sizeof(hashedStrBytes) };
int32_t result = GetLoaderInstance()->sha256(&originalStrBuffer, &hashedStrBuffer);
if (result != IS_SUCCESS) {
LOGE("sha256 failed, ret:%" LOG_PUB "d", result);
return result;
}
uint32_t hashedStrHexLength = SHA256_LEN * BYTE_TO_HEX_OPER_LENGTH + 1;
char *hashedStrHex = (char *)HcMalloc(hashedStrHexLength, 0);
if (hashedStrHex == NULL) {
LOGE("malloc hashedStrHex string failed");
return IS_ERR_ALLOC_MEMORY;
}
result = ByteToHexString(hashedStrBytes, SHA256_LEN, hashedStrHex, hashedStrHexLength);
if (result != IS_SUCCESS) {
LOGE("Byte to hexString failed, ret:%" LOG_PUB "d", result);
HcFree(hashedStrHex);
return result;
}
char *upperSubHashedStr = NULL;
result = ToUpperCase(subHashedStr, &upperSubHashedStr);
if (result != IS_SUCCESS) {
LOGE("Failed to convert the input sub hashed string to upper case!");
HcFree(hashedStrHex);
return result;
}
if (strstr((const char *)hashedStrHex, upperSubHashedStr) != NULL) {
LOGI("Original string hash is match!");
HcFree(hashedStrHex);
HcFree(upperSubHashedStr);
return IS_SUCCESS;
}
HcFree(hashedStrHex);
HcFree(upperSubHashedStr);
return IS_ERROR;
}
bool IsCredHashMatch(Credential *credential, CJson *reqJson)
{
const char *deviceIdHash = GetStringFromJson(reqJson, FIELD_DEVICE_ID_HASH);
if (deviceIdHash != NULL &&
IsOriginalStrHashMatch(StringGet(&credential->deviceId), deviceIdHash) != IS_SUCCESS) {
return false;
}
const char *userIdHash = GetStringFromJson(reqJson, FIELD_USER_ID_HASH);
if (userIdHash != NULL &&
IsOriginalStrHashMatch(StringGet(&credential->userId), userIdHash) != IS_SUCCESS) {
return false;
}
return true;
}
static int32_t CheckCredKeyExist(int32_t osAccountId, const Credential *credential, const char *credId)
{
if (credential->credType == ACCOUNT_SHARED || credential->ownerUid == DEV_AUTH_UID) {
return HC_SUCCESS;
}
uint32_t credIdByteLen = HcStrlen(credId) / BYTE_TO_HEX_OPER_LENGTH;
Uint8Buff credIdByte = { NULL, credIdByteLen };
credIdByte.val = (uint8_t *)HcMalloc(credIdByteLen, 0);
if (credIdByte.val == NULL) {
LOGE("Failed to malloc credIdByteLen");
return IS_ERR_ALLOC_MEMORY;
}
int32_t ret = HexStringToByte(credId, credIdByte.val, credIdByte.length);
if (ret != IS_SUCCESS) {
LOGE("Failed to convert credId to byte, invalid credId, ret = %" LOG_PUB "d", ret);
HcFree(credIdByte.val);
return IS_ERR_INVALID_HEX_STRING;
}
ret = GetLoaderInstance()->checkKeyExist(&credIdByte, false, osAccountId);
HcFree(credIdByte.val);
switch (ret) {
case HAL_ERR_KEY_NOT_EXIST:
LOGE("Huks key not exist!");
DelCredById(osAccountId, credId);
break;
case HAL_ERR_HUKS:
LOGE("Failed to check key exist in huks");
break;
case IS_SUCCESS:
break;
default:
LOGE("CheckKeyExist failed");
break;
}
return ret;
}
static void ReloadCredIfNeeded(int32_t osAccountId, const CJson *reqJson, const Credential *credential)
{
if (credential->credType != ACCOUNT_RELATED) {
return;
}
bool isQueryOpenCred = false;
if (GetBoolFromJson(reqJson, FIELD_IS_QUERY_OPEN_CRED, &isQueryOpenCred) != HC_SUCCESS) {
LOGW("Open query flag not exists!");
}
if (!isQueryOpenCred) {
return;
}
const char *extendInfoJsonStr = StringGet(&credential->extendInfo);
if (extendInfoJsonStr == NULL) {
LOGE("extendInfo is null!");
return;
}
CJson *extendInfoJson = CreateJsonFromString(extendInfoJsonStr);
if (extendInfoJson == NULL) {
LOGE("Failed to create extendInfoJson!");
return;
}
bool isOpenCredRegistered = false;
if (GetBoolFromJson(extendInfoJson, FIELD_IS_OPEN_CRED_REGISTERED, &isOpenCredRegistered) != HC_SUCCESS) {
LOGE("Failed to get isOpenCredRegistered!");
FreeJson(extendInfoJson);
return;
}
FreeJson(extendInfoJson);
if (isOpenCredRegistered) {
LOGI("Open cred is already registered.");
return;
}
if (HasAccountPlugin()) {
LOGI("Try to reload account related cred.");
(void)ExecuteAccountAuthCmd(osAccountId, FORCE_RELOAD_CRED_MGR, NULL, NULL);
}
}
int32_t GetCredIdsFromCredVec(int32_t osAccountId, CJson *reqJson, CredentialVec *credentialVec, CJson *credIdJson)
{
uint32_t index;
int32_t ret;
Credential **ptr;
FOR_EACH_HC_VECTOR(*credentialVec, index, ptr) {
if (*ptr == NULL) {
continue;
}
Credential *credential = (Credential *)(*ptr);
const char *credId = StringGet(&credential->credId);
if (CheckCredKeyExist(osAccountId, credential, credId) != IS_SUCCESS) {
LOGE("CredKey not Exist!");
continue;
}
if (!IsCredHashMatch(credential, reqJson)) {
continue;
}
ReloadCredIfNeeded(osAccountId, reqJson, credential);
ret = AddStringToArray(credIdJson, credId);
if (ret != IS_SUCCESS) {
LOGE("Failed to add credId to json");
return IS_ERR_JSON_ADD;
}
PRINT_SENSITIVE_DATA("credId", credId);
}
LOGI("credIdList size is: %" LOG_PUB "d", GetItemNum(credIdJson));
return IS_SUCCESS;
}
static int32_t UpdateExtendInfo(Credential *credential, const char *extendInfo)
{
if (!StringSetPointer(&credential->extendInfo, extendInfo)) {
LOGE("Failed to update extendInfo");
return IS_ERR_MEMORY_COPY;
}
return IS_SUCCESS;
}
static int32_t UpdateAppList(Credential *credential, CJson *appList)
{
DestroyStrVector(&credential->authorizedAppList);
credential->authorizedAppList = CreateStrVector();
int32_t ret = SetVectorFromList(&credential->authorizedAppList, appList);
if (ret != IS_SUCCESS) {
LOGE("Failed to update authorizedAppList");
return ret;
}
return IS_SUCCESS;
}
int32_t UpdateInfoFromJson(Credential *credential, CJson *json)
{
const char *extendInfo = GetStringFromJson(json, FIELD_EXTEND_INFO);
CJson *appList = GetObjFromJson(json, FIELD_AUTHORIZED_APP_LIST);
if (extendInfo == NULL && appList == NULL) {
LOGE("Failed to set update info: no valid field");
return IS_ERR_INVALID_PARAMS;
}
int32_t ret;
if (extendInfo != NULL) {
ret = UpdateExtendInfo(credential, extendInfo);
if (ret != IS_SUCCESS) {
return ret;
}
}
if (appList != NULL) {
ret = UpdateAppList(credential, appList);
}
return ret;
}
int32_t DelCredById(int32_t osAccountId, const char *credId)
{
QueryCredentialParams delParams = InitQueryCredentialParams();
delParams.credId = credId;
int32_t ret = DelCredential(osAccountId, &delParams);
if (ret != IS_SUCCESS) {
LOGE("Failed to delete credential, ret: %" LOG_PUB "d", ret);
return ret;
}
ret = SaveOsAccountCredDb(osAccountId);
if (ret != IS_SUCCESS) {
LOGE("Failed to save CredDb, ret: %" LOG_PUB "d", ret);
return ret;
}
return IS_SUCCESS;
}
int32_t AddKeyValueToReturn(Uint8Buff keyValue, char **returnData)
{
CJson *keyValueJson = CreateJson();
if (keyValueJson == NULL) {
LOGE("Failed to create keyValueJson");
return IS_ERR_JSON_CREATE;
}
int32_t ret = AddByteToJson(keyValueJson, FIELD_KEY_VALUE, keyValue.val, keyValue.length);
if (ret != IS_SUCCESS) {
LOGE("Failed to add key value to json");
FreeJson(keyValueJson);
return IS_ERR_JSON_ADD;
}
*returnData = PackJsonToString(keyValueJson);
FreeJson(keyValueJson);
if (*returnData == NULL) {
LOGE("Failed to pack key value json to string");
return IS_ERR_PACKAGE_JSON_TO_STRING_FAIL;
}
return IS_SUCCESS;
}
int32_t GenerateReturnEmptyArrayStr(char **returnVec)
{
CJson *json = CreateJsonArray();
if (json == NULL) {
LOGE("Failed to allocate json memory!");
return IS_ERR_JSON_CREATE;
}
*returnVec = PackJsonToString(json);
FreeJson(json);
if (*returnVec == NULL) {
LOGE("Failed to convert json to string!");
return IS_ERR_PACKAGE_JSON_TO_STRING_FAIL;
}
return IS_SUCCESS;
}
int32_t CheckOwnerUidPermission(Credential *credential)
{
int32_t currentUid = GetCallingUid();
if (currentUid == DEV_AUTH_UID && credential->credType == ACCOUNT_RELATED) {
return IS_SUCCESS;
}
if (currentUid != credential->ownerUid) {
LOGE("check Onwer Uid failed, currentUid: %" LOG_PUB "d, ownerUid: %" LOG_PUB "d",
currentUid, credential->ownerUid);
return IS_ERR_OWNER_UID;
}
return IS_SUCCESS;
}
int32_t GenerateCredKeyAlias(const char *credId, const char *deviceId, Uint8Buff *alias)
{
if ((credId == NULL) || (deviceId == NULL) || (alias == NULL)) {
LOGE("Invalid input params");
return IS_ERR_NULL_PTR;
}
uint32_t credIdLen = HcStrlen(credId);
uint32_t deviceIdLen = HcStrlen(deviceId);
uint32_t aliasStrLen = credIdLen + deviceIdLen + 1;
uint8_t *aliasStr = (uint8_t *)HcMalloc(aliasStrLen, 0);
if (aliasStr == NULL) {
LOGE("Failed to malloc for key aliasStr.");
return IS_ERR_ALLOC_MEMORY;
}
Uint8Buff aliasBuff = {
aliasStr,
aliasStrLen
};
if (memcpy_s(aliasBuff.val, aliasBuff.length, credId, credIdLen) != EOK) {
LOGE("Failed to copy credId.");
HcFree(aliasStr);
return IS_ERR_MEMORY_COPY;
}
if (memcpy_s(aliasBuff.val + credIdLen, deviceIdLen,
deviceId, deviceIdLen) != EOK) {
LOGE("Failed to copy deviceId.");
HcFree(aliasStr);
return IS_ERR_MEMORY_COPY;
}
int32_t ret = GetLoaderInstance()->sha256(&aliasBuff, alias);
HcFree(aliasStr);
if (ret != HAL_SUCCESS) {
LOGE("Compute alias failed");
}
return ret;
}
static int32_t ComputeAndSavePskInner(int32_t osAccountId, uint8_t credAlgo, const Uint8Buff *selfKeyAlias,
const Uint8Buff *peerKeyAlias, Uint8Buff *sharedKeyAlias)
{
KeyParams selfKeyParams = { { selfKeyAlias->val, selfKeyAlias->length, true }, false, osAccountId };
uint8_t peerPubKeyVal[KEY_VALUE_MAX_LENGTH] = { 0 };
Uint8Buff peerPubKeyBuff = { peerPubKeyVal, KEY_VALUE_MAX_LENGTH };
KeyParams keyParams = { { peerKeyAlias->val, peerKeyAlias->length, true }, false, osAccountId };
int32_t res = GetLoaderInstance()->exportPublicKey(&keyParams, &peerPubKeyBuff);
if (res != IS_SUCCESS) {
LOGE("Failed to export peer public key!");
return res;
}
KeyBuff peerKeyBuff = { peerPubKeyBuff.val, peerPubKeyBuff.length, false };
Algorithm algo = GetAlgoFromCred(credAlgo);
res = GetLoaderInstance()->agreeSharedSecretWithStorage(&selfKeyParams, &peerKeyBuff, algo,
PSK_LEN, sharedKeyAlias);
if (res != IS_SUCCESS) {
LOGE("Agree psk failed.");
}
return res;
}
int32_t SetAgreeCredInfo(int32_t osAccountId, CJson *reqJson,
Credential *agreeCredential, Uint8Buff *keyValue, Uint8Buff *agreeCredIdByte)
{
if (AddIntToJson(reqJson, FIELD_METHOD, METHOD_IMPORT) != IS_SUCCESS) {
LOGE("Failed to add method to json!");
return IS_ERR_JSON_ADD;
}
uint8_t method = DEFAULT_VAL;
int32_t ret = CheckAndSetCredInfo(osAccountId, agreeCredential, reqJson, &method, keyValue);
if (ret != IS_SUCCESS) {
return ret;
}
if ((ret = GenerateCredId(osAccountId, agreeCredential, agreeCredIdByte)) != IS_SUCCESS) {
HcFree(keyValue->val);
return ret;
}
return IS_SUCCESS;
}
int32_t ImportAgreeKeyValue(int32_t osAccountId, Credential *agreeCredential, Uint8Buff *keyValue,
Uint8Buff *peerKeyAlias)
{
int32_t ret = GenerateCredKeyAlias(
StringGet(&agreeCredential->credId), StringGet(&agreeCredential->deviceId), peerKeyAlias);
if (ret != IS_SUCCESS) {
LOGE("Failed to generate peer key alias!");
return ret;
}
ret = AddKeyValueToHuks(osAccountId, peerKeyAlias, agreeCredential, METHOD_IMPORT, keyValue);
if (ret != IS_SUCCESS) {
LOGE("Failed to add peer key value to huks!");
return ret;
}
return IS_SUCCESS;
}
int32_t CheckAndDelInvalidCred(int32_t osAccountId, const char *selfCredId, Uint8Buff *selfCredIdByte)
{
int32_t ret = GetValidKeyAlias(osAccountId, selfCredId, selfCredIdByte);
if (ret == HAL_ERR_KEY_NOT_EXIST) {
LOGE("Huks key not exist!");
DelCredById(osAccountId, selfCredId);
return IS_ERR_HUKS_KEY_NOT_EXIST;
}
if (ret == HAL_ERR_HUKS) {
LOGE("Huks check key exist failed");
return IS_ERR_HUKS_CHECK_KEY_EXIST_FAILED;
}
if (ret != IS_SUCCESS) {
LOGE("Failed to check key exist in HUKS");
return ret;
}
return IS_SUCCESS;
}
int32_t ComputePskAndDelInvalidKey(int32_t osAccountId, uint8_t credAlgo, Uint8Buff *selfCredIdByte,
Uint8Buff *peerKeyAlias, Uint8Buff *agreeCredIdByte)
{
int32_t ret = ComputeAndSavePskInner(osAccountId, credAlgo, selfCredIdByte, peerKeyAlias, agreeCredIdByte);
if (ret != IS_SUCCESS) {
LOGE("Failed to compute and save psk!");
return ret;
}
ret = GetLoaderInstance()->deleteKey(peerKeyAlias, false, osAccountId);
if (ret != IS_SUCCESS) {
LOGE("Failed to delete key from HUKS");
return ret;
}
return IS_SUCCESS;
}
int32_t SetRequiredParamsFromJson(QueryCredentialParams *queryParams, CJson *baseInfoJson)
{
if (GetUint8FromJson(baseInfoJson, FIELD_CRED_TYPE, &(queryParams->credType)) != IS_SUCCESS) {
LOGE("Failed to set query params: credType");
return IS_ERR_JSON_GET;
}
if (queryParams->credType != ACCOUNT_SHARED) {
LOGE("Not support for credType %" LOG_PUB "d, only support for ACCOUNT_SHARED", queryParams->credType);
return IS_ERR_NOT_SUPPORT;
}
const char *credOwner = GetStringFromJson(baseInfoJson, FIELD_CRED_OWNER);
if (credOwner == NULL || IsStrEqual(credOwner, "")) {
LOGE("Failed to set query params: credOwner");
return IS_ERR_JSON_GET;
}
queryParams->credOwner = credOwner;
return IS_SUCCESS;
}
int32_t SetUpdateToQueryParams(CJson *json, QueryCredentialParams *queryParams)
{
const char *userId = GetStringFromJson(json, FIELD_USER_ID);
if (userId == NULL || IsStrEqual(userId, "")) {
LOGE("Failed to set query params: userId");
return IS_ERR_JSON_GET;
}
queryParams->userId = userId;
const char *deviceId = GetStringFromJson(json, FIELD_DEVICE_ID);
if (deviceId == NULL || IsStrEqual(deviceId, "")) {
LOGE("Failed to set query params: deviceId");
return IS_ERR_JSON_GET;
}
queryParams->deviceId = deviceId;
return IS_SUCCESS;
}
static int32_t EraseCredIdInVec(const char *credId, CredentialVec *credVec)
{
uint32_t index = 0;
Credential **item;
while (index < credVec->size(credVec)) {
item = credVec->getp(credVec, index);
if (item == NULL || *item == NULL) {
index++;
continue;
}
const char *itemCredId = StringGet(&(*item)->credId);
if (itemCredId != NULL && IsStrEqual(credId, itemCredId)) {
credVec->eraseElement(credVec, item, index);
return IS_SUCCESS;
}
index++;
}
return IS_ERROR;
}
int32_t AddUpdateInfoToJson(QueryCredentialParams *queryParams, CJson *baseInfoJson)
{
if (AddStringToJson(baseInfoJson, FIELD_USER_ID, queryParams->userId) != IS_SUCCESS) {
LOGE("add userId to baseInfoJson fail.");
return IS_ERR_JSON_ADD;
}
if (AddStringToJson(baseInfoJson, FIELD_DEVICE_ID, queryParams->deviceId) != IS_SUCCESS) {
LOGE("add deviceId to baseInfoJson fail.");
return IS_ERR_JSON_ADD;
}
if (AddIntToJson(baseInfoJson, FIELD_METHOD, METHOD_IMPORT) != IS_SUCCESS) {
LOGE("Failed to add method to baseInfoJson!");
return IS_ERR_JSON_ADD;
}
return IS_SUCCESS;
}
int32_t EraseUpdateCredIdInSelfVec(CredentialVec *updateCredVec, CredentialVec *selfCredVec)
{
Credential **cred = updateCredVec->getp(updateCredVec, 0);
if (cred == NULL || *cred == NULL) {
LOGE("Failed to get first cred");
return IS_ERR_NULL_PTR;
}
const char *updateCredId = StringGet(&(*cred)->credId);
if (updateCredId == NULL) {
LOGE("Failed to get updateCredId");
return IS_ERR_NULL_PTR;
}
return EraseCredIdInVec(updateCredId, selfCredVec);
}
int32_t GetQueryJsonStr(CJson *baseInfoJson, char **queryJsonStr)
{
const char *credOwner = GetStringFromJson(baseInfoJson, FIELD_CRED_OWNER);
if (credOwner == NULL) {
LOGE("Failed to get credOwner");
return IS_ERR_INVALID_PARAMS;
}
CJson *queryJson = CreateJson();
if (queryJson == NULL) {
LOGE("Failed to create queryJson");
return IS_ERR_JSON_CREATE;
}
if (AddStringToJson(queryJson, FIELD_CRED_OWNER, credOwner)) {
FreeJson(queryJson);
return IS_ERR_JSON_ADD;
}
*queryJsonStr = PackJsonToString(queryJson);
FreeJson(queryJson);
if (*queryJsonStr == NULL) {
LOGE("Failed to pack queryJson to string");
return IS_ERR_PACKAGE_JSON_TO_STRING_FAIL;
}
return IS_SUCCESS;
}
int32_t GetUpdateCredVec(int32_t osAccountId, CJson *updateInfo,
QueryCredentialParams *queryParams, CredentialVec *updateCredVec)
{
int32_t ret = SetUpdateToQueryParams(updateInfo, queryParams);
if (ret != IS_SUCCESS) {
LOGE("Failed to set updateLists to query params");
return ret;
}
return QueryCredentials(osAccountId, queryParams, updateCredVec);
}