!205 【SR000GVLTP】【SR000H039Q】【SR000H039R】【SR000H03A7】【MR账号相关非对称需求】

Merge pull request !205 from 胡玉/master
This commit is contained in:
openharmony_ci
2022-04-26 02:09:59 +00:00
committed by Gitee
70 changed files with 6351 additions and 403 deletions
+1 -1
View File
@@ -13,7 +13,7 @@
declare_args() {
enable_group = true
enable_account = false
enable_account = true
enable_p2p_bind_lite_protocol = true
enable_p2p_auth_lite_protocol = true
+7 -3
View File
@@ -1,4 +1,4 @@
# Copyright (C) 2021 Huawei Device Co., Ltd.
# Copyright (C) 2021-2022 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
@@ -63,12 +63,13 @@ if (defined(ohos_lite)) {
"//base/hiviewdfx/hilog_lite/interfaces/native/innerkits/hilog",
"//third_party/bounds_checking_function/include",
"//base/startup/syspara_lite/interfaces/kits/",
"//third_party/mbedtls/include",
]
sources = hal_common_files
sources += [
"${key_management_adapter_path}/impl/src/small/huks_adapter.c",
"${key_management_adapter_path}/impl/src/small/mbedtls_hash_to_point.c",
"${key_management_adapter_path}/impl/src/small/mbedtls_ec_adapter.c",
"${os_adapter_path}/impl/src/linux/hc_condition.c",
"${os_adapter_path}/impl/src/linux/hc_dev_info.c",
"${os_adapter_path}/impl/src/linux/hc_file.c",
@@ -79,7 +80,6 @@ if (defined(ohos_lite)) {
cflags = [ "-DHILOG_ENABLE" ]
defines = [ "LITE_DEVICE" ]
deps = [
"//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared",
"//base/security/huks/interfaces/innerkits/huks_lite:huks_3.0_sdk",
@@ -102,12 +102,15 @@ if (defined(ohos_lite)) {
"//third_party/openssl/include/",
"//base/security/huks/interfaces/innerkits/huks_standard/main/include",
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include",
"//third_party/mbedtls/include",
"//third_party/mbedtls/include/mbedtls",
]
sources = hal_common_files
sources += [
"${key_management_adapter_path}/impl/src/standard/crypto_hash_to_point.c",
"${key_management_adapter_path}/impl/src/standard/huks_adapter.c",
"${key_management_adapter_path}/impl/src/standard/mbedtls_ec_adapter.c",
"${os_adapter_path}/impl/src/linux/hc_condition.c",
"${os_adapter_path}/impl/src/linux/hc_dev_info.c",
"${os_adapter_path}/impl/src/linux/hc_file.c",
@@ -120,6 +123,7 @@ if (defined(ohos_lite)) {
"//base/security/huks/interfaces/innerkits/huks_standard/main:libhukssdk",
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara",
"//third_party/cJSON:cjson_static",
"//third_party/mbedtls:mbedtls_shared",
"//third_party/openssl:libcrypto_static",
"//utils/native/base:utils",
]
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2022 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
@@ -13,11 +13,12 @@
* limitations under the License.
*/
#ifndef MBEDTLS_HASH_TO_POINT_H
#define MBEDTLS_HASH_TO_POINT_H
#ifndef MBEDTLS_EC_ADAPTER_H
#define MBEDTLS_EC_ADAPTER_H
#include <stdint.h>
#include "string_util.h"
#include "alg_defs.h"
#define HASH2POINT_PARA_PREPRO 0xc0
#define BYTE_LENGTH_CURVE_25519 32
@@ -27,8 +28,9 @@ extern "C" {
#endif
int32_t MbedtlsHashToPoint(const Uint8Buff *hash, Uint8Buff *outEcPoint);
int32_t MbedtlsAgreeSharedSecret(const KeyBuff *priKey, const KeyBuff *pubKey, Uint8Buff *sharedKey);
#ifdef __cplusplus
}
#endif
#endif
#endif
@@ -18,7 +18,7 @@
#include "hks_api.h"
#include "hks_param.h"
#include "hks_type.h"
#include "mbedtls_hash_to_point.h"
#include "mbedtls_ec_adapter.h"
#include "string_util.h"
static enum HksKeyAlg g_algToHksAlgorithm[] = {
@@ -619,6 +619,9 @@ static int32_t ConstructGenerateKeyPairWithStorageParams(struct HksParamSet **pa
}, {
.tag = HKS_TAG_KEY_AUTH_ID,
.blob = *authIdBlob
}, {
.tag = HKS_TAG_DIGEST,
.uint32Param = HKS_DIGEST_SHA256
}
};
@@ -804,7 +807,10 @@ static int32_t ConstructSignParams(struct HksParamSet **paramSet, Algorithm algo
.uint32Param = HKS_KEY_PURPOSE_SIGN
}, {
.tag = HKS_TAG_ALGORITHM,
.uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_ED25519
.uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_ED25519 and HKS_ALG_ECC.
}, {
.tag = HKS_TAG_DIGEST,
.uint32Param = HKS_DIGEST_SHA256
}
};
@@ -826,7 +832,6 @@ static int32_t Sign(const Uint8Buff *keyAlias, const Uint8Buff *message, Algorit
if (ret != HAL_SUCCESS) {
return ret;
}
CHECK_LEN_EQUAL_RETURN(outSignature->length, SIGNATURE_LEN, "outSignature->length");
struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
Uint8Buff messageHash = { NULL, 0 };
@@ -851,11 +856,12 @@ static int32_t Sign(const Uint8Buff *keyAlias, const Uint8Buff *message, Algorit
}
ret = HksSign(&keyAliasBlob, paramSet, &messageBlob, &signatureBlob);
if ((ret != HKS_SUCCESS) || (signatureBlob.size != SIGNATURE_LEN)) {
if (ret != HKS_SUCCESS) {
LOGE("Hks sign failed.");
ret = HAL_FAILED;
goto ERR;
}
outSignature->length = signatureBlob.size;
ret = HAL_SUCCESS;
ERR:
HksFreeParamSet(&paramSet);
@@ -871,10 +877,13 @@ static int32_t ConstructVerifyParams(struct HksParamSet **paramSet, Algorithm al
.uint32Param = HKS_KEY_PURPOSE_VERIFY
}, {
.tag = HKS_TAG_ALGORITHM,
.uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_ED25519
.uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_ED25519 and HKS_ALG_ECC.
}, {
.tag = HKS_TAG_IS_KEY_ALIAS,
.boolParam = isAlias
}, {
.tag = HKS_TAG_DIGEST,
.uint32Param = HKS_DIGEST_SHA256
}
};
@@ -896,7 +905,6 @@ static int32_t Verify(const Uint8Buff *key, const Uint8Buff *message, Algorithm
if (ret != HAL_SUCCESS) {
return ret;
}
CHECK_LEN_EQUAL_RETURN(signature->length, SIGNATURE_LEN, "signature");
struct HksBlob keyAliasBlob = { key->length, key->val };
Uint8Buff messageHash = { NULL, 0 };
@@ -936,6 +944,9 @@ ERR:
static int32_t ConstructImportPublicKeyParams(struct HksParamSet **paramSet, Algorithm algo, uint32_t keyLen,
const struct HksBlob *authIdBlob, const union KeyRoleInfoUnion *roleInfoUnion)
{
if (g_algToHksAlgorithm[algo] == HKS_ALG_ECC) {
keyLen = ECC_PK_LEN;
}
struct HksParam importParam[] = {
{
.tag = HKS_TAG_ALGORITHM,
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2022 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
@@ -13,7 +13,7 @@
* limitations under the License.
*/
#include "mbedtls_hash_to_point.h"
#include "mbedtls_ec_adapter.h"
#include <stdio.h>
#include <mbedtls/bignum.h>
#include "securec.h"
@@ -279,3 +279,10 @@ int32_t MbedtlsHashToPoint(const Uint8Buff *hash, Uint8Buff *outEcPoint)
}
return status;
}
// only support P256 AgreeSharedSecret for standard system
int32_t MbedtlsAgreeSharedSecret(const KeyBuff *priKey, const KeyBuff *pubKey, Uint8Buff *sharedKey)
{
LOGE("MbedtlsAgreeSharedSecret for P256 is not supported now in small system.");
return HAL_ERR_NOT_SUPPORTED;
}
@@ -19,10 +19,12 @@
#include "hks_api.h"
#include "hks_param.h"
#include "hks_type.h"
#include "mbedtls_ec_adapter.h"
#include "string_util.h"
#define BASE_IMPORT_PARAMS_LEN 7
#define EXT_IMPORT_PARAMS_LEN 2
#define ECDH_COMMON_SIZE_P256 512
static enum HksKeyPurpose g_purposeToHksKeyPurpose[] = {
HKS_KEY_PURPOSE_MAC,
@@ -419,29 +421,135 @@ static int32_t AesGcmDecrypt(const Uint8Buff *key, const Uint8Buff *cipher,
static int32_t HashToPoint(const Uint8Buff *hash, Algorithm algo, Uint8Buff *outEcPoint)
{
CHECK_PTR_RETURN_HAL_ERROR_CODE(hash, "hash");
CHECK_PTR_RETURN_HAL_ERROR_CODE(hash->val, "hash->va");
CHECK_PTR_RETURN_HAL_ERROR_CODE(hash->val, "hash->val");
CHECK_LEN_EQUAL_RETURN(hash->length, SHA256_LEN, "hash->length");
CHECK_PTR_RETURN_HAL_ERROR_CODE(outEcPoint, "outEcPoint");
CHECK_PTR_RETURN_HAL_ERROR_CODE(outEcPoint->val, "outEcPoint->va");
CHECK_LEN_EQUAL_RETURN(outEcPoint->length, SHA256_LEN, "outEcPoint->length");
CHECK_PTR_RETURN_HAL_ERROR_CODE(outEcPoint->val, "outEcPoint->val");
if (algo != X25519) {
LOGE("Invalid algo: %d.", algo);
if (algo != X25519 && algo != P256) {
LOGE("Compute algo: %d.", algo);
return HAL_ERR_INVALID_PARAM;
}
if (algo == P256) {
LOGI("Compute HashToPoint for P256");
return MbedtlsHashToPoint(hash, outEcPoint);
}
CHECK_LEN_EQUAL_RETURN(outEcPoint->length, SHA256_LEN, "outEcPoint->length");
struct HksBlob hashBlob = { hash->length, hash->val };
struct HksBlob pointBlob = { outEcPoint->length, outEcPoint->val };
int32_t ret = OpensslHashToPoint(&hashBlob, &pointBlob);
if (ret != HAL_SUCCESS || pointBlob.size != SHA256_LEN) {
LOGE("Hks hashToPoint failed, ret: %d", ret);
LOGE("HashToPoint for x25519 failed, ret: %d", ret);
return HAL_FAILED;
}
return HAL_SUCCESS;
}
static int32_t ConstructInitParamsP256(struct HksParamSet **initParamSet)
{
struct HksParam agreeParamInit[] = {
{
.tag = HKS_TAG_ALGORITHM,
.uint32Param = HKS_ALG_ECDH
}, {
.tag = HKS_TAG_PURPOSE,
.uint32Param = HKS_KEY_PURPOSE_AGREE
}, {
.tag = HKS_TAG_KEY_SIZE,
.uint32Param = HKS_ECC_KEY_SIZE_256
}
};
int32_t ret = ConstructParamSet(initParamSet, agreeParamInit, CAL_ARRAY_SIZE(agreeParamInit));
if (ret != HAL_SUCCESS) {
LOGE("Construct init param set failed for P256, ret = %d", ret);
}
return ret;
}
static int32_t ConstructFinishParamsP256(struct HksParamSet **finishParamSet,
const struct HksBlob *sharedKeyAliasBlob)
{
struct HksParam agreeParamFinish[] = {
{
.tag = HKS_TAG_KEY_STORAGE_FLAG,
.uint32Param = HKS_STORAGE_PERSISTENT
}, {
.tag = HKS_TAG_IS_KEY_ALIAS,
.boolParam = true
}, {
.tag = HKS_TAG_ALGORITHM,
.uint32Param = HKS_ALG_AES
}, {
.tag = HKS_TAG_KEY_SIZE,
.uint32Param = HKS_AES_KEY_SIZE_256
}, {
.tag = HKS_TAG_PURPOSE,
.uint32Param = HKS_KEY_PURPOSE_DERIVE
}, {
.tag = HKS_TAG_DIGEST,
.uint32Param = HKS_DIGEST_SHA256
}, {
.tag = HKS_TAG_KEY_ALIAS,
.blob = *sharedKeyAliasBlob
}
};
int32_t ret = ConstructParamSet(finishParamSet, agreeParamFinish, CAL_ARRAY_SIZE(agreeParamFinish));
if (ret != HAL_SUCCESS) {
LOGE("Construct finish param set failed for P256, ret = %d", ret);
}
return ret;
}
static int32_t AgreeSharedSecretWithStorageP256(const KeyBuff *priKeyAlias, const KeyBuff *pubKey,
const struct HksBlob *sharedKeyAliasBlob)
{
struct HksParamSet *initParamSet = NULL;
struct HksParamSet *finishParamSet = NULL;
int32_t ret = ConstructInitParamsP256(&initParamSet);
if (ret != HAL_SUCCESS) {
return ret;
}
ret = ConstructFinishParamsP256(&finishParamSet, sharedKeyAliasBlob);
if (ret != HAL_SUCCESS) {
HksFreeParamSet(&initParamSet);
return ret;
}
struct HksBlob priKeyAliasBlob = { priKeyAlias->keyLen, priKeyAlias->key };
struct HksBlob pubKeyBlob = { pubKey->keyLen, pubKey->key };
uint8_t handle[sizeof(uint64_t)] = { 0 };
struct HksBlob handleBlob = { sizeof(uint64_t), handle };
uint8_t outDataUpdate[ECDH_COMMON_SIZE_P256] = { 0 };
struct HksBlob outDataUpdateBlob = { ECDH_COMMON_SIZE_P256, outDataUpdate };
uint8_t outDataFinish[ECDH_COMMON_SIZE_P256] = { 0 };
struct HksBlob outDataFinishBlob = { ECDH_COMMON_SIZE_P256, outDataFinish };
do {
ret = HksInit(&priKeyAliasBlob, initParamSet, &handleBlob);
if (ret != HKS_SUCCESS) {
LOGE("Huks agree P256 key: HksInit failed, ret = %d", ret);
ret = HAL_ERR_HUKS;
break;
}
ret = HksUpdate(&handleBlob, initParamSet, &pubKeyBlob, &outDataUpdateBlob);
if (ret != HKS_SUCCESS) {
LOGE("Huks agree P256 key: HksUpdate failed, ret = %d", ret);
ret = HAL_ERR_HUKS;
break;
}
ret = HksFinish(&handleBlob, finishParamSet, &pubKeyBlob, &outDataFinishBlob);
if (ret != HKS_SUCCESS) {
LOGE("Huks agree P256 key: HksFinish failed, ret = %d", ret);
ret = HAL_ERR_HUKS;
break;
}
} while (0);
HksFreeParamSet(&initParamSet);
HksFreeParamSet(&finishParamSet);
return ret;
}
static int32_t ConstructAgreeWithStorageParams(struct HksParamSet **paramSet, uint32_t keyLen, Algorithm algo,
const KeyBuff *priKey, const KeyBuff *pubKey)
{
@@ -465,7 +573,7 @@ static int32_t ConstructAgreeWithStorageParams(struct HksParamSet **paramSet, ui
.uint32Param = HKS_KEY_GENERATE_TYPE_AGREE
}, {
.tag = HKS_TAG_AGREE_ALG,
.uint32Param = g_algToHksAlgorithm[algo]
.uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_ED25519 and HKS_ALG_X25519
}, {
.tag = HKS_TAG_AGREE_PRIVATE_KEY_ALIAS,
.blob = priKeyBlob
@@ -481,7 +589,6 @@ static int32_t ConstructAgreeWithStorageParams(struct HksParamSet **paramSet, ui
int32_t ret = ConstructParamSet(paramSet, agreeParam, CAL_ARRAY_SIZE(agreeParam));
if (ret != HAL_SUCCESS) {
LOGE("Construct param set failed, ret = %d", ret);
return ret;
}
return ret;
}
@@ -501,6 +608,10 @@ static int32_t AgreeSharedSecretWithStorage(const KeyBuff *priKey, const KeyBuff
CHECK_LEN_ZERO_RETURN_ERROR_CODE(sharedKeyLen, "sharedKeyLen");
struct HksBlob sharedKeyAliasBlob = { sharedKeyAlias->length, sharedKeyAlias->val };
if (g_algToHksAlgorithm[algo] == HKS_ALG_ECC) {
LOGI("Hks agree key with storage for P256.");
return AgreeSharedSecretWithStorageP256(priKey, pubKey, &sharedKeyAliasBlob);
}
struct HksParamSet *paramSet = NULL;
int32_t ret = ConstructAgreeWithStorageParams(&paramSet, sharedKeyLen, algo, priKey, pubKey);
if (ret != HAL_SUCCESS) {
@@ -530,6 +641,11 @@ static int32_t AgreeSharedSecret(const KeyBuff *priKey, const KeyBuff *pubKey, A
CHECK_PTR_RETURN_HAL_ERROR_CODE(sharedKey->val, "sharedKey->val");
CHECK_LEN_ZERO_RETURN_ERROR_CODE(sharedKey->length, "sharedKey->length");
if (g_algToHksAlgorithm[algo] == HKS_ALG_ECC) {
LOGI("Hks agree key for P256.");
return MbedtlsAgreeSharedSecret(priKey, pubKey, sharedKey);
}
struct HksBlob priKeyBlob = { priKey->keyLen, priKey->key };
struct HksBlob pubKeyBlob = { pubKey->keyLen, pubKey->key };
struct HksBlob sharedKeyBlob = { sharedKey->length, sharedKey->val };
@@ -630,6 +746,9 @@ static int32_t ConstructGenerateKeyPairWithStorageParams(struct HksParamSet **pa
}, {
.tag = HKS_TAG_KEY_AUTH_ID,
.blob = *authIdBlob
}, {
.tag = HKS_TAG_DIGEST,
.uint32Param = HKS_DIGEST_SHA256
}
};
@@ -815,7 +934,10 @@ static int32_t ConstructSignParams(struct HksParamSet **paramSet, Algorithm algo
.uint32Param = HKS_KEY_PURPOSE_SIGN
}, {
.tag = HKS_TAG_ALGORITHM,
.uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_ED25519
.uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_ED25519 and HKS_ALG_ECC.
}, {
.tag = HKS_TAG_DIGEST,
.uint32Param = HKS_DIGEST_SHA256
}
};
@@ -837,7 +959,6 @@ static int32_t Sign(const Uint8Buff *keyAlias, const Uint8Buff *message, Algorit
if (ret != HAL_SUCCESS) {
return ret;
}
CHECK_LEN_EQUAL_RETURN(outSignature->length, SIGNATURE_LEN, "outSignature->length");
struct HksBlob keyAliasBlob = { keyAlias->length, keyAlias->val };
Uint8Buff messageHash = { NULL, 0 };
@@ -862,11 +983,12 @@ static int32_t Sign(const Uint8Buff *keyAlias, const Uint8Buff *message, Algorit
}
ret = HksSign(&keyAliasBlob, paramSet, &messageBlob, &signatureBlob);
if ((ret != HKS_SUCCESS) || (signatureBlob.size != SIGNATURE_LEN)) {
if (ret != HKS_SUCCESS) {
LOGE("Hks sign failed.");
ret = HAL_FAILED;
goto ERR;
}
outSignature->length = signatureBlob.size;
ret = HAL_SUCCESS;
ERR:
HksFreeParamSet(&paramSet);
@@ -882,10 +1004,13 @@ static int32_t ConstructVerifyParams(struct HksParamSet **paramSet, Algorithm al
.uint32Param = HKS_KEY_PURPOSE_VERIFY
}, {
.tag = HKS_TAG_ALGORITHM,
.uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_ED25519
.uint32Param = g_algToHksAlgorithm[algo] // only support HKS_ALG_ED25519 and HKS_ALG_ECC.
}, {
.tag = HKS_TAG_IS_KEY_ALIAS,
.boolParam = isAlias
}, {
.tag = HKS_TAG_DIGEST,
.uint32Param = HKS_DIGEST_SHA256
}
};
@@ -907,7 +1032,6 @@ static int32_t Verify(const Uint8Buff *key, const Uint8Buff *message, Algorithm
if (ret != HAL_SUCCESS) {
return ret;
}
CHECK_LEN_EQUAL_RETURN(signature->length, SIGNATURE_LEN, "signature");
struct HksBlob keyAliasBlob = { key->length, key->val };
Uint8Buff messageHash = { NULL, 0 };
@@ -947,6 +1071,9 @@ ERR:
static int32_t ConstructImportPublicKeyParams(struct HksParamSet **paramSet, Algorithm algo, uint32_t keyLen,
const struct HksBlob *authIdBlob, const union KeyRoleInfoUnion *roleInfoUnion)
{
if (g_algToHksAlgorithm[algo] == HKS_ALG_ECC) {
keyLen = ECC_PK_LEN;
}
struct HksParam importParam[] = {
{
.tag = HKS_TAG_ALGORITHM,
@@ -1129,6 +1256,13 @@ static bool CheckDlPublicKey(const Uint8Buff *key, const char *primeHex)
return true;
}
static bool CheckEcPublicKeyFuncFake(const Uint8Buff *pubKey, Algorithm algo)
{
(void)pubKey;
(void)algo;
return true;
}
static int32_t CheckImportSymmetricKeyParam(const Uint8Buff *keyAlias, const Uint8Buff *authToken)
{
const Uint8Buff *inParams[] = { keyAlias, authToken };
@@ -1244,7 +1378,7 @@ static const AlgLoader g_huksLoader = {
.verify = Verify,
.importPublicKey = ImportPublicKey,
.checkDlPublicKey = CheckDlPublicKey,
.checkEcPublicKey = NULL,
.checkEcPublicKey = CheckEcPublicKeyFuncFake,
.bigNumCompare = BigNumCompare
};
@@ -0,0 +1,313 @@
/*
* Copyright (C) 2022 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 "mbedtls_ec_adapter.h"
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#include <mbedtls/error.h>
#include <mbedtls/pk.h>
#include <mbedtls/x509.h>
#include "hal_error.h"
#include "hc_log.h"
#include "huks_adapter.h"
#define LOG_AND_RETURN_IF_FAIL(ret, fmt, ...) \
do { \
if ((ret) != 0) { \
LOGE(fmt, ##__VA_ARGS__); \
return (ret); \
} \
} while (0)
#define LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, fmt, ...) \
do { \
if ((ret) != 0) { \
LOGE(fmt, ##__VA_ARGS__); \
goto CLEAN_UP; \
} \
} while (0)
#define BITS_PER_BYTE 8
#define EC_LEN 64
#define SHA256_HASH_LEN 32
#define P256_KEY_SIZE 32
#define P256_PUBLIC_SIZE 64 // P256_KEY_SIZE * 2
typedef struct Blob {
uint32_t dataSize;
uint8_t *data;
} Blob;
static const uint8_t g_pointA[] = {
0x04, 0x53, 0xf9, 0xe4, 0xf4, 0xbc, 0x3a, 0xb5, 0x9d, 0x44, 0x78, 0x45, 0x21, 0x13, 0x8b, 0x49,
0xba, 0xa3, 0x1c, 0xe2, 0xa8, 0xdb, 0xbd, 0xb8, 0xd6, 0x73, 0x31, 0x46, 0x3a, 0x69, 0x53, 0xf1,
0xed, 0xef, 0x96, 0x1e, 0xdb, 0x42, 0xbe, 0x3a, 0x24, 0x43, 0xc4, 0x08, 0x23, 0xfb, 0x58, 0xee,
0x61, 0x24, 0x8b, 0x59, 0x64, 0x65, 0x2d, 0xbc, 0x6b, 0xa5, 0x1d, 0x6e, 0x04, 0x22, 0x53, 0xae,
0x27
};
static const uint8_t g_pointB[] = {
0x04, 0x03, 0x4d, 0x11, 0x11, 0xa6, 0x3f, 0x5f, 0x72, 0x43, 0x59, 0x73, 0x8b, 0x46, 0xc3, 0xfd,
0x70, 0x58, 0xb0, 0xb6, 0x11, 0xd3, 0x4f, 0xf3, 0x49, 0xa0, 0xd2, 0x86, 0xd7, 0x35, 0x33, 0xc5,
0x36, 0xe4, 0x99, 0xcc, 0x13, 0x47, 0xe4, 0xab, 0xde, 0x8f, 0x3a, 0xd6, 0x65, 0x1a, 0x77, 0x0b,
0xc4, 0x82, 0xd5, 0xac, 0x4b, 0x5d, 0xe4, 0xcc, 0x48, 0xb0, 0x54, 0x6c, 0x9b, 0x76, 0x76, 0x1a,
0xba
};
static const uint8_t g_randomSeedCustom[] = { 0x4C, 0x54, 0x4B, 0x53 }; // LTKS means LiteKeystore
static bool IsInvalidBlob(const Blob *blob)
{
return (blob == NULL) || (blob->data == NULL) || (blob->dataSize == 0);
}
static void InitPointParams(mbedtls_mpi *scalarA, mbedtls_mpi *scalarB, mbedtls_ecp_point *pointA,
mbedtls_ecp_point *pointB, mbedtls_ecp_point *result)
{
mbedtls_mpi_init(scalarA);
mbedtls_mpi_init(scalarB);
mbedtls_ecp_point_init(pointA);
mbedtls_ecp_point_init(pointB);
mbedtls_ecp_point_init(result);
}
static void FreePointParams(mbedtls_mpi *scalarA, mbedtls_mpi *scalarB, mbedtls_ecp_point *pointA,
mbedtls_ecp_point *pointB, mbedtls_ecp_point *result)
{
mbedtls_mpi_free(scalarA);
mbedtls_mpi_free(scalarB);
mbedtls_ecp_point_free(pointA);
mbedtls_ecp_point_free(pointB);
mbedtls_ecp_point_free(result);
}
static int32_t CalculateMessageDigest(mbedtls_md_type_t type, const Blob *input, Blob *output)
{
const mbedtls_md_info_t *info = mbedtls_md_info_from_type(type);
if (info == NULL) {
return HAL_ERR_NOT_SUPPORTED;
}
uint32_t outSize = mbedtls_md_get_size(info);
if (output->dataSize < outSize) {
return HAL_ERR_SHORT_BUFFER;
}
int32_t ret = mbedtls_md(info, input->data, input->dataSize, output->data);
LOG_AND_RETURN_IF_FAIL(ret, "Calculate message digest failed.\n");
output->dataSize = outSize;
return ret;
}
static int32_t Sha256(const Blob *input, Blob *output)
{
if (IsInvalidBlob(input) || IsInvalidBlob(output)) {
LOGE("Input params for sha256 is invalid.");
return HAL_ERR_INVALID_PARAM;
}
return CalculateMessageDigest(MBEDTLS_MD_SHA256, input, output);
}
static int32_t ReadBigNums(mbedtls_mpi *x, mbedtls_mpi *y, const Blob *blob)
{
int32_t ret = mbedtls_mpi_read_binary(x, blob->data, P256_KEY_SIZE);
LOG_AND_RETURN_IF_FAIL(ret, "Read x coordinate of public key failed.");
return mbedtls_mpi_read_binary(y, blob->data + P256_KEY_SIZE, P256_KEY_SIZE);
}
static int32_t ReadEcPublicKey(mbedtls_ecp_point *point, const Blob *publicKey)
{
int32_t ret = ReadBigNums(&point->X, &point->Y, publicKey);
LOG_AND_RETURN_IF_FAIL(ret, "Read coordinate of public key failed.");
return mbedtls_mpi_lset(&point->Z, 1);
}
static int32_t WriteOutBigNums(const mbedtls_mpi *x, const mbedtls_mpi *y, Blob *out)
{
int32_t ret = mbedtls_mpi_write_binary(x, out->data, P256_KEY_SIZE);
LOG_AND_RETURN_IF_FAIL(ret, "Write x coordinate of public key failed.");
ret = mbedtls_mpi_write_binary(y, out->data + P256_KEY_SIZE, P256_KEY_SIZE);
LOG_AND_RETURN_IF_FAIL(ret, "Write y coordinate of public key failed.");
out->dataSize = P256_PUBLIC_SIZE;
return ret;
}
static int32_t WriteOutEcPublicKey(const mbedtls_ecp_point *point, Blob *publicKey)
{
return WriteOutBigNums(&point->X, &point->Y, publicKey);
}
static int32_t EcKeyAgreement(const Blob *privateKey, const Blob *publicKey, Blob *secretKey)
{
if (IsInvalidBlob(publicKey) || publicKey->dataSize != P256_PUBLIC_SIZE || IsInvalidBlob(secretKey) ||
secretKey->dataSize != P256_PUBLIC_SIZE || IsInvalidBlob(privateKey)) {
LOGE("Input params for ec key agree is invalid.");
return HAL_ERR_INVALID_PARAM;
}
mbedtls_mpi *secret = HcMalloc(sizeof(mbedtls_mpi), 0);
mbedtls_ecp_keypair *keyPair = HcMalloc(sizeof(mbedtls_ecp_keypair), 0);
mbedtls_entropy_context *entropy = HcMalloc(sizeof(mbedtls_entropy_context), 0);
mbedtls_ctr_drbg_context *ctrDrbg = HcMalloc(sizeof(mbedtls_ctr_drbg_context), 0);
mbedtls_mpi_init(secret);
mbedtls_ecp_keypair_init(keyPair);
mbedtls_entropy_init(entropy);
mbedtls_ctr_drbg_init(ctrDrbg);
mbedtls_ecp_point P;
mbedtls_ecp_point_init(&P);
int32_t ret = ReadEcPublicKey(&keyPair->Q, publicKey);
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read the public key failed.\n");
ret = mbedtls_ecp_group_load(&keyPair->grp, MBEDTLS_ECP_DP_SECP256R1);
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Load the ecp group failed.\n");
ret = mbedtls_mpi_read_binary(&keyPair->d, privateKey->data, privateKey->dataSize);
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read the private key failed.\n");
ret = mbedtls_ctr_drbg_seed(ctrDrbg, mbedtls_entropy_func, entropy,
g_randomSeedCustom, sizeof(g_randomSeedCustom));
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set custom string failed.\n");
ret = mbedtls_ecp_mul_restartable(&keyPair->grp, &P, &keyPair->d, &keyPair->Q,
mbedtls_ctr_drbg_random, ctrDrbg, NULL);
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Compute secret key failed.\n");
mbedtls_mpi_copy(secret, &P.X);
WriteOutEcPublicKey(&P, secretKey);
CLEAN_UP:
mbedtls_mpi_free(secret);
mbedtls_ecp_keypair_free(keyPair);
mbedtls_entropy_free(entropy);
mbedtls_ctr_drbg_free(ctrDrbg);
mbedtls_ecp_point_free(&P);
HcFree(secret);
HcFree(keyPair);
HcFree(entropy);
HcFree(ctrDrbg);
return ret;
}
static int32_t EcHashToPoint(const Blob *hash, Blob *point)
{
if (IsInvalidBlob(hash) || IsInvalidBlob(point)) {
return HAL_ERR_INVALID_PARAM;
}
if (point->dataSize < P256_PUBLIC_SIZE) {
return HAL_ERR_SHORT_BUFFER;
}
mbedtls_mpi scalarA;
mbedtls_mpi scalarB;
mbedtls_ecp_point pointA;
mbedtls_ecp_point pointB;
mbedtls_ecp_point result;
InitPointParams(&scalarA, &scalarB, &pointA, &pointB, &result);
mbedtls_ecp_group grp;
mbedtls_ecp_group_init(&grp);
uint8_t digest[SHA256_HASH_LEN] = { 0 };
Blob digestBlob = { sizeof(digest), digest };
int32_t ret = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Load ecp group failed.\n");
ret = mbedtls_ecp_point_read_binary(&grp, &pointA, g_pointA, sizeof(g_pointA));
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read point A failed.\n");
ret = mbedtls_ecp_point_read_binary(&grp, &pointB, g_pointB, sizeof(g_pointB));
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read point B failed.\n");
ret = Sha256(hash, &digestBlob);
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Compute message digest failed.\n");
ret = mbedtls_mpi_lset(&scalarA, 1);
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Set number one failed.\n");
ret = mbedtls_mpi_read_binary(&scalarB, digest, SHA256_HASH_LEN);
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Read digest failed.\n");
ret = mbedtls_ecp_muladd(&grp, &result, &scalarA, &pointA, &scalarB, &pointB);
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Double-scalar multiplication failed.\n");
ret = mbedtls_ecp_check_pubkey(&grp, &result);
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Invalid point on P256 is returned.\n");
ret = WriteOutEcPublicKey(&result, point);
LOG_AND_GOTO_CLEANUP_IF_FAIL(ret, "Write out public key failed.\n");
CLEAN_UP:
FreePointParams(&scalarA, &scalarB, &pointA, &pointB, &result);
mbedtls_ecp_group_free(&grp);
return ret;
}
// only support P256 HashToPoint for standard system
int32_t MbedtlsHashToPoint(const Uint8Buff *hash, Uint8Buff *outEcPoint)
{
CHECK_PTR_RETURN_HAL_ERROR_CODE(hash, "hash");
CHECK_PTR_RETURN_HAL_ERROR_CODE(hash->val, "hash->val");
CHECK_LEN_EQUAL_RETURN(hash->length, SHA256_LEN, "hash->length");
CHECK_PTR_RETURN_HAL_ERROR_CODE(outEcPoint, "outEcPoint");
CHECK_PTR_RETURN_HAL_ERROR_CODE(outEcPoint->val, "outEcPoint->val");
CHECK_LEN_EQUAL_RETURN(outEcPoint->length, EC_LEN, "outEcPoint->length");
struct Blob hashBlob = {
.dataSize = hash->length,
.data = hash->val
};
struct Blob pointBlob = {
.dataSize = outEcPoint->length,
.data = outEcPoint->val
};
int32_t ret = EcHashToPoint(&hashBlob, &pointBlob);
if (ret != HAL_SUCCESS || pointBlob.dataSize != EC_LEN) {
LOGE("HashToPoint with mbedtls for P256 failed, ret: %d", ret);
return HAL_FAILED;
}
return HAL_SUCCESS;
}
// only support P256 AgreeSharedSecret for standard system
int32_t MbedtlsAgreeSharedSecret(const KeyBuff *priKey, const KeyBuff *pubKey, Uint8Buff *sharedKey)
{
CHECK_PTR_RETURN_HAL_ERROR_CODE(priKey, "priKey");
CHECK_PTR_RETURN_HAL_ERROR_CODE(priKey->key, "priKey->key");
CHECK_LEN_ZERO_RETURN_ERROR_CODE(priKey->keyLen, "priKey->keyLen");
CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey, "devicePk");
CHECK_PTR_RETURN_HAL_ERROR_CODE(pubKey->key, "devicePk->key");
CHECK_LEN_ZERO_RETURN_ERROR_CODE(pubKey->keyLen, "devicePk->keyLen");
CHECK_PTR_RETURN_HAL_ERROR_CODE(sharedKey, "sharedKey");
CHECK_PTR_RETURN_HAL_ERROR_CODE(sharedKey->val, "sharedKey->val");
CHECK_LEN_ZERO_RETURN_ERROR_CODE(sharedKey->length, "sharedKey->length");
struct Blob priKeyBlob = {
.dataSize = priKey->keyLen,
.data = priKey->key
};
struct Blob pubKeyBlob = {
.dataSize = pubKey->keyLen,
.data = pubKey->key
};
struct Blob sharedKeyBlob = {
.dataSize = sharedKey->length,
.data = sharedKey->val
};
int32_t ret = EcKeyAgreement(&priKeyBlob, &pubKeyBlob, &sharedKeyBlob);
if (ret != HAL_SUCCESS) {
LOGE("Agree key failed, ret = %d", ret);
return HAL_FAILED;
}
return HAL_SUCCESS;
}
@@ -21,6 +21,7 @@
#include "hc_types.h"
#define BITS_PER_BYTE 8
#define ECC_PK_LEN 32
#define CAL_ARRAY_SIZE(arr) ((sizeof(arr)) / (sizeof((arr)[0])))
@@ -58,6 +58,17 @@ const char *GetStorageDirPath(void)
return storageFile;
}
const char *GetAccountStoragePath(void)
{
#ifndef LITE_DEVICE
const char *storageFile = "/data/data/deviceauth/account";
#else
const char *storageFile = "/storage/deviceauth/account";
#endif
LOGI("[OS]: Account storage dir: %s", storageFile);
return storageFile;
}
#ifdef __cplusplus
}
#endif
@@ -32,5 +32,8 @@ enum {
HAL_ERR_BUILD_PARAM_SET_FAILED = -17,
HAL_ERR_FRESH_PARAM_SET_FAILED = -18,
HAL_ERR_INIT_FAILED = -19,
HAL_ERR_HUKS = -20,
HAL_ERR_SHORT_BUFFER = -21,
HAL_ERR_NOT_SUPPORTED = -22,
};
#endif
@@ -37,6 +37,7 @@ int32_t HcGetUdid(uint8_t *udid, int32_t udidLen);
const char *GetStoragePath(void);
const char *GetStorageDirPath(void);
const char *GetAccountStoragePath(void);
#ifdef __cplusplus
}
Executable → Regular
+1 -2
View File
@@ -43,7 +43,6 @@ extern "C" {
#define PARAM_TYPE_BIND 12
#define PARAM_TYPE_UNBIND 13
#define PARAM_TYPE_GROUP_TYPE 14
#define PARAM_TYPE_CREDENTIAL 15
#define PARAM_TYPE_MGR_APPID 16
#define PARAM_TYPE_FRIEND_APPID 17
#define PARAM_TYPE_QUERY_PARAMS 18
@@ -62,6 +61,7 @@ extern "C" {
#define PARAM_TYPE_CB_OBJECT 31
#define PARAM_TYPE_OS_ACCOUNT_ID 32
#define PARAM_TYPE_RETURN_DATA 33
#define PARAM_TYPE_REQ_JSON 34
enum {
IPC_CALL_ID_REG_CB = 1,
@@ -73,7 +73,6 @@ enum {
IPC_CALL_ID_ADD_GROUP_MEMBER,
IPC_CALL_ID_DEL_GROUP_MEMBER,
IPC_CALL_ID_GM_PROC_DATA,
IPC_CALL_ID_SAVE_CREDENTIAL,
IPC_CALL_ID_APPLY_REG_INFO,
IPC_CALL_ID_CHECK_ACCESS_TO_GROUP,
IPC_CALL_ID_GET_PK_INFO_LIST,
+9 -17
View File
@@ -565,21 +565,7 @@ static int32_t IpcGmProcessData(int64_t requestId, const uint8_t *data, uint32_t
return ret;
}
static int32_t IpcGmProcCredential(int32_t operationCode, const char *credential, char **returnJsonStr)
{
LOGI("starting ...");
(void)operationCode;
(void)returnJsonStr;
if (!IS_STRING_VALID(credential)) {
LOGE("The input groupType is invalid!");
return HC_ERR_INVALID_PARAMS;
}
LOGE("IpcGmProcCredential is currently not supported!");
return HC_ERR_NOT_SUPPORT;
}
static int32_t IpcGmGetRegisterInfo(char **registerInfo)
static int32_t IpcGmGetRegisterInfo(const char *reqJsonStr, char **registerInfo)
{
uintptr_t callCtx = 0x0;
int32_t ret;
@@ -588,7 +574,8 @@ static int32_t IpcGmGetRegisterInfo(char **registerInfo)
char *outInfo = NULL;
LOGI("starting ...");
if (registerInfo == NULL) {
if ((reqJsonStr == NULL) || (registerInfo == NULL)) {
LOGE("Invalid params.");
return HC_ERR_INVALID_PARAMS;
}
if (!IsServiceRunning()) {
@@ -600,6 +587,12 @@ static int32_t IpcGmGetRegisterInfo(char **registerInfo)
LOGE("CreateCallCtx failed, ret %d", ret);
return HC_ERR_IPC_INIT;
}
ret = SetCallRequestParamInfo(callCtx, PARAM_TYPE_REQ_JSON, (const uint8_t *)reqJsonStr, strlen(reqJsonStr) + 1);
if (ret != HC_SUCCESS) {
LOGE("set request param failed, ret %d, param id %d", ret, PARAM_TYPE_REQ_JSON);
DestroyCallCtx(&callCtx, NULL);
return HC_ERR_IPC_BUILD_PARAM;
}
ret = DoBinderCall(callCtx, IPC_CALL_ID_APPLY_REG_INFO, true);
if (ret == HC_ERR_IPC_INTERNAL_FAILED) {
LOGE("ipc call failed");
@@ -1372,7 +1365,6 @@ static void InitIpcGmMethods(DeviceGroupManager *gmMethodObj)
gmMethodObj->addMemberToGroup = IpcGmAddMemberToGroup;
gmMethodObj->deleteMemberFromGroup = IpcGmDelMemberFromGroup;
gmMethodObj->processData = IpcGmProcessData;
gmMethodObj->processCredential = IpcGmProcCredential;
gmMethodObj->getRegisterInfo = IpcGmGetRegisterInfo;
gmMethodObj->checkAccessToGroup = IpcGmCheckAccessToGroup;
gmMethodObj->getPkInfoList = IpcGmGetPkInfoList;
+7 -38
View File
@@ -404,50 +404,20 @@ static int32_t IpcServiceGmProcessData(const IpcDataInfo *ipcParams, int32_t par
return ret;
}
static int32_t IpcServiceGmSaveCredential(const IpcDataInfo *ipcParams, int32_t paramNum, uintptr_t outCache)
{
int32_t callRet;
int32_t ret;
int32_t opCode = 0;
int32_t inOutLen;
const char *credential = NULL;
char *returnJsonStr = NULL;
LOGI("starting ...");
inOutLen = sizeof(int32_t);
ret = GetIpcRequestParamByType(ipcParams, paramNum, PARAM_TYPE_OPCODE, (uint8_t *)&opCode, &inOutLen);
if ((inOutLen != sizeof(int32_t)) || (ret != HC_SUCCESS)) {
LOGE("get param error, type %d", PARAM_TYPE_OPCODE);
return HC_ERR_IPC_BAD_PARAM;
}
ret = GetIpcRequestParamByType(ipcParams, paramNum, PARAM_TYPE_CREDENTIAL, (uint8_t *)&credential, NULL);
if ((credential == NULL) || (ret != HC_SUCCESS)) {
LOGE("get param error, type %d", PARAM_TYPE_CREDENTIAL);
return HC_ERR_IPC_BAD_PARAM;
}
callRet = g_devGroupMgrMethod.processCredential(opCode, credential, &returnJsonStr);
ret = IpcEncodeCallReplay(outCache, PARAM_TYPE_IPC_RESULT, (const uint8_t *)&callRet, sizeof(int32_t));
LOGI("process done, call ret %d, ipc ret %d", callRet, ret);
if ((ret == HC_SUCCESS) && (returnJsonStr != NULL)) {
ret += IpcEncodeCallReplay(outCache, PARAM_TYPE_REG_INFO,
(const uint8_t *)returnJsonStr, strlen(returnJsonStr) + 1);
g_devGroupMgrMethod.destroyInfo(&returnJsonStr);
} else {
ret += IpcEncodeCallReplay(outCache, PARAM_TYPE_REG_INFO, NULL, 0);
}
return (ret == HC_SUCCESS) ? ret : HC_ERROR;
}
static int32_t IpcServiceGmApplyRegisterInfo(const IpcDataInfo *ipcParams, int32_t paramNum, uintptr_t outCache)
{
int32_t callRet;
int32_t ret;
const char *reqJsonStr = NULL;
char *registerInfo = NULL;
(void)ipcParams;
(void)paramNum;
LOGI("starting ...");
callRet = g_devGroupMgrMethod.getRegisterInfo(&registerInfo);
ret = GetIpcRequestParamByType(ipcParams, paramNum, PARAM_TYPE_REQ_JSON, (uint8_t *)&reqJsonStr, NULL);
if ((reqJsonStr == NULL) || (ret != HC_SUCCESS)) {
LOGE("get param error, type %d", PARAM_TYPE_REQ_JSON);
return HC_ERR_IPC_BAD_PARAM;
}
callRet = g_devGroupMgrMethod.getRegisterInfo(reqJsonStr, &registerInfo);
ret = IpcEncodeCallReplay(outCache, PARAM_TYPE_IPC_RESULT, (const uint8_t *)&callRet, sizeof(int32_t));
ret += IpcEncodeCallReplay(outCache, PARAM_TYPE_IPC_RESULT_NUM,
(const uint8_t *)&g_ipcResultNum1, sizeof(int32_t));
@@ -977,7 +947,6 @@ static int32_t AddMethodMap(uintptr_t ipcInstance)
ret &= SetIpcCallMap(ipcInstance, IpcServiceGmAddMemberToGroup, IPC_CALL_ID_ADD_GROUP_MEMBER);
ret &= SetIpcCallMap(ipcInstance, IpcServiceGmDelMemberFromGroup, IPC_CALL_ID_DEL_GROUP_MEMBER);
ret &= SetIpcCallMap(ipcInstance, IpcServiceGmProcessData, IPC_CALL_ID_GM_PROC_DATA);
ret &= SetIpcCallMap(ipcInstance, IpcServiceGmSaveCredential, IPC_CALL_ID_SAVE_CREDENTIAL);
ret &= SetIpcCallMap(ipcInstance, IpcServiceGmApplyRegisterInfo, IPC_CALL_ID_APPLY_REG_INFO);
ret &= SetIpcCallMap(ipcInstance, IpcServiceGmCheckAccessToGroup, IPC_CALL_ID_CHECK_ACCESS_TO_GROUP);
ret &= SetIpcCallMap(ipcInstance, IpcServiceGmGetPkInfoList, IPC_CALL_ID_GET_PK_INFO_LIST);
+3 -3
View File
@@ -1518,9 +1518,9 @@ static bool IsTypeForSettingPtr(int32_t type)
int32_t typeList[] = {
PARAM_TYPE_APPID, PARAM_TYPE_DEV_AUTH_CB, PARAM_TYPE_LISTERNER, PARAM_TYPE_CREATE_PARAMS,
PARAM_TYPE_GROUPID, PARAM_TYPE_UDID, PARAM_TYPE_ADD_PARAMS, PARAM_TYPE_DEL_PARAMS,
PARAM_TYPE_BIND, PARAM_TYPE_UNBIND, PARAM_TYPE_CREDENTIAL, PARAM_TYPE_MGR_APPID,
PARAM_TYPE_FRIEND_APPID, PARAM_TYPE_QUERY_PARAMS, PARAM_TYPE_COMM_DATA, PARAM_TYPE_REQ_CFM,
PARAM_TYPE_SESS_KEY, PARAM_TYPE_REQ_INFO, PARAM_TYPE_GROUP_INFO, PARAM_TYPE_AUTH_PARAMS
PARAM_TYPE_BIND, PARAM_TYPE_UNBIND, PARAM_TYPE_MGR_APPID, PARAM_TYPE_FRIEND_APPID,
PARAM_TYPE_QUERY_PARAMS, PARAM_TYPE_COMM_DATA, PARAM_TYPE_REQ_CFM, PARAM_TYPE_SESS_KEY,
PARAM_TYPE_REQ_INFO, PARAM_TYPE_GROUP_INFO, PARAM_TYPE_AUTH_PARAMS, PARAM_TYPE_REQ_JSON
};
int32_t i;
int32_t n = sizeof(typeList) / sizeof(typeList[0]);
+3 -3
View File
@@ -1427,9 +1427,9 @@ static bool IsTypeForSettingPtr(int32_t type)
int32_t typeList[] = {
PARAM_TYPE_APPID, PARAM_TYPE_DEV_AUTH_CB, PARAM_TYPE_LISTERNER, PARAM_TYPE_CREATE_PARAMS,
PARAM_TYPE_GROUPID, PARAM_TYPE_UDID, PARAM_TYPE_ADD_PARAMS, PARAM_TYPE_DEL_PARAMS,
PARAM_TYPE_BIND, PARAM_TYPE_UNBIND, PARAM_TYPE_CREDENTIAL, PARAM_TYPE_MGR_APPID,
PARAM_TYPE_FRIEND_APPID, PARAM_TYPE_QUERY_PARAMS, PARAM_TYPE_COMM_DATA, PARAM_TYPE_REQ_CFM,
PARAM_TYPE_SESS_KEY, PARAM_TYPE_REQ_INFO, PARAM_TYPE_GROUP_INFO, PARAM_TYPE_AUTH_PARAMS
PARAM_TYPE_BIND, PARAM_TYPE_UNBIND, PARAM_TYPE_MGR_APPID, PARAM_TYPE_FRIEND_APPID,
PARAM_TYPE_QUERY_PARAMS, PARAM_TYPE_COMM_DATA, PARAM_TYPE_REQ_CFM, PARAM_TYPE_SESS_KEY,
PARAM_TYPE_REQ_INFO, PARAM_TYPE_GROUP_INFO, PARAM_TYPE_AUTH_PARAMS, PARAM_TYPE_REQ_JSON
};
int32_t i;
int32_t n = sizeof(typeList) / sizeof(typeList[0]);
+2 -4
View File
@@ -38,7 +38,6 @@
#define FIELD_DELETE_ID "deleteId"
#define FIELD_APP_ID "appId"
#define FIELD_SERVICE_TYPE "serviceType"
#define FIELD_PEER_AUTH_STATE "peerAuthState"
#define FIELD_IS_DEVICE_LEVEL "isDeviceLevel"
#define FIELD_ALTERNATIVE "alternative"
#define FIELD_PEER_UDID "peerUdid"
@@ -58,7 +57,6 @@
#define FIELD_SHARED_USER_ID "sharedUserId"
#define FIELD_OWNER_USER_ID "ownerUserId"
#define FIELD_DEVICE_ID "deviceId"
#define FIELD_UID_HASH "uidHash"
#define FIELD_PIN_CODE "pinCode"
#define FIELD_AUTH_ID "authId"
#define FIELD_UDID "udid"
@@ -76,6 +74,7 @@ typedef enum {
} OsAccountEnum;
typedef enum {
GROUP_TYPE_INVALID = -1,
ALL_GROUP = 0,
IDENTICAL_ACCOUNT_GROUP = 1,
PEER_TO_PEER_GROUP = 256,
@@ -173,8 +172,7 @@ typedef struct {
int32_t (*deleteMemberFromGroup)(int32_t osAccountId, int64_t requestId, const char *appId,
const char *deleteParams);
int32_t (*processData)(int64_t requestId, const uint8_t *data, uint32_t dataLen);
int32_t (*processCredential)(int operationCode, const char *reqJsonStr, char **returnJsonStr);
int32_t (*getRegisterInfo)(char **returnRegisterInfo);
int32_t (*getRegisterInfo)(const char *reqJsonStr, char **returnRegisterInfo);
int32_t (*checkAccessToGroup)(int32_t osAccountId, const char *appId, const char *groupId);
int32_t (*getPkInfoList)(int32_t osAccountId, const char *appId, const char *queryParams, char **returnInfoList,
uint32_t *returnInfoNum);
@@ -49,6 +49,7 @@ enum {
HC_ERR_VERIFY_FAILED = 0x00001004,
HC_ERR_HASH_FAIL = 0x00001005,
HC_ERR_ALG_FAIL = 0x00001006,
HC_ERR_HKS_PARAM_SET_FAILED = 0x00001007,
/* error code for json util , 0x00002000 ~ 0x00002FFF */
HC_ERR_JSON_FAIL = 0x00002001,
@@ -89,6 +90,13 @@ enum {
HC_ERR_INVALID_ALG = 0x0000400A,
HC_ERR_IGNORE_MSG = 0x0000400B,
HC_ERR_LOCAL_IDENTITY_NOT_EXIST = 0x0000400C,
HC_ERR_UNSUPPORTED_OPCODE = 0x0000400D,
HC_ERR_AUTH_TOKEN = 0x0000400F,
HC_ERR_PSK = 0x00004010,
HC_ERR_TOKEN = 0x00004011,
HC_ERR_GENERATE_RANDOM = 0x00004012,
HC_ERR_STATUS = 0x00004013,
HC_ERR_STEP = 0x00004014,
/* error code for group , 0x00005000 ~ 0x00005FFF */
HC_ERR_ACCESS_DENIED = 0x00005001,
@@ -106,6 +114,7 @@ enum {
HC_ERR_SESSION_IS_FULL = 0x0000500D,
HC_ERR_INVALID_UDID = 0x0000500E,
HC_ERR_INVALID_TCIS_ID = 0x0000500F,
HC_ERR_DEL_GROUP = 0x00005010,
/* error code for database , 0x00006000 ~ 0x00006FFF */
HC_ERR_DB = 0x00006001,
@@ -126,6 +135,17 @@ enum {
HC_ERR_CHANNEL_NOT_EXIST = 0x00008001,
HC_ERR_SOFT_BUS = 0x00008002,
/* error code used on account-related authenticator */
HC_ERR_GET_PK_INFO = 0x00009001,
HC_ERR_ACCOUNT_TASK_IS_FULL = 0x00009002,
HC_ERR_ACCOUNT_ECDH_FAIL = 0x00009003,
HC_ERR_ACCOUNT_VERIFY_PK_SIGN = 0x00009004,
HC_ERR_AUTH_STATUS = 0x00009005,
HC_ERR_AUTH_INTERNAL = 0x00009006,
HC_ERR_ADD_ACCOUNT_TASK = 0x00009007,
HC_ERR_CLIENT_CONFIRM_PROTOCOL = 0x00009008,
HC_ERR_SERVER_CONFIRM_PROTOCOL = 0x00009009,
/* error code used on DAS service */
INVALID_PARAMETERS = 0xF0000001,
EXCEED_AUTHORITY = 0xF0000002,
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2022 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
@@ -17,12 +17,11 @@
#define ACCOUNT_MODULE_H
#include "dev_auth_module_manager.h"
#include "hc_types.h"
#include "json_utils.h"
int32_t CheckAccountMsgRepeatability(const CJson *in);
bool IsAccountSupported(void);
AuthModuleBase *CreateAccountModule(void);
int32_t ProcessAccountCredentials(int credentialOpCode, const CJson *in, CJson *out);
int32_t ProcessAccountCredentials(int32_t osAccountId, int32_t credentialOpCode, const CJson *in, CJson *out);
#endif
@@ -0,0 +1,56 @@
/*
* Copyright (C) 2022 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.
*/
#ifndef ACCOUNT_MODULE_DEFINES_H
#define ACCOUNT_MODULE_DEFINES_H
#define SEED_SIZE 32
#define USER_ID_SIZE 65
#define PK_SIZE 128
#define PK_VERSION_SIZE 256
#define DEVICE_ID_SIZE 256
#define SIGNATURE_SIZE 128
#define PUBLIC_KEY_INFO_SIZE 1024
#define SERVER_PK_SIZE 128
typedef enum {
TASK_TYPE_DEFAULT = 0,
TASK_TYPE_PAKE_V2_AUTH_CLIENT = 5,
TASK_TYPE_PAKE_V2_AUTH_SERVER = 6,
TASK_TYPE_ISO_AUTH_CLIENT = 7,
TASK_TYPE_ISO_AUTH_SERVER = 8,
} AccountTaskType;
typedef enum {
CMD_PAKE_AUTH_MAIN_ONE = 0x0030,
RET_PAKE_AUTH_FOLLOWER_ONE = 0x0031,
CMD_PAKE_AUTH_MAIN_TWO = 0x0032,
RET_PAKE_AUTH_FOLLOWER_TWO = 0x0033,
ERR_MSG = 0x8080,
} MessageStepCode;
typedef enum {
ALG_ECC = 0x0000,
ALG_RSA = 0x0001,
ALG_HKDF = 0x0002,
ALG_HMAC = 0x0003,
ALG_AES = 0x0004,
ALG_PBKDF2 = 0x0005,
ALG_ECDH = 0x0006,
ALG_X25519 = 0x0007,
ALG_ED25519 = 0x0008,
} KeyAlgEncode;
#endif
@@ -0,0 +1,46 @@
/*
* Copyright (C) 2022 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.
*/
#ifndef ACCOUNT_MULTI_TASK_MANAGER_H
#define ACCOUNT_MULTI_TASK_MANAGER_H
#include "account_task_main.h"
#define ACCOUNT_MULTI_TASK_MAX_SIZE 64
typedef struct {
int32_t count;
AccountTask *taskArray[ACCOUNT_MULTI_TASK_MAX_SIZE];
bool (*isTaskNumUpToMax)(void);
int32_t (*addTaskToManager)(AccountTask *taskBase);
AccountTask *(*getTaskFromManager)(int32_t taskId);
void (*deleteTaskFromManager)(int32_t taskId);
} AccountMultiTaskManager;
#ifdef __cplusplus
extern "C" {
#endif
AccountMultiTaskManager *GetAccountMultiTaskManager(void);
void InitAccountMultiTaskManager(void);
void DestroyAccountMultiTaskManager(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2022 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.
*/
#ifndef ACCOUNT_TASK_MAIN_H
#define ACCOUNT_TASK_MAIN_H
#include "json_utils.h"
#include "account_module_defines.h"
typedef struct TaskBaseT {
AccountTaskType (*getTaskType)(void);
void (*destroyTask)(struct TaskBaseT *);
int32_t (*process)(struct TaskBaseT *, const CJson *in, CJson *out, int32_t *status);
int32_t taskStatus;
} TaskBase;
typedef struct AccountTaskT {
int32_t taskId;
void (*destroyTask)(struct AccountTaskT *);
int32_t (*processTask)(struct AccountTaskT *, const CJson *in, CJson *out, int32_t *status);
int32_t versionStatus;
TaskBase *subTask;
} AccountTask;
AccountTask *CreateAccountTaskT(int32_t *taskId, const CJson *in, CJson *out);
#endif
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2022 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.
*/
#ifndef ACCOUNT_VERSION_UTIL_H
#define ACCOUNT_VERSION_UTIL_H
#include "alg_defs.h"
#include "json_utils.h"
#include "pake_defs.h"
#include "protocol_common.h"
#include "account_task_main.h"
typedef enum {
BIND_VERSION_NO_NONE = 0,
BIND_PAKE_V2_DL = 0x0001,
BIND_PAKE_V2_EC_P256 = 0x0002,
BIND_PAKE_V2_EC_P256_WITH_PROOF = 0x0004,
BIND_PAKE_V2_EC_X25519 = 0x0008,
BIND_PAKE_V1_DL = 0x0010,
} BindVersionNo;
typedef enum {
AUTH_VERSION_NO_NONE = 0,
AUTH_PAKE_V2_EC_P256 = 0x0001,
AUTH_ISO = 0x0002,
} AuthVersionNo;
typedef enum {
VERSION_INITIAL = 0,
VERSION_NEGOTIATION = 1,
VERSION_CONFIRMED = 2,
} AccountVersionStatus;
typedef struct _AccountVersionInfo {
uint64_t versionNo;
ProtocolType protocolType;
PakeAlgType pakeAlgType;
CurveType curveType;
bool withExtraOperation;
bool (*isTaskSupported)(void);
TaskBase *(*createTask)(const CJson *, CJson *, const struct _AccountVersionInfo *);
} AccountVersionInfo;
void InitVersionInfos(void);
void DestroyVersionInfos(void);
uint64_t GetSupportedVersionNo(int32_t operationCode);
const AccountVersionInfo *GetNegotiatedVersionInfo(int32_t operationCode, uint64_t versionNo);
#endif
@@ -1,31 +1,39 @@
/*
* Copyright (C) 2021 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.
*/
#ifndef LCM_ADAPTER_H
#define LCM_ADAPTER_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int32_t ProcessCredential(int operationCode, const char *reqJsonStr, char **returnJsonStr);
int32_t GetRegisterInfo(char **returnRegisterInfo);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (C) 2022 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.
*/
#ifndef PAKE_V2_AUTH_CLIENT_TASK_H
#define PAKE_V2_AUTH_CLIENT_TASK_H
#include "json_utils.h"
#include "pake_v2_auth_task_common.h"
#include "account_task_main.h"
#include "account_version_util.h"
typedef struct {
TaskBase taskBase;
PakeAuthParams params;
} PakeV2AuthClientTask;
#ifdef __cplusplus
extern "C" {
#endif
TaskBase *CreatePakeV2AuthClientTask(const CJson *in, CJson *out, const AccountVersionInfo *verInfo);
#ifdef __cplusplus
}
#endif
#endif
@@ -1,32 +1,39 @@
/*
* Copyright (C) 2021 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 "lcm_adapter.h"
#include "device_auth_defines.h"
int32_t ProcessCredential(int operationCode, const char *reqJsonStr, char **returnJsonStr)
{
(void)operationCode;
(void)reqJsonStr;
(void)returnJsonStr;
return HC_ERR_NOT_SUPPORT;
}
int32_t GetRegisterInfo(char **returnRegisterInfo)
{
(void)returnRegisterInfo;
return HC_ERR_NOT_SUPPORT;
}
/*
* Copyright (C) 2022 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.
*/
#ifndef PAKE_V2_AUTH_SERVER_TASK_H
#define PAKE_V2_AUTH_SERVER_TASK_H
#include "json_utils.h"
#include "pake_v2_auth_task_common.h"
#include "account_task_main.h"
#include "account_version_util.h"
typedef struct {
TaskBase taskBase;
PakeAuthParams params;
} PakeV2AuthServerTask;
#ifdef __cplusplus
extern "C" {
#endif
TaskBase *CreatePakeV2AuthServerTask(const CJson *in, CJson *out, const AccountVersionInfo *verInfo);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,80 @@
/*
* Copyright (C) 2022 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.
*/
#ifndef PAKE_V2_AUTH_TASK_COMMON_H
#define PAKE_V2_AUTH_TASK_COMMON_H
#include "json_utils.h"
#include "pake_defs.h"
#include "string_util.h"
#include "account_module_defines.h"
#include "account_task_main.h"
#include "account_version_util.h"
typedef struct {
PakeBaseParams pakeParams;
uint64_t versionNo;
int32_t authForm;
int32_t osAccountId;
int32_t authKeyAlgEncode;
Uint8Buff deviceIdSelf;
Uint8Buff deviceIdPeer;
Uint8Buff devIdSelf;
Uint8Buff devIdPeer;
uint8_t pkCloud[SERVER_PK_SIZE];
uint8_t userIdSelf[USER_ID_SIZE];
uint8_t userIdPeer[USER_ID_SIZE];
uint8_t pkSelf[PK_SIZE];
Uint8Buff pkInfoSelf;
Uint8Buff pkInfoSignSelf;
uint8_t pkPeer[PK_SIZE];
Uint8Buff pkInfoPeer;
Uint8Buff pkInfoSignPeer;
} PakeAuthParams;
#ifdef __cplusplus
extern "C" {
#endif
bool IsPakeV2AuthTaskSupported(void);
TaskBase *CreatePakeV2AuthTask(const CJson *in, CJson *out, const AccountVersionInfo *verInfo);
int32_t VerifyPkSignPeer(const PakeAuthParams *params);
int32_t GenerateEcdhSharedKey(PakeAuthParams *params);
int32_t GetPkInfoPeer(PakeAuthParams *params, const CJson *in);
int32_t InitPakeAuthParams(const CJson *in, PakeAuthParams *params, const AccountVersionInfo *verInfo);
void DestroyPakeAuthParams(PakeAuthParams *params);
int32_t ExtractPakePeerId(PakeAuthParams *params, const CJson *in);
int32_t ExtractPakeSelfId(PakeAuthParams *params);
int32_t ExtractSelfDeviceId(PakeAuthParams *params, const CJson *in, bool useSelfPrefix);
int32_t ExtractPeerDeviceId(PakeAuthParams *params, const CJson *in);
int32_t ExtractSelfDevId(PakeAuthParams *params, const CJson *in);
int32_t ExtractPeerDevId(PakeAuthParams *params, const CJson *in);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,83 @@
/*
* Copyright (C) 2022 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.
*/
#ifndef ASY_TOKEN_MANAGER_H
#define ASY_TOKEN_MANAGER_H
#include <stdint.h>
#include "alg_defs.h"
#include "common_defs.h"
#include "string_util.h"
#define SELF_ECC_KEY_LEN 32
#define COPY_STRING_GOTO_ERR_IF_FAIL(src, dest, tag) \
do { \
if ((src) == NULL) { \
LOGE("%s is NULL", tag); \
goto ERR; \
} \
if (memcpy_s((dest), sizeof(dest), src, HcStrlen(src) + 1) != EOK) { \
LOGE("%s copy failed", tag); \
goto ERR; \
} \
} while (0)
typedef struct {
Uint8Buff version;
Uint8Buff userId;
Uint8Buff deviceId;
Uint8Buff devicePk;
} PkInfo;
typedef struct {
Uint8Buff pkInfoStr;
PkInfo pkInfo;
Uint8Buff pkInfoSignature;
Uint8Buff serverPk;
} AccountToken;
DECLARE_HC_VECTOR(AccountTokenVec, AccountToken*)
typedef struct {
int32_t (*addToken)(int32_t osAccountId, const CJson *in, CJson *out);
int32_t (*getToken)(int32_t osAccountId, AccountToken *token, const char *userId);
int32_t (*deleteToken)(int32_t osAccountId, const char *userId);
int32_t (*getRegisterProof)(const CJson *in, CJson *out);
int32_t (*getServerPublicKey)(int32_t osAccountId, const char *userId, Uint8Buff *serverPk);
int32_t (*generateKeyAlias)(const char *userId, const char *deviceId,
Uint8Buff *keyAlias, bool isServerPkAlias);
Algorithm (*getAlgVersion)(int32_t osAccountId, const char *userId);
} AccountAuthTokenManager;
#ifdef __cplusplus
extern "C" {
#endif
AccountAuthTokenManager *GetAccountAuthTokenManager(void);
void InitTokenManager(void);
void DestroyTokenManager(void);
AccountToken *CreateAccountToken(void);
void DestroyAccountToken(AccountToken *token);
AccountTokenVec CreateAccountTokenVec(void);
void ClearAccountTokenVec(AccountTokenVec *vec);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,184 @@
/*
* Copyright (C) 2022 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 "account_module.h"
#include "alg_loader.h"
#include "asy_token_manager.h"
#include "clib_error.h"
#include "clib_types.h"
#include "common_defs.h"
#include "device_auth_defines.h"
#include "hc_log.h"
#include "json_utils.h"
#include "pake_v2_auth_client_task.h"
#include "pake_v2_auth_server_task.h"
#include "account_module_defines.h"
#include "account_multi_task_manager.h"
#include "account_version_util.h"
#define ACCOUNT_CLIENT_FIRST_MESSAGE 0x0000
#define ACCOUNT_CLIENT_STEP_MASK 0x000F
typedef struct {
AuthModuleBase moduleBase;
} AccountModule;
static AccountModule g_module;
int32_t CheckAccountMsgRepeatability(const CJson *in)
{
int32_t opCode;
if (GetIntFromJson(in, FIELD_OPERATION_CODE, &opCode) != CLIB_SUCCESS) {
LOGE("Get opCode failed.");
return HC_ERR_JSON_GET;
}
const char *key = NULL;
if (opCode == OP_BIND) {
key = FIELD_MESSAGE;
} else if (opCode == AUTHENTICATE) {
key = FIELD_STEP;
} else {
LOGE("Invalid opCode: %d.", opCode);
return HC_ERR_INVALID_PARAMS;
}
uint32_t message;
if (GetIntFromJson(in, key, (int32_t *)&message) != CLIB_SUCCESS) {
LOGD("There is no message code."); // The first message of the client has no message code
return HC_SUCCESS;
}
if ((message & ACCOUNT_CLIENT_STEP_MASK) == ACCOUNT_CLIENT_FIRST_MESSAGE) {
return HC_SUCCESS;
}
LOGI("The message is repeated, ignore it, code: %u", message);
return HC_ERR_IGNORE_MSG;
}
static int32_t CreateAccountTask(int32_t *taskId, const CJson *in, CJson *out)
{
if (taskId == NULL || in == NULL || out == NULL) {
LOGE("Params is null in account task.");
return HC_ERR_NULL_PTR;
}
int32_t res = CheckAccountMsgRepeatability(in);
if (res != HC_SUCCESS) {
LOGE("The result of CheckAccountMsgRepeatability is %x.", res);
return res;
}
AccountMultiTaskManager *authManager = GetAccountMultiTaskManager();
if (authManager == NULL) {
LOGE("Get multi auth manager instance failed.");
return HC_ERROR;
}
if (authManager->isTaskNumUpToMax() == true) {
LOGE("Account auth task is full.");
return HC_ERR_ACCOUNT_TASK_IS_FULL;
}
AccountTask *newTask = CreateAccountTaskT(taskId, in, out);
if (newTask == NULL) {
LOGE("Create account related task failed.");
return HC_ERR_ALLOC_MEMORY;
}
res = authManager->addTaskToManager(newTask);
if (res != HC_SUCCESS) {
LOGE("Add new task into task manager failed, res: %d.", res);
newTask->destroyTask(newTask);
}
return res;
}
static int32_t ProcessAccountTask(int32_t taskId, const CJson *in, CJson *out, int32_t *status)
{
AccountMultiTaskManager *authManager = GetAccountMultiTaskManager();
if (authManager == NULL) {
LOGE("Get multi auth manager instance failed.");
return HC_ERROR;
}
AccountTask *currentTask = authManager->getTaskFromManager(taskId);
if (currentTask == NULL) {
LOGE("Get task from manager failed, taskId: %d.", taskId);
return HC_ERR_TASK_ID_IS_NOT_MATCH;
}
LOGD("Begin process account related task, taskId: %d.", taskId);
return currentTask->processTask(currentTask, in, out, status);
}
static void DestroyAccountTask(int32_t taskId)
{
AccountMultiTaskManager *authManager = GetAccountMultiTaskManager();
if (authManager == NULL) {
LOGE("Get multi auth manager instance failed.");
return;
}
LOGI("Delete taskId:%d from task manager.", taskId);
authManager->deleteTaskFromManager(taskId);
}
static void DestroyAccountModule(AuthModuleBase *module)
{
DestroyAccountMultiTaskManager();
DestroyTokenManager();
DestroyVersionInfos();
(void)memset_s(module, sizeof(AccountModule), 0, sizeof(AccountModule));
}
AuthModuleBase *CreateAccountModule(void)
{
g_module.moduleBase.moduleType = ACCOUNT_MODULE;
g_module.moduleBase.createTask = CreateAccountTask;
g_module.moduleBase.processTask = ProcessAccountTask;
g_module.moduleBase.destroyTask = DestroyAccountTask;
g_module.moduleBase.destroyModule = DestroyAccountModule;
InitVersionInfos();
InitAccountMultiTaskManager();
InitTokenManager();
return (AuthModuleBase *)&g_module;
}
bool IsAccountSupported(void)
{
return true;
}
int32_t ProcessAccountCredentials(int32_t osAccountId, int32_t credentialOpCode, const CJson *in, CJson *out)
{
if (in == NULL) {
LOGE("The input param: in is null.");
return HC_ERR_NULL_PTR;
}
switch (credentialOpCode) {
case IMPORT_SELF_CREDENTIAL:
return GetAccountAuthTokenManager()->addToken(osAccountId, in, out);
case DELETE_SELF_CREDENTIAL: {
const char *userId = GetStringFromJson(in, FIELD_USER_ID);
if (userId == NULL) {
LOGE("Failed to get user id.");
return HC_ERR_JSON_GET;
}
return GetAccountAuthTokenManager()->deleteToken(osAccountId, userId);
}
case REQUEST_SIGNATURE:
if (out == NULL) {
LOGE("Params: out is null.");
return HC_ERR_NULL_PTR;
}
return GetAccountAuthTokenManager()->getRegisterProof(in, out);
default:
LOGE("Operation is not supported for: %d.", credentialOpCode);
break;
}
return HC_ERR_NOT_SUPPORT;
}
@@ -0,0 +1,128 @@
/*
* Copyright (C) 2022 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 "account_multi_task_manager.h"
#include "device_auth.h"
#include "device_auth_defines.h"
#include "hc_log.h"
#include "hc_types.h"
static AccountMultiTaskManager g_taskManager;
static bool IsManagerHasTaskId(int32_t taskId)
{
for (uint32_t i = 0; i < ACCOUNT_MULTI_TASK_MAX_SIZE; ++i) {
if (g_taskManager.taskArray[i] != NULL && taskId == g_taskManager.taskArray[i]->taskId) {
LOGD("Task already exists, taskId: %d.", taskId);
return true;
}
}
LOGD("Multi auth manager do not has task id(%d).", taskId);
return false;
}
static bool IsTaskNumUpToMax(void)
{
if (g_taskManager.count >= ACCOUNT_MULTI_TASK_MAX_SIZE) {
LOGD("The number of tasks reaches maximun.");
return true;
}
return false;
}
static bool CanAddTaskInManager(int32_t taskId)
{
if (IsTaskNumUpToMax()) {
LOGE("Task number is up to limit.");
return false;
}
if (IsManagerHasTaskId(taskId)) {
LOGE("Task id is already in exist.");
return false;
}
return true;
}
static int32_t AddTaskToManager(AccountTask *task)
{
if (task == NULL) {
LOGE("Task is null.");
return HC_ERR_NULL_PTR;
}
if (!CanAddTaskInManager(task->taskId)) {
LOGE("Can not add task into manager.");
return HC_ERR_ADD_ACCOUNT_TASK;
}
for (uint32_t i = 0; i < ACCOUNT_MULTI_TASK_MAX_SIZE; ++i) {
if (g_taskManager.taskArray[i] == NULL) {
g_taskManager.taskArray[i] = task;
g_taskManager.count++;
return HC_SUCCESS;
}
}
LOGE("There is no empty space in the task manager.");
return HC_ERR_OUT_OF_LIMIT;
}
static AccountTask *GetTaskFromManager(int32_t taskId)
{
for (uint32_t i = 0; i < ACCOUNT_MULTI_TASK_MAX_SIZE; ++i) {
if ((g_taskManager.taskArray[i] != NULL) && (g_taskManager.taskArray[i]->taskId == taskId)) {
return g_taskManager.taskArray[i];
}
}
LOGE("Task does not exist, taskId: %d.", taskId);
return NULL;
}
static void DeleteTaskFromManager(int32_t taskId)
{
for (uint32_t i = 0; i < ACCOUNT_MULTI_TASK_MAX_SIZE; ++i) {
if ((g_taskManager.taskArray[i] != NULL) && (g_taskManager.taskArray[i]->taskId == taskId)) {
g_taskManager.taskArray[i]->destroyTask(g_taskManager.taskArray[i]);
g_taskManager.taskArray[i] = NULL;
g_taskManager.count--;
}
}
}
void InitAccountMultiTaskManager(void)
{
DestroyAccountMultiTaskManager();
g_taskManager.count = 0;
g_taskManager.isTaskNumUpToMax = IsTaskNumUpToMax;
g_taskManager.addTaskToManager = AddTaskToManager;
g_taskManager.getTaskFromManager = GetTaskFromManager;
g_taskManager.deleteTaskFromManager = DeleteTaskFromManager;
}
AccountMultiTaskManager *GetAccountMultiTaskManager(void)
{
return &g_taskManager;
}
void DestroyAccountMultiTaskManager(void)
{
for (uint32_t i = 0; i < ACCOUNT_MULTI_TASK_MAX_SIZE; ++i) {
if (g_taskManager.taskArray[i] != NULL) {
if (g_taskManager.taskArray[i]->destroyTask != NULL) {
g_taskManager.taskArray[i]->destroyTask(g_taskManager.taskArray[i]);
}
g_taskManager.taskArray[i] = NULL;
}
}
(void)memset_s(&g_taskManager, sizeof(AccountMultiTaskManager), 0, sizeof(AccountMultiTaskManager));
}
@@ -0,0 +1,227 @@
/*
* Copyright (C) 2022 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 "account_task_main.h"
#include "alg_defs.h"
#include "alg_loader.h"
#include "common_defs.h"
#include "device_auth.h"
#include "device_auth_defines.h"
#include "clib_error.h"
#include "hc_log.h"
#include "json_utils.h"
#include "account_version_util.h"
static void AccountSendErrMsgToSelf(CJson *out, int32_t errCode)
{
CJson *sendToSelf = CreateJson();
if (sendToSelf == NULL) {
LOGE("Create sendToSelf json failed.");
return;
}
if (AddIntToJson(sendToSelf, FIELD_ERROR_CODE, errCode) != CLIB_SUCCESS) {
LOGE("Add errCode to self json failed.");
FreeJson(sendToSelf);
return;
}
if (AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf) != CLIB_SUCCESS) {
LOGE("Add sendToSelf obj to out json failed.");
FreeJson(sendToSelf);
return;
}
FreeJson(sendToSelf);
}
static void AccountSendErrMsgToOut(CJson *out, int32_t opCode, int32_t errCode)
{
CJson *sendToSelf = CreateJson();
if (sendToSelf == NULL) {
LOGE("Create sendToSelf json failed.");
return;
}
CJson *sendToPeer = CreateJson();
if (sendToPeer == NULL) {
LOGE("Create sendToPeer json failed.");
FreeJson(sendToSelf);
return;
}
if (opCode == OP_BIND) {
if (AddIntToJson(sendToPeer, FIELD_MESSAGE, ERR_MSG) != CLIB_SUCCESS) {
LOGE("Failed to add error message to json for bind.");
goto CLEAN_UP;
}
} else {
if (AddIntToJson(sendToPeer, FIELD_STEP, ERR_MSG) != CLIB_SUCCESS) {
LOGE("Failed to add error message to json for auth.");
goto CLEAN_UP;
}
}
if (AddIntToJson(sendToPeer, FIELD_ERROR_CODE, errCode) != CLIB_SUCCESS) {
LOGE("Add errCode to json failed.");
goto CLEAN_UP;
}
if (AddIntToJson(sendToSelf, FIELD_AUTH_FORM, ACCOUNT_MODULE) != CLIB_SUCCESS) {
LOGE("Add auth form to json failed.");
goto CLEAN_UP;
}
if (AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer) != CLIB_SUCCESS) {
LOGE("Add sendToPeer to json failed.");
goto CLEAN_UP;
}
if (AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf) != CLIB_SUCCESS) {
LOGE("Add sendToSelf to json failed.");
goto CLEAN_UP;
}
CLEAN_UP:
FreeJson(sendToPeer);
FreeJson(sendToSelf);
return;
}
static void DestroyTaskT(AccountTask *task)
{
if (task == NULL) {
return;
}
if (task->subTask != NULL) {
task->subTask->destroyTask(task->subTask);
}
HcFree(task);
}
static bool IsPeerErrMessage(const CJson *in)
{
int32_t res = 0;
int32_t message = 0;
if ((GetIntFromJson(in, FIELD_MESSAGE, &message) != CLIB_SUCCESS) &&
(GetIntFromJson(in, FIELD_STEP, &message) != CLIB_SUCCESS)) {
LOGD("There is no message code."); // The first message of the client has no message code
return false;
}
if (message != ERR_MSG) {
return false;
}
if (GetIntFromJson(in, FIELD_ERROR_CODE, &res) != CLIB_SUCCESS) {
LOGE("Get peer error code failed.");
}
LOGE("Receive error message from peer, errCode: %x.", res);
return true;
}
static int32_t MapSubTaskTypeToOpCode(AccountTaskType subTaskType)
{
if (subTaskType >= TASK_TYPE_PAKE_V2_AUTH_CLIENT && subTaskType <= TASK_TYPE_ISO_AUTH_SERVER) {
return AUTHENTICATE;
}
return CODE_NULL;
}
static int32_t ProcessTaskT(AccountTask *task, const CJson *in, CJson *out, int32_t *status)
{
if (IsPeerErrMessage(in)) {
AccountSendErrMsgToSelf(out, HC_ERR_PEER_ERROR);
return HC_ERR_PEER_ERROR;
}
int32_t res = task->subTask->process(task->subTask, in, out, status);
if (res != HC_SUCCESS) {
LOGE("Process subTask failed, res: %x.", res);
int32_t operationCode = MapSubTaskTypeToOpCode(task->subTask->getTaskType());
AccountSendErrMsgToOut(out, operationCode, res);
}
return res;
}
static int32_t NegotiateAndCreateSubTask(AccountTask *task, const CJson *in, CJson *out)
{
bool isClient = false;
int32_t operationCode = 0;
uint64_t versionNo = 0;
if (GetBoolFromJson(in, FIELD_IS_CLIENT, &isClient) != CLIB_SUCCESS) {
LOGI("There is no isClient in json.");
}
if (GetIntFromJson(in, FIELD_OPERATION_CODE, &operationCode) != CLIB_SUCCESS) {
LOGE("Get operationCode from json failed.");
return HC_ERR_JSON_GET;
}
if (isClient) {
versionNo = GetSupportedVersionNo(operationCode);
} else if (GetInt64FromJson(in, FIELD_SUPPORTED_VERSION, (int64_t *)&versionNo) != CLIB_SUCCESS) {
LOGE("No peer supportedVersion for server.");
return HC_ERR_BAD_MESSAGE;
}
const AccountVersionInfo *verInfo = GetNegotiatedVersionInfo(operationCode, versionNo);
if (verInfo == NULL) {
LOGE("Get Negotiated versionInfo failed.");
return HC_ERR_UNSUPPORTED_VERSION;
}
task->subTask = verInfo->createTask(in, out, verInfo);
if (task->subTask == NULL) {
LOGE("Create sub task failed.");
return HC_ERR_ALLOC_MEMORY;
}
task->versionStatus = VERSION_CONFIRMED;
return HC_SUCCESS;
}
static void AccountSendCreateError(const CJson *in, CJson *out, int32_t errCode)
{
bool isClient = false;
if (GetBoolFromJson(in, FIELD_IS_CLIENT, &isClient) != CLIB_SUCCESS) {
LOGE("Get isClient from json failed.");
}
if (isClient) {
AccountSendErrMsgToSelf(out, errCode);
return;
}
int32_t operationCode = CODE_NULL;
if (GetIntFromJson(in, FIELD_OPERATION_CODE, &operationCode) != CLIB_SUCCESS) {
LOGE("Get operationCode from json failed.");
} else {
AccountSendErrMsgToOut(out, operationCode, errCode);
}
}
AccountTask *CreateAccountTaskT(int32_t *taskId, const CJson *in, CJson *out)
{
int32_t res;
AccountTask *task = (AccountTask *)HcMalloc(sizeof(AccountTask), 0);
if (task == NULL) {
LOGE("Malloc for account related task failed.");
res = HC_ERR_ALLOC_MEMORY;
goto ERR;
}
task->destroyTask = DestroyTaskT;
task->processTask = ProcessTaskT;
task->versionStatus = VERSION_INITIAL;
Uint8Buff taskIdBuf = { (uint8_t *)taskId, sizeof(int32_t) };
res = GetLoaderInstance()->generateRandom(&taskIdBuf);
if (res != HC_SUCCESS) {
LOGE("Generate taskId failed, res: %d.", res);
goto ERR;
}
task->taskId = *taskId;
res = NegotiateAndCreateSubTask(task, in, out);
if (res != HC_SUCCESS) {
LOGE("NegotiateAndCreateSubTask failed, res: %d.", res);
goto ERR;
}
return task;
ERR:
AccountSendCreateError(in, out, res);
DestroyTaskT(task);
return NULL;
}
@@ -0,0 +1,93 @@
/*
* Copyright (C) 2022 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 "account_version_util.h"
#include "common_defs.h"
#include "hc_log.h"
#include "hc_types.h"
#include "pake_defs.h"
#include "pake_protocol_dl_common.h"
#include "pake_protocol_ec_common.h"
#include "pake_v2_auth_task_common.h"
#define IS_SUPPORT_CURVE_256 true
#define IS_SUPPORT_CURVE_25519 false
DECLARE_HC_VECTOR(AccountVersionInfoVec, void *)
IMPLEMENT_HC_VECTOR(AccountVersionInfoVec, void *, 1)
static AccountVersionInfoVec g_authVersionInfoVec;
static uint64_t g_authVersionNo = 0;
static bool IsAuthPakeV2EcP256Supported(void)
{
return IsPakeV2AuthTaskSupported() && (GetPakeEcAlg() == PAKE_ALG_EC) && IS_SUPPORT_CURVE_256;
}
static AccountVersionInfo g_authVersionInfoAll[] = {
{ AUTH_PAKE_V2_EC_P256, PAKE_V2, PAKE_ALG_EC, CURVE_256, false, IsAuthPakeV2EcP256Supported, CreatePakeV2AuthTask},
};
void InitVersionInfos(void)
{
g_authVersionInfoVec = CREATE_HC_VECTOR(AccountVersionInfoVec);
uint32_t size = sizeof(g_authVersionInfoAll) / sizeof(AccountVersionInfo);
for (uint32_t i = 0; i < size; i++) {
if (!g_authVersionInfoAll[i].isTaskSupported()) {
continue;
}
(void)g_authVersionInfoVec.pushBackT(&g_authVersionInfoVec, (void *)(&g_authVersionInfoAll[i]));
g_authVersionNo |= g_authVersionInfoAll[i].versionNo;
}
}
void DestroyVersionInfos(void)
{
DESTROY_HC_VECTOR(AccountVersionInfoVec, &g_authVersionInfoVec);
}
static const AccountVersionInfo *NegotiateForAuth(uint64_t versionNo)
{
uint32_t index;
void **ptr = NULL;
FOR_EACH_HC_VECTOR(g_authVersionInfoVec, index, ptr) {
if (ptr == NULL || *ptr == NULL) {
continue;
}
AccountVersionInfo *temp = (AccountVersionInfo *)(*ptr);
if ((temp->versionNo & versionNo) == versionNo) {
return temp;
}
}
LOGE("Version is not matched, failed to negotiate for account auth.");
return NULL;
}
const AccountVersionInfo *GetNegotiatedVersionInfo(int32_t operationCode, uint64_t versionNo)
{
// Now, only support auth negotiate.
if (operationCode != AUTHENTICATE) {
LOGE("operationCode is not auth, not supported.");
return NULL;
}
return NegotiateForAuth(versionNo);
}
uint64_t GetSupportedVersionNo(int32_t operationCode)
{
(void)operationCode; // Now, only support auth negotiate.
return g_authVersionNo;
}
@@ -0,0 +1,312 @@
/*
* Copyright (C) 2022 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 "pake_v2_auth_client_task.h"
#include "common_defs.h"
#include "device_auth_defines.h"
#include "hal_error.h"
#include "hc_types.h"
#include "hc_log.h"
#include "string_util.h"
#include "protocol_common.h"
#include "account_module.h"
#include "account_version_util.h"
#include "pake_v2_auth_task_common.h"
#include "pake_v2_protocol_common.h"
enum {
TASK_STATUS_PAKE_MAIN_BEGIN = 0,
TASK_STATUS_PAKE_MAIN_STEP_ONE = 1,
TASK_STATUS_PAKE_MAIN_STEP_TWO = 2,
TASK_STATUS_PAKE_MAIN_END = 3,
};
static AccountTaskType GetPakeV2AuthClientType(void)
{
return TASK_TYPE_PAKE_V2_AUTH_CLIENT;
}
static int32_t DealClientStepOne(PakeAuthParams *params, const CJson *in)
{
int32_t res = ExtractSelfDevId(params, in);
if (res != HC_SUCCESS) {
LOGE("ExtractSelfDevId failed for client.");
}
return res;
}
static int32_t AsyAuthClientStepOne(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
{
PakeV2AuthClientTask *innerTask = (PakeV2AuthClientTask *)task;
CJson *sendToPeer = CreateJson();
if (sendToPeer == NULL) {
LOGE("Failed to create sendToPeer json.");
return HC_ERR_JSON_CREATE;
}
CJson *data = CreateJson();
if (data == NULL) {
LOGE("Failed to create data json.");
FreeJson(sendToPeer);
return HC_ERR_JSON_CREATE;
}
uint64_t versionNo = GetSupportedVersionNo(AUTHENTICATE);
GOTO_IF_ERR(GetIntFromJson(in, FIELD_AUTH_FORM, &innerTask->params.authForm));
GOTO_IF_ERR(ExtractSelfDeviceId(&innerTask->params, in, true));
GOTO_IF_ERR(DealClientStepOne(&innerTask->params, in));
GOTO_IF_ERR(AddInt64StringToJson(sendToPeer, FIELD_SUPPORTED_VERSION, versionNo));
GOTO_IF_ERR(AddIntToJson(sendToPeer, FIELD_AUTH_FORM, innerTask->params.authForm));
GOTO_IF_ERR(AddStringToJson(sendToPeer, FIELD_USER_ID, (const char *)innerTask->params.userIdSelf));
GOTO_IF_ERR(AddIntToJson(sendToPeer, FIELD_STEP, CMD_PAKE_AUTH_MAIN_ONE));
GOTO_IF_ERR(AddStringToJson(sendToPeer, FIELD_DEVICE_ID, (const char *)innerTask->params.deviceIdSelf.val));
GOTO_IF_ERR(AddStringToJson(sendToPeer, FIELD_DEV_ID, (const char *)innerTask->params.devIdSelf.val));
GOTO_IF_ERR(AddIntToJson(data, FIELD_AUTH_KEY_ALG_ENCODE, ALG_ECC));
GOTO_IF_ERR(AddStringToJson(data, FIELD_AUTH_PK_INFO, (const char *)innerTask->params.pkInfoSelf.val));
GOTO_IF_ERR(AddByteToJson(data, FIELD_AUTH_PK_INFO_SIGN, innerTask->params.pkInfoSignSelf.val,
innerTask->params.pkInfoSignSelf.length));
GOTO_IF_ERR(AddObjToJson(sendToPeer, FIELD_DATA, data));
GOTO_IF_ERR(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer));
innerTask->taskBase.taskStatus = TASK_STATUS_PAKE_MAIN_STEP_ONE;
*status = CONTINUE;
FreeJson(sendToPeer);
FreeJson(data);
return HC_SUCCESS;
ERR:
LOGE("Client step one failed.");
FreeJson(sendToPeer);
FreeJson(data);
return HC_ERR_AUTH_INTERNAL;
}
static int32_t DealAsyStepTwoData(PakeV2AuthClientTask *task)
{
if (ExtractPakeSelfId(&task->params) != HC_SUCCESS) {
LOGE("ExtractPakeSelfId failed for client.");
return HC_ERR_AUTH_INTERNAL;
}
if (VerifyPkSignPeer(&task->params) != HC_SUCCESS) {
LOGE("VerifyPkSignPeer failed for client.");
return HC_ERR_ACCOUNT_VERIFY_PK_SIGN;
}
if (GenerateEcdhSharedKey(&task->params) != HC_SUCCESS) {
LOGE("Generate ecdh shared key failed for client.");
return HC_ERR_ACCOUNT_ECDH_FAIL;
}
if (ClientConfirmPakeV2Protocol(&task->params.pakeParams)) {
LOGE("ClientConfirmPakeV2Protocol failed.");
return HC_ERR_CLIENT_CONFIRM_PROTOCOL;
}
return HC_SUCCESS;
}
static int32_t PrepareAsyClientStepTwoData(const PakeV2AuthClientTask *innerTask, CJson *out)
{
CJson *sendToPeer = CreateJson();
if (sendToPeer == NULL) {
LOGE("Create sendToPeer json NULL.");
return HC_ERR_JSON_CREATE;
}
CJson *data = CreateJson();
if (data == NULL) {
LOGE("Create data json NULL.");
FreeJson(sendToPeer);
return HC_ERR_JSON_CREATE;
}
int32_t ret = HC_SUCCESS;
GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_AUTH_FORM, innerTask->params.authForm), ret);
GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_STEP, CMD_PAKE_AUTH_MAIN_TWO), ret);
GOTO_ERR_AND_SET_RET(AddByteToJson(data, FIELD_KCF_DATA, innerTask->params.pakeParams.kcfData.val,
innerTask->params.pakeParams.kcfData.length), ret);
GOTO_ERR_AND_SET_RET(AddStringToJson(data, FIELD_DEVICE_ID,
(const char *)innerTask->params.deviceIdSelf.val), ret);
GOTO_ERR_AND_SET_RET(AddByteToJson(data, FIELD_EPK, innerTask->params.pakeParams.epkSelf.val,
innerTask->params.pakeParams.epkSelf.length), ret);
GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_DATA, data), ret);
GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), ret);
ERR:
FreeJson(sendToPeer);
FreeJson(data);
return ret;
}
static int32_t AsyAuthClientStepTwo(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
{
PakeV2AuthClientTask *innerTask = (PakeV2AuthClientTask *)task;
if (innerTask->taskBase.taskStatus != TASK_STATUS_PAKE_MAIN_STEP_ONE) {
LOGE("Client step two status error.");
return HC_ERR_AUTH_STATUS;
}
const char *userIdPeer = GetStringFromJson(in, FIELD_USER_ID);
uint32_t userIdPeerLen = HcStrlen(userIdPeer) + 1;
if (userIdPeer == NULL || userIdPeerLen > USER_ID_SIZE) {
LOGE("Payload not contain peer userId or userId len is invalid.");
return HC_ERR_BAD_MESSAGE;
}
GOTO_IF_ERR(strcpy_s((char *)innerTask->params.userIdPeer, userIdPeerLen, userIdPeer));
GOTO_IF_ERR(GetPkInfoPeer(&innerTask->params, in));
GOTO_IF_ERR(ExtractPeerDeviceId(&innerTask->params, in));
GOTO_IF_ERR(ExtractPeerDevId(&innerTask->params, in));
GOTO_IF_ERR(ExtractPakePeerId(&innerTask->params, in));
GOTO_IF_ERR(GetByteFromJson(in, FIELD_AUTH_PK_INFO_SIGN, innerTask->params.pkInfoSignPeer.val,
innerTask->params.pkInfoSignPeer.length));
const char *pkInfoSignPeerStr = GetStringFromJson(in, FIELD_AUTH_PK_INFO_SIGN);
if (pkInfoSignPeerStr == NULL) {
LOGE("pkInfoSignPeer in client is null.");
return HC_ERR_NULL_PTR;
}
innerTask->params.pkInfoSignPeer.length = HcStrlen(pkInfoSignPeerStr) / BYTE_TO_HEX_OPER_LENGTH;
GOTO_IF_ERR(GetByteFromJson(in, FIELD_SALT, innerTask->params.pakeParams.salt.val,
innerTask->params.pakeParams.salt.length));
GOTO_IF_ERR(GetByteFromJson(in, FIELD_EPK, innerTask->params.pakeParams.epkPeer.val,
innerTask->params.pakeParams.epkPeer.length));
GOTO_IF_ERR(DealAsyStepTwoData(innerTask));
GOTO_IF_ERR(PrepareAsyClientStepTwoData(innerTask, out));
innerTask->taskBase.taskStatus = TASK_STATUS_PAKE_MAIN_STEP_TWO;
*status = CONTINUE;
return HC_SUCCESS;
ERR:
LOGE("Client step two failed");
return HC_ERR_AUTH_INTERNAL;
}
static int32_t DealAsyStepThreeData(PakeAuthParams *params)
{
int32_t res = ClientVerifyConfirmPakeV2Protocol(&params->pakeParams);
if (res != HC_SUCCESS) {
LOGE("Client Verify ConfirmPakeV2Protocol failed.");
}
return res;
}
static int32_t SendFinalToOut(PakeV2AuthClientTask *task, CJson *out)
{
CJson *sendToSelf = CreateJson();
if (sendToSelf == NULL) {
LOGE("Create sendToSelf json NULL.");
return HC_ERR_JSON_CREATE;
}
GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_USER_ID, (const char *)task->params.userIdPeer));
GOTO_IF_ERR(AddByteToJson(sendToSelf,
FIELD_SESSION_KEY, task->params.pakeParams.sessionKey.val, task->params.pakeParams.sessionKey.length));
GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_DEVICE_ID, (const char *)task->params.deviceIdSelf.val));
GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_DEV_ID, (const char *)task->params.devIdPeer.val));
GOTO_IF_ERR(AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf));
FreeJson(sendToSelf);
FreeAndCleanKey(&task->params.pakeParams.sessionKey);
return HC_SUCCESS;
ERR:
FreeAndCleanKey(&task->params.pakeParams.sessionKey);
FreeJson(sendToSelf);
LOGE("SendFinalToOut failed");
return HC_ERR_AUTH_INTERNAL;
}
static int32_t AsyAuthClientStepThree(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
{
PakeV2AuthClientTask *innerTask = (PakeV2AuthClientTask *)task;
if (innerTask->taskBase.taskStatus != TASK_STATUS_PAKE_MAIN_STEP_TWO) {
LOGE("Client step three status error.");
return HC_ERR_AUTH_STATUS;
}
GOTO_IF_ERR(GetByteFromJson(in, FIELD_KCF_DATA,
innerTask->params.pakeParams.kcfDataPeer.val, innerTask->params.pakeParams.kcfDataPeer.length));
GOTO_IF_ERR(DealAsyStepThreeData(&innerTask->params));
GOTO_IF_ERR(SendFinalToOut(innerTask, out));
innerTask->taskBase.taskStatus = TASK_STATUS_PAKE_MAIN_END;
*status = FINISH;
return HC_SUCCESS;
ERR:
LOGE("Client step three failed");
return HC_ERR_AUTH_INTERNAL;
}
static int32_t ProcessClientTask(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
{
LOGI("Start process client pake v2 auth task.");
if (task == NULL || in == NULL || out == NULL || status == NULL) {
LOGE("ProcessClientTask in params NULL.");
return HC_ERR_INVALID_PARAMS;
}
if (task->taskStatus == TASK_STATUS_PAKE_MAIN_BEGIN) {
return AsyAuthClientStepOne(task, in, out, status);
}
int32_t step = 0; // step comes from opposite device
if (GetIntFromJson(in, FIELD_STEP, &step) != HC_SUCCESS) {
LOGE("Get no auth step.");
return HC_ERR_JSON_GET;
}
int32_t res;
switch (step) {
case RET_PAKE_AUTH_FOLLOWER_ONE: // the step name of the opposite
res = AsyAuthClientStepTwo(task, in, out, status);
break;
case RET_PAKE_AUTH_FOLLOWER_TWO:
res = AsyAuthClientStepThree(task, in, out, status);
break;
case ERR_MSG:
return HC_ERR_PEER_ERROR;
default:
res = HC_ERR_BAD_MESSAGE;
break;
}
if (res != HC_SUCCESS) {
LOGE("error occurred and send error");
return res;
}
LOGI("End process client, step = %d", step);
return HC_SUCCESS;
}
static void DestroyAuthClientAuthTask(TaskBase *task)
{
if (task == NULL) {
LOGD("Task is NULL");
return;
}
PakeV2AuthClientTask *innerTask = (PakeV2AuthClientTask *)task;
DestroyPakeAuthParams(&(innerTask->params));
HcFree(innerTask);
}
TaskBase *CreatePakeV2AuthClientTask(const CJson *in, CJson *out, const AccountVersionInfo *verInfo)
{
if (in == NULL || out == NULL || verInfo == NULL) {
LOGE("Params is null for create client pake v2 auth task.");
return NULL;
}
PakeV2AuthClientTask *taskParams = (PakeV2AuthClientTask *)HcMalloc(sizeof(PakeV2AuthClientTask), 0);
if (taskParams == NULL) {
LOGE("Malloc for PakeV2AuthClientTask failed.");
return NULL;
}
taskParams->taskBase.getTaskType = GetPakeV2AuthClientType;
taskParams->taskBase.destroyTask = DestroyAuthClientAuthTask;
taskParams->taskBase.process = ProcessClientTask;
int32_t res = InitPakeAuthParams(in, &(taskParams->params), verInfo);
if (res != HC_SUCCESS) {
DestroyAuthClientAuthTask((TaskBase *)taskParams);
LOGE("InitPakeAuthParams failed");
return NULL;
}
taskParams->taskBase.taskStatus = TASK_STATUS_PAKE_MAIN_BEGIN;
return (TaskBase *)taskParams;
}
@@ -0,0 +1,313 @@
/*
* Copyright (C) 2022 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 "pake_v2_auth_server_task.h"
#include "account_module.h"
#include "asy_token_manager.h"
#include "common_defs.h"
#include "device_auth_defines.h"
#include "hc_log.h"
#include "hc_types.h"
#include "pake_v2_auth_task_common.h"
#include "pake_v2_protocol_common.h"
#include "protocol_common.h"
#include "account_version_util.h"
enum {
TASK_STATUS_PAKE_FOLLOW_BEGIN = 0,
TASK_STATUS_PAKE_FOLLOW_STEP_ONE = 1,
TASK_STATUS_PAKE_FOLLOW_STEP_TWO = 2,
TASK_STATUS_PAKE_FOLLOW_END = 3,
};
static AccountTaskType GetPakeV2AuthServerType(void)
{
return TASK_TYPE_PAKE_V2_AUTH_SERVER;
}
static void DestroyAuthServerAuthTask(TaskBase *task)
{
if (task == NULL) {
LOGD("NULL pointer and return");
return;
}
PakeV2AuthServerTask *innerTask = (PakeV2AuthServerTask *)task;
DestroyPakeAuthParams(&(innerTask->params));
HcFree(innerTask);
}
static int32_t DealAsyStepOneData(PakeV2AuthServerTask *task, const CJson *in)
{
int32_t res = ExtractSelfDevId(&task->params, in);
if (res != HC_SUCCESS) {
LOGE("ExtractSelfDevId failed for server.");
return res;
}
if (VerifyPkSignPeer(&task->params) != HC_SUCCESS) {
LOGE("Step one: VerifyPkSignPeer failed for server.");
return HC_ERR_ACCOUNT_VERIFY_PK_SIGN;
}
if (GenerateEcdhSharedKey(&task->params) != HC_SUCCESS) {
LOGE("Step one: Generate ecdh shared key failed for server.");
return HC_ERR_ACCOUNT_ECDH_FAIL;
}
res = ServerResponsePakeV2Protocol(&task->params.pakeParams);
if (res != HC_SUCCESS) {
LOGE("Step one: ServerResponsePakeV2Protocol failed.");
return res;
}
if (ExtractPakeSelfId(&task->params) != HC_SUCCESS) {
LOGE("ConstructPayLoad peer failed.");
return HC_ERR_AUTH_INTERNAL;
}
return HC_SUCCESS;
}
static int32_t GetNegotiatedVersionForServer(const CJson *in, uint64_t *negotiatedVersionNo)
{
uint64_t peerSupportedVersion = 0;
if (GetInt64FromJson(in, FIELD_SUPPORTED_VERSION, (int64_t *)&peerSupportedVersion) != HC_SUCCESS) {
LOGE("Get version from client failed.");
return HC_ERR_JSON_GET;
}
const AccountVersionInfo *verInfo = GetNegotiatedVersionInfo(AUTHENTICATE, peerSupportedVersion);
if (verInfo == NULL) {
LOGE("Get negotiated VersionInfo failed for server.");
return HC_ERR_UNSUPPORTED_VERSION;
}
*negotiatedVersionNo = verInfo->versionNo;
return HC_SUCCESS;
}
static int32_t PrepareAsyServerStepOneData(const PakeV2AuthServerTask *innerTask, const CJson *in, CJson *out)
{
uint64_t negotiatedVersionNo = 0;
if (GetNegotiatedVersionForServer(in, &negotiatedVersionNo) != HC_SUCCESS) {
return HC_ERR_AUTH_INTERNAL;
}
CJson *sendToPeer = CreateJson();
if (sendToPeer == NULL) {
LOGE("Create json NULL.");
return HC_ERR_JSON_CREATE;
}
CJson *data = CreateJson();
if (data == NULL) {
LOGE("Create json NULL.");
FreeJson(sendToPeer);
return HC_ERR_JSON_CREATE;
}
int32_t ret = HC_SUCCESS;
GOTO_ERR_AND_SET_RET(AddInt64StringToJson(sendToPeer, FIELD_SUPPORTED_VERSION, negotiatedVersionNo), ret);
GOTO_ERR_AND_SET_RET(AddStringToJson(sendToPeer, FIELD_USER_ID,
(const char *)innerTask->params.userIdSelf), ret);
GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_STEP, RET_PAKE_AUTH_FOLLOWER_ONE), ret);
GOTO_ERR_AND_SET_RET(AddStringToJson(sendToPeer, FIELD_DEVICE_ID,
(const char *)innerTask->params.deviceIdSelf.val), ret);
GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_AUTH_FORM, 1), ret);
GOTO_ERR_AND_SET_RET(AddStringToJson(sendToPeer, FIELD_DEV_ID, (const char *)innerTask->params.devIdSelf.val), ret);
GOTO_ERR_AND_SET_RET(AddIntToJson(data, FIELD_AUTH_KEY_ALG_ENCODE, innerTask->params.authKeyAlgEncode), ret);
GOTO_ERR_AND_SET_RET(AddStringToJson(data, FIELD_AUTH_PK_INFO,
(const char *)innerTask->params.pkInfoSelf.val), ret);
GOTO_ERR_AND_SET_RET(AddByteToJson(data, FIELD_AUTH_PK_INFO_SIGN, innerTask->params.pkInfoSignSelf.val,
innerTask->params.pkInfoSignSelf.length), ret);
GOTO_ERR_AND_SET_RET(AddByteToJson(data, FIELD_EPK, innerTask->params.pakeParams.epkSelf.val,
innerTask->params.pakeParams.epkSelf.length), ret);
GOTO_ERR_AND_SET_RET(AddByteToJson(data, FIELD_SALT, innerTask->params.pakeParams.salt.val,
innerTask->params.pakeParams.salt.length), ret);
GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_DATA, data), ret);
GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), ret);
ERR:
FreeJson(sendToPeer);
FreeJson(data);
return ret;
}
static int32_t AsyAuthServerStepOne(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
{
PakeV2AuthServerTask *innerTask = (PakeV2AuthServerTask *)task;
if (innerTask->taskBase.taskStatus != TASK_STATUS_PAKE_FOLLOW_STEP_ONE) {
LOGE("Server step one task status error.");
return HC_ERR_AUTH_STATUS;
}
GOTO_IF_ERR(GetIntFromJson(in, FIELD_AUTH_FORM, &innerTask->params.authForm));
const char *userIdPeer = GetStringFromJson(in, FIELD_USER_ID);
uint32_t userIdPeerLen = HcStrlen(userIdPeer) + 1;
if (userIdPeer == NULL || userIdPeerLen > USER_ID_SIZE) {
LOGE("Payload not contain peer userId or userId len is invalid.");
return HC_ERR_BAD_MESSAGE;
}
GOTO_IF_ERR(strcpy_s((char *)innerTask->params.userIdPeer, userIdPeerLen, userIdPeer));
GOTO_IF_ERR(ExtractSelfDeviceId(&innerTask->params, in, true));
GOTO_IF_ERR(ExtractPeerDeviceId(&innerTask->params, in));
GOTO_IF_ERR(ExtractPeerDevId(&innerTask->params, in));
GOTO_IF_ERR(GetIntFromJson(in, FIELD_AUTH_KEY_ALG_ENCODE, &innerTask->params.authKeyAlgEncode));
GOTO_IF_ERR(GetPkInfoPeer(&innerTask->params, in));
GOTO_IF_ERR(GetByteFromJson(in, FIELD_AUTH_PK_INFO_SIGN, innerTask->params.pkInfoSignPeer.val,
innerTask->params.pkInfoSignPeer.length));
const char *pkInfoSignPeerStr = GetStringFromJson(in, FIELD_AUTH_PK_INFO_SIGN);
if (pkInfoSignPeerStr == NULL) {
LOGE("pkInfoSignPeer in server is null.");
return HC_ERR_NULL_PTR;
}
innerTask->params.pkInfoSignPeer.length = HcStrlen(pkInfoSignPeerStr) / BYTE_TO_HEX_OPER_LENGTH;
GOTO_IF_ERR(DealAsyStepOneData(innerTask, in));
GOTO_IF_ERR(PrepareAsyServerStepOneData(innerTask, in, out));
innerTask->taskBase.taskStatus = TASK_STATUS_PAKE_FOLLOW_STEP_TWO;
*status = CONTINUE;
return HC_SUCCESS;
ERR:
LOGE("Server step one failed.");
return HC_ERR_AUTH_INTERNAL;
}
static int32_t DealAsyStepTwoData(PakeV2AuthServerTask *task)
{
if (ServerConfirmPakeV2Protocol(&task->params.pakeParams) != HC_SUCCESS) {
LOGE("Server ConfirmPakeV2Protocol failed.");
return HC_ERR_SERVER_CONFIRM_PROTOCOL;
}
return HC_SUCCESS;
}
static int32_t SendFinalToOut(PakeV2AuthServerTask *task, CJson *out)
{
CJson *sendToSelf = CreateJson();
if (sendToSelf == NULL) {
LOGE("Create json sendToSelf failed.");
return HC_ERR_JSON_CREATE;
}
CJson *sendToPeer = CreateJson();
if (sendToPeer == NULL) {
LOGE("Create json sendToPeer failed.");
FreeJson(sendToSelf);
return HC_ERR_JSON_CREATE;
}
CJson *sendToPeerData = CreateJson();
if (sendToPeerData == NULL) {
LOGE("Create json sendToPeerData failed.");
FreeJson(sendToPeer);
FreeJson(sendToSelf);
return HC_ERR_JSON_CREATE;
}
GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_USER_ID, (const char *)task->params.userIdPeer));
GOTO_IF_ERR(AddByteToJson(sendToSelf, FIELD_SESSION_KEY,
task->params.pakeParams.sessionKey.val, task->params.pakeParams.sessionKey.length));
GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_DEVICE_ID, (const char *)task->params.deviceIdSelf.val));
GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_DEV_ID, (const char *)task->params.devIdPeer.val));
GOTO_IF_ERR(AddIntToJson(sendToPeer, FIELD_AUTH_FORM, 1));
GOTO_IF_ERR(AddIntToJson(sendToPeer, FIELD_STEP, RET_PAKE_AUTH_FOLLOWER_TWO));
GOTO_IF_ERR(AddByteToJson(sendToPeerData,
FIELD_KCF_DATA, task->params.pakeParams.kcfData.val, task->params.pakeParams.kcfData.length));
GOTO_IF_ERR(AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf));
GOTO_IF_ERR(AddObjToJson(sendToPeer, FIELD_DATA, sendToPeerData));
GOTO_IF_ERR(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer));
FreeJson(sendToPeer);
FreeJson(sendToSelf);
FreeJson(sendToPeerData);
FreeAndCleanKey(&task->params.pakeParams.sessionKey);
return HC_SUCCESS;
ERR:
LOGE("Server send final failed");
FreeJson(sendToPeer);
FreeJson(sendToSelf);
FreeJson(sendToPeerData);
FreeAndCleanKey(&task->params.pakeParams.sessionKey);
return HC_ERR_AUTH_INTERNAL;
}
static int32_t AsyAuthServerStepTwo(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
{
PakeV2AuthServerTask *innerTask = (PakeV2AuthServerTask *)task;
if (innerTask->taskBase.taskStatus != TASK_STATUS_PAKE_FOLLOW_STEP_TWO) {
LOGE("Server task status error");
return HC_ERR_AUTH_STATUS;
}
GOTO_IF_ERR(GetByteFromJson(in,
FIELD_EPK, innerTask->params.pakeParams.epkPeer.val, innerTask->params.pakeParams.epkPeer.length));
GOTO_IF_ERR(GetByteFromJson(in,
FIELD_KCF_DATA, innerTask->params.pakeParams.kcfDataPeer.val, innerTask->params.pakeParams.kcfDataPeer.length));
GOTO_IF_ERR(ExtractPakePeerId(&innerTask->params, in));
GOTO_IF_ERR(DealAsyStepTwoData(innerTask));
GOTO_IF_ERR(SendFinalToOut(innerTask, out));
innerTask->taskBase.taskStatus = TASK_STATUS_PAKE_FOLLOW_END;
*status = FINISH;
return HC_SUCCESS;
ERR:
LOGE("server AsyAuthServerStepTwo failed");
return HC_ERR_AUTH_INTERNAL;
}
static int32_t ProcessServerTask(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
{
if ((task == NULL) || (in == NULL) || (out == NULL) || (status == NULL)) {
LOGE("invalid param");
return HC_ERR_INVALID_PARAMS;
}
int32_t step = 0;
if (GetIntFromJson(in, FIELD_STEP, &step) != HC_SUCCESS) {
LOGE("server no auth step");
return HC_ERR_JSON_GET;
}
LOGI("ProcessServerTask step: %d", step);
int32_t res;
switch (step) {
case CMD_PAKE_AUTH_MAIN_ONE:
res = AsyAuthServerStepOne(task, in, out, status);
break;
case CMD_PAKE_AUTH_MAIN_TWO:
res = AsyAuthServerStepTwo(task, in, out, status);
break;
case ERR_MSG:
return HC_ERR_PEER_ERROR;
default:
res = HC_ERR_BAD_MESSAGE;
break;
}
if (res != HC_SUCCESS) {
LOGE("Server ProcessServerTask failed, step: %d.", step);
}
return res;
}
TaskBase *CreatePakeV2AuthServerTask(const CJson *in, CJson *out, const AccountVersionInfo *verInfo)
{
if (in == NULL || out == NULL || verInfo == NULL) {
LOGE("Params is null.");
return NULL;
}
PakeV2AuthServerTask *taskParams = (PakeV2AuthServerTask *)HcMalloc(sizeof(PakeV2AuthServerTask), 0);
if (taskParams == NULL) {
LOGE("Malloc taskParams failed");
return NULL;
}
(void)memset_s(taskParams, sizeof(PakeV2AuthServerTask), 0, sizeof(PakeV2AuthServerTask));
taskParams->taskBase.getTaskType = GetPakeV2AuthServerType;
taskParams->taskBase.process = ProcessServerTask;
taskParams->taskBase.destroyTask = DestroyAuthServerAuthTask;
if (InitPakeAuthParams(in, &(taskParams->params), verInfo) != HC_SUCCESS) {
LOGE("InitPakeAuthParams error.");
DestroyAuthServerAuthTask((TaskBase *)taskParams);
return NULL;
}
taskParams->taskBase.taskStatus = TASK_STATUS_PAKE_FOLLOW_STEP_ONE;
return (TaskBase *)taskParams;
}
@@ -0,0 +1,477 @@
/*
* Copyright (C) 2022 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 "pake_v2_auth_task_common.h"
#include <ctype.h>
#include "account_module.h"
#include "asy_token_manager.h"
#include "common_defs.h"
#include "device_auth_defines.h"
#include "hc_dev_info.h"
#include "hal_error.h"
#include "hc_log.h"
#include "hc_types.h"
#include "pake_v2_protocol_common.h"
#include "pake_v2_auth_client_task.h"
#include "pake_v2_auth_server_task.h"
#include "protocol_common.h"
#include "string_util.h"
#define P256_SHARED_SECRET_KEY_SIZE 32
#define P256_PUBLIC_SIZE 64
#define P256_KEY_SIZE 32
#define SHARED_KEY_ALIAS "sharedKeyAlias"
bool IsPakeV2AuthTaskSupported(void)
{
return true;
}
TaskBase *CreatePakeV2AuthTask(const CJson *in, CJson *out, const AccountVersionInfo *verInfo)
{
bool isClient = false;
if (GetBoolFromJson(in, FIELD_IS_CLIENT, &isClient) != HC_SUCCESS) {
LOGD("Get isClient from json failed.");
isClient = false;
}
if (isClient) {
return CreatePakeV2AuthClientTask(in, out, verInfo);
}
return CreatePakeV2AuthServerTask(in, out, verInfo);
}
int32_t VerifyPkSignPeer(const PakeAuthParams *params)
{
uint8_t *serverPkAlias = (uint8_t *)HcMalloc(SHA256_LEN, 0);
if (serverPkAlias == NULL) {
LOGE("Failed to malloc for serverPk key alias.");
return HC_ERR_ALLOC_MEMORY;
}
Uint8Buff serverPkAliasBuff = {
.val = serverPkAlias,
.length = SHA256_LEN
};
int32_t res = GetAccountAuthTokenManager()->generateKeyAlias((const char *)(params->userIdSelf),
(const char *)params->devIdSelf.val, &serverPkAliasBuff, true);
if (res != HC_SUCCESS) {
HcFree(serverPkAlias);
return res;
}
Uint8Buff messageBuff = {
.val = params->pkInfoPeer.val,
.length = params->pkInfoPeer.length
};
Uint8Buff peerSignBuff = {
.val = params->pkInfoSignPeer.val,
.length = params->pkInfoSignPeer.length
};
res = params->pakeParams.loader->verify(&serverPkAliasBuff, &messageBuff, P256, &peerSignBuff, true);
HcFree(serverPkAlias);
if (res != HC_SUCCESS) {
LOGE("Verify pk sign failed.");
return HC_ERR_VERIFY_FAILED;
}
return HC_SUCCESS;
}
int32_t GenerateEcdhSharedKey(PakeAuthParams *params)
{
uint8_t *priAliasVal = (uint8_t *)HcMalloc(SHA256_LEN, 0);
if (priAliasVal == NULL) {
LOGE("Failed to malloc for self key alias.");
return HC_ERR_ALLOC_MEMORY;
}
Uint8Buff aliasBuff = {
.val = priAliasVal,
.length = SHA256_LEN
};
int32_t res = GetAccountAuthTokenManager()->generateKeyAlias((const char *)(params->userIdSelf),
(const char *)params->devIdSelf.val, &aliasBuff, false);
if (res != HC_SUCCESS) {
HcFree(priAliasVal);
return res;
}
KeyBuff priAliasKeyBuff = {
.key = aliasBuff.val,
.keyLen = aliasBuff.length,
.isAlias = true
};
KeyBuff publicKeyBuff = {
.key = params->pkPeer,
.keyLen = sizeof(params->pkPeer),
.isAlias = false
};
uint32_t sharedKeyAliasLen = HcStrlen(SHARED_KEY_ALIAS) + 1;
params->pakeParams.psk.val = (uint8_t *)HcMalloc(sharedKeyAliasLen, 0);
if (params->pakeParams.psk.val == NULL) {
LOGE("Failed to malloc for psk alias.");
HcFree(priAliasVal);
return HC_ERR_ALLOC_MEMORY;
}
params->pakeParams.psk.length = sharedKeyAliasLen;
(void)memcpy_s(params->pakeParams.psk.val, sharedKeyAliasLen, SHARED_KEY_ALIAS, sharedKeyAliasLen);
res = params->pakeParams.loader->agreeSharedSecretWithStorage(&priAliasKeyBuff, &publicKeyBuff,
P256, P256_SHARED_SECRET_KEY_SIZE, &(params->pakeParams.psk));
HcFree(priAliasVal);
return res;
}
static int32_t InitCharStringBuff(Uint8Buff *param, uint32_t len)
{
if (param == NULL || len <= 0) {
LOGE("param is invalid for init.");
return HC_ERR_NULL_PTR;
}
if (InitSingleParam(param, len + 1) != HC_SUCCESS) {
return HC_ERR_ALLOC_MEMORY;
}
param->length = len;
return HC_SUCCESS;
}
int32_t ExtractPakePeerId(PakeAuthParams *params, const CJson *in)
{
if (params == NULL || in == NULL) {
LOGE("Input params is invalid.");
return HC_ERR_INVALID_PARAMS;
}
int32_t deviceIdPeerLen = HcStrlen((const char *)params->deviceIdPeer.val);
if (InitCharStringBuff(&params->pakeParams.idPeer,
params->devIdPeer.length + deviceIdPeerLen) != HC_SUCCESS) {
LOGE("InitCharStringBuff: idPeer failed.");
return HC_ERR_AUTH_INTERNAL;
}
(void)memcpy_s(params->pakeParams.idPeer.val, params->pakeParams.idPeer.length, params->devIdPeer.val,
params->devIdPeer.length);
(void)memcpy_s(params->pakeParams.idPeer.val + params->devIdPeer.length,
params->pakeParams.idPeer.length - params->devIdPeer.length, params->deviceIdPeer.val, deviceIdPeerLen);
return HC_SUCCESS;
}
int32_t ExtractPakeSelfId(PakeAuthParams *params)
{
if (params == NULL) {
LOGE("Input params NULL.");
return HC_ERR_INVALID_PARAMS;
}
int32_t deviceIdSelfLen = HcStrlen((const char *)params->deviceIdSelf.val);
if (InitCharStringBuff(&params->pakeParams.idSelf,
params->devIdSelf.length + deviceIdSelfLen) != HC_SUCCESS) {
LOGE("InitCharStringBuff: idSelf failed.");
return HC_ERR_AUTH_INTERNAL;
}
(void)memcpy_s(params->pakeParams.idSelf.val, params->pakeParams.idSelf.length, params->devIdSelf.val,
params->devIdSelf.length);
(void)memcpy_s(params->pakeParams.idSelf.val + params->devIdSelf.length,
params->pakeParams.idSelf.length - params->devIdSelf.length, params->deviceIdSelf.val, deviceIdSelfLen);
return HC_SUCCESS;
}
int32_t ExtractSelfDeviceId(PakeAuthParams *params, const CJson *in, bool useSelfPrefix)
{
if (params == NULL || in == NULL) {
LOGE("Input params NULL.");
return HC_ERR_INVALID_PARAMS;
}
const char *deviceId = NULL;
if (useSelfPrefix) {
deviceId = GetStringFromJson(in, FIELD_SELF_DEVICE_ID);
} else {
deviceId = GetStringFromJson(in, FIELD_DEVICE_ID);
}
if (deviceId == NULL) {
LOGE("Get selfDeviceId from json failed.");
return HC_ERR_JSON_GET;
}
params->deviceIdSelf.length = HcStrlen(deviceId);
params->deviceIdSelf.val = (uint8_t *)HcMalloc(params->deviceIdSelf.length + 1, 0);
if (params->deviceIdSelf.val == NULL) {
LOGE("Failed to malloc for deviceIdSelf.");
return HC_ERR_ALLOC_MEMORY;
}
if (memcpy_s(params->deviceIdSelf.val, params->deviceIdSelf.length + 1,
deviceId, params->deviceIdSelf.length) != EOK) {
LOGE("Memcpy_s for deviceIdSelf failed.");
return HC_ERR_MEMORY_COPY;
}
return HC_SUCCESS;
}
int32_t ExtractPeerDeviceId(PakeAuthParams *params, const CJson *in)
{
if (params == NULL || in == NULL) {
LOGE("Input params NULL.");
return HC_ERR_INVALID_PARAMS;
}
const char *deviceId = GetStringFromJson(in, FIELD_DEVICE_ID);
if (deviceId == NULL) {
LOGE("Get peer deviceId failed.");
return HC_ERR_JSON_GET;
}
int32_t len = HcStrlen(deviceId);
if (InitCharStringBuff(&params->deviceIdPeer, len) != HC_SUCCESS) {
LOGE("InitCharStringBuff: deviceIdPeer failed.");
return HC_ERR_AUTH_INTERNAL;
}
if (memcpy_s(params->deviceIdPeer.val, params->deviceIdPeer.length + 1, deviceId, len) != EOK) {
LOGE("memcpy_s deviceId failed.");
return HC_ERR_MEMORY_COPY;
}
for (uint32_t i = 0; i < params->deviceIdPeer.length; i++) {
// Change a - f charactor to upper charactor.
if (params->deviceIdPeer.val[i] >= 'a' && params->deviceIdPeer.val[i] <= 'f') {
params->deviceIdPeer.val[i] = toupper(params->deviceIdPeer.val[i]);
}
}
return HC_SUCCESS;
}
int32_t ExtractSelfDevId(PakeAuthParams *params, const CJson *in)
{
if (params == NULL || in == NULL) {
LOGE("Input params is invalid.");
return HC_ERR_INVALID_PARAMS;
}
const char *devIdSelf = GetStringFromJson(in, FIELD_SELF_DEV_ID);
if (devIdSelf == NULL) {
LOGE("Get devIdSelf failed.");
return HC_ERR_JSON_GET;
}
params->devIdSelf.length = HcStrlen(devIdSelf);
params->devIdSelf.val = (uint8_t *)HcMalloc(params->devIdSelf.length + 1, 0);
if (params->devIdSelf.val == NULL) {
LOGE("Malloc for devIdSelf failed.");
return HC_ERR_ALLOC_MEMORY;
}
if (memcpy_s(params->devIdSelf.val, params->devIdSelf.length, devIdSelf,
params->devIdSelf.length) != EOK) {
LOGE("Copy for self devId failed.");
return HC_ERR_MEMORY_COPY;
}
return HC_SUCCESS;
}
int32_t ExtractPeerDevId(PakeAuthParams *params, const CJson *in)
{
if (params == NULL || in == NULL) {
LOGE("Input params is invalid.");
return HC_ERR_INVALID_PARAMS;
}
const char *devId = GetStringFromJson(in, FIELD_DEV_ID);
if (devId == NULL) {
LOGE("Get PeerDevId failed.");
return HC_ERR_JSON_GET;
}
int32_t len = HcStrlen(devId);
// Peer devId type is hex string, no need to transfer.
if (InitCharStringBuff(&params->devIdPeer, len) != HC_SUCCESS) {
LOGE("InitCharStringBuff: idPeer failed.");
return HC_ERR_AUTH_INTERNAL;
}
if (memcpy_s(params->devIdPeer.val, params->devIdPeer.length, devId, len) != EOK) {
LOGE("Failed to copy devId.");
return HC_ERR_MEMORY_COPY;
}
return HC_SUCCESS;
}
int32_t GetPkInfoPeer(PakeAuthParams *params, const CJson *in)
{
if (params == NULL || in == NULL) {
LOGE("Input params is invalid.");
return HC_ERR_INVALID_PARAMS;
}
const char *pkInfoPeerStr = GetStringFromJson(in, FIELD_AUTH_PK_INFO);
if (pkInfoPeerStr == NULL) {
LOGE("Failed to get peer pkInfo string.");
return HC_ERR_JSON_GET;
}
int32_t len = HcStrlen(pkInfoPeerStr) + 1;
if (InitSingleParam(&params->pkInfoPeer, len) != HC_SUCCESS) {
LOGE("Failed to malloc for peer pkInfo.");
return HC_ERR_ALLOC_MEMORY;
}
if (memcpy_s(params->pkInfoPeer.val, len, pkInfoPeerStr, len) != EOK) {
LOGE("GetPkInfoPeer: copy pkInfoPeer failed.");
HcFree(params->pkInfoPeer.val);
params->pkInfoPeer.val = NULL;
return HC_ERR_ALLOC_MEMORY;
}
CJson *info = CreateJsonFromString(pkInfoPeerStr);
if (info == NULL) {
LOGE("Failed to create json for peer pkInfo.");
HcFree(params->pkInfoPeer.val);
params->pkInfoPeer.val = NULL;
return HC_ERR_JSON_CREATE;
}
if (GetByteFromJson(info, FIELD_DEVICE_PK, params->pkPeer, PK_SIZE) != HC_SUCCESS) {
LOGE("Failed to get devicePk.");
FreeJson(info);
HcFree(params->pkInfoPeer.val);
params->pkInfoPeer.val = NULL;
return HC_ERR_JSON_GET;
}
FreeJson(info);
return HC_SUCCESS;
}
static int32_t GetAsyPubKeyInfo(PakeAuthParams *params)
{
AccountToken *token = CreateAccountToken();
if (token == NULL) {
LOGE("Failed to create token.");
return HC_ERR_ALLOC_MEMORY;
}
int32_t res = HC_ERR_GET_PK_INFO;
do {
if (GetAccountAuthTokenManager()->getToken(params->osAccountId, token,
(const char *)params->userIdSelf) != HC_SUCCESS) {
LOGE("Get token from local error.");
break;
}
int32_t pkInfoLen = token->pkInfoStr.length;
if (pkInfoLen >= PUBLIC_KEY_INFO_SIZE) {
LOGE("Length of pkInfo from local is error.");
break;
}
if (InitSingleParam(&params->pkInfoSelf, pkInfoLen) != HC_SUCCESS) {
LOGE("InitSingleParam: pkInfoSelf failed.");
break;
}
if (memcpy_s(params->pkInfoSelf.val, params->pkInfoSelf.length, token->pkInfoStr.val, pkInfoLen) != EOK) {
LOGE("Copy pkInfoSelf failed.");
break;
}
if (memcpy_s(params->pkSelf, PK_SIZE, token->pkInfo.devicePk.val, token->pkInfo.devicePk.length) != EOK) {
LOGE("Copy pkSelf failed.");
break;
}
if (memcpy_s(params->pkInfoSignSelf.val, params->pkInfoSignSelf.length, token->pkInfoSignature.val,
token->pkInfoSignature.length) != EOK) {
LOGE("Copy pkInfoSignSelf failed.");
break;
}
params->pkInfoSignSelf.length = token->pkInfoSignature.length;
Uint8Buff serverPk = {
.val = params->pkCloud,
.length = sizeof(params->pkCloud)
};
if (GetAccountAuthTokenManager()->getServerPublicKey(params->osAccountId,
(const char *)params->userIdSelf, &serverPk) != HC_SUCCESS) {
LOGE("Get local server pk error.");
break;
}
res = HC_SUCCESS;
} while (0);
DestroyAccountToken(token);
return res;
}
static int32_t FillUserIdForAuth(const CJson *in, PakeAuthParams *params)
{
const char *userIdSelf = GetStringFromJson(in, FIELD_SELF_USER_ID);
if (userIdSelf == NULL) {
LOGE("Failed to get self userId from input data.");
return HC_ERR_JSON_GET;
}
if (memcpy_s(params->userIdSelf, sizeof(params->userIdSelf), userIdSelf,
sizeof(params->userIdSelf)) != EOK) {
LOGE("Copy for userIdSelf failed.");
return HC_ERR_MEMORY_COPY;
}
return HC_SUCCESS;
}
int32_t InitPakeAuthParams(const CJson *in, PakeAuthParams *params, const AccountVersionInfo *verInfo)
{
if (in == NULL || params == NULL || verInfo == NULL) {
LOGE("Input params is NULL.");
return HC_ERR_INVALID_PARAMS;
}
const char *deviceId = GetStringFromJson(in, FIELD_SELF_DEVICE_ID);
if (deviceId == NULL) {
LOGE("Self deviceId is NULL.");
return HC_ERR_INVALID_PARAMS;
}
int32_t deviceIdLen = HcStrlen(deviceId);
GOTO_IF_ERR(GetIntFromJson(in, FIELD_OS_ACCOUNT_ID, &params->osAccountId));
GOTO_IF_ERR(InitPakeV2BaseParams(&params->pakeParams));
GOTO_IF_ERR(InitSingleParam(&params->pakeParams.epkPeer, P256_PUBLIC_SIZE));
GOTO_IF_ERR(InitSingleParam(&params->pkInfoSignSelf, SIGNATURE_SIZE));
GOTO_IF_ERR(InitSingleParam(&params->pkInfoSignPeer, SIGNATURE_SIZE));
GOTO_IF_ERR(InitSingleParam(&params->pakeParams.idSelf, deviceIdLen + 1));
(void)memcpy_s(params->pakeParams.idSelf.val, deviceIdLen, deviceId, deviceIdLen);
params->pakeParams.idSelf.length = deviceIdLen;
GOTO_IF_ERR(FillUserIdForAuth(in, params));
GOTO_IF_ERR(GetBoolFromJson(in, FIELD_IS_CLIENT, &params->pakeParams.isClient));
GOTO_IF_ERR(GetAsyPubKeyInfo(params));
params->pakeParams.supportedPakeAlg = verInfo->pakeAlgType;
params->pakeParams.curveType = verInfo->curveType;
params->versionNo = verInfo->versionNo;
#ifdef ACCOUNT_PAKE_DL_PRIME_LEN_384
params->pakeParams.supportedDlPrimeMod = (uint32_t)params->pakeParams.supportedDlPrimeMod | DL_PRIME_MOD_384;
#endif
#ifdef ACCOUNT_PAKE_DL_PRIME_LEN_256
params->pakeParams.supportedDlPrimeMod = (uint32_t)params->pakeParams.supportedDlPrimeMod | DL_PRIME_MOD_256;
#endif
return HC_SUCCESS;
ERR:
LOGE("InitPakeAuthParams failed.");
return HC_ERR_AUTH_INTERNAL;
}
static void FreeUint8Buff(Uint8Buff *buff)
{
if (buff == NULL) {
return;
}
if (buff->val != NULL) {
HcFree(buff->val);
buff->val = NULL;
}
buff->length = 0;
}
void DestroyPakeAuthParams(PakeAuthParams *params)
{
if (params == NULL) {
LOGE("Pointer is NULL.");
return;
}
(void)memset_s(params->pkCloud, sizeof(params->pkCloud), 0, sizeof(params->pkCloud));
(void)memset_s(params->userIdSelf, sizeof(params->userIdSelf), 0, sizeof(params->userIdSelf));
(void)memset_s(params->userIdPeer, sizeof(params->userIdPeer), 0, sizeof(params->userIdPeer));
(void)memset_s(params->pkSelf, sizeof(params->pkSelf), 0, sizeof(params->pkSelf));
(void)memset_s(params->pkPeer, sizeof(params->pkPeer), 0, sizeof(params->pkPeer));
(void)memset_s(params->pkInfoPeer.val, params->pkInfoPeer.length, 0, params->pkInfoPeer.length);
FreeUint8Buff(&params->pkInfoPeer);
FreeUint8Buff(&params->deviceIdPeer);
FreeUint8Buff(&params->devIdSelf);
FreeUint8Buff(&params->devIdPeer);
FreeUint8Buff(&params->pkInfoSelf);
FreeUint8Buff(&params->pkInfoSignPeer);
FreeUint8Buff(&params->pkInfoSignSelf);
DestroyPakeV2BaseParams(&params->pakeParams);
HcFree(params->deviceIdSelf.val);
params->deviceIdSelf.val = NULL;
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2022 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
@@ -35,8 +35,9 @@ AuthModuleBase *CreateAccountModule(void)
return NULL;
}
int32_t ProcessAccountCredentials(int credentialOpCode, const CJson *in, CJson *out)
int32_t ProcessAccountCredentials(int32_t osAccountId, int32_t credentialOpCode, const CJson *in, CJson *out)
{
(void)osAccountId;
(void)credentialOpCode;
(void)in;
(void)out;
+4 -3
View File
@@ -33,8 +33,8 @@ typedef struct {
int32_t type; /* including identical account group(1), peer to peer group(256), across account group(1282) */
int32_t visibility; /* visibility of the group */
int32_t expireTime; /* the time of group expired, unit day, user config */
HcString userIdHash; /* hash result of the user account id */
StringVector sharedUserIdHashVec; /* vector of hash results for shared user account id */
HcString userId; /* the user account id */
HcString sharedUserId; /* the shared user account id */
StringVector managers; /* group manager vector, group manager can add and delete members, index 0 is the owner */
StringVector friends; /* group friend vector, group friend can query group information */
} TrustedGroupEntry;
@@ -45,11 +45,11 @@ typedef struct {
HcString groupId;
HcString udid; /* unique device id */
HcString authId; /* id by service defined for authentication */
HcString userId; /* the user account id */
HcString serviceType; /* compatible with previous versions, the value is the same as groupId */
HcParcel ext; /* for caching extern data, user data */
uint8_t credential; /* 1 - asymmetrical, 2 - symmetrical */
uint8_t devType; /* 0 - accessory, 1 - controller, 2 - proxy */
HcString userIdHash; /* hash result of the user account id */
uint64_t lastTm; /* accessed time of the device of the auth information, absolute time */
} TrustedDeviceEntry;
DECLARE_HC_VECTOR(DeviceEntryVec, TrustedDeviceEntry*)
@@ -58,6 +58,7 @@ typedef struct {
const char *groupId;
const char *groupName;
const char *ownerName;
const char *userId;
int32_t groupType;
int32_t groupVisibility;
} QueryGroupParams;
+70 -38
View File
@@ -34,8 +34,8 @@ typedef struct {
TlvUint32 type;
TlvInt32 visibility;
TlvInt32 expireTime;
TlvString userIdHash;
TlvBuffer sharedUserIdHashVec;
TlvString userId;
TlvString sharedUserId;
TlvBuffer managers;
TlvBuffer friends;
} TlvGroupElement;
@@ -56,10 +56,10 @@ typedef struct {
TlvString groupId;
TlvString udid;
TlvString authId;
TlvString userId;
TlvString serviceType;
TlvBuffer ext;
TlvDevAuthFixedLenInfo info;
TlvString userIdHash;
} TlvDeviceElement;
DECLEAR_INIT_FUNC(TlvDeviceElement)
DECLARE_TLV_VECTOR(TlvDeviceVec, TlvDeviceElement)
@@ -80,8 +80,8 @@ BEGIN_TLV_STRUCT_DEFINE(TlvGroupElement, 0x0001)
TLV_MEMBER(TlvUint32, type, 0x4003)
TLV_MEMBER(TlvInt32, visibility, 0x4004)
TLV_MEMBER(TlvInt32, expireTime, 0x4005)
TLV_MEMBER(TlvString, userIdHash, 0x4006)
TLV_MEMBER(TlvBuffer, sharedUserIdHashVec, 0x4007)
TLV_MEMBER(TlvString, userId, 0x4006)
TLV_MEMBER(TlvString, sharedUserId, 0x4007)
TLV_MEMBER(TlvBuffer, managers, 0x4008)
TLV_MEMBER(TlvBuffer, friends, 0x4009)
END_TLV_STRUCT_DEFINE()
@@ -91,7 +91,7 @@ BEGIN_TLV_STRUCT_DEFINE(TlvDeviceElement, 0x0002)
TLV_MEMBER(TlvString, groupId, 0x4101)
TLV_MEMBER(TlvString, udid, 0x4102)
TLV_MEMBER(TlvString, authId, 0x4103)
TLV_MEMBER(TlvString, userIdHash, 0x4107)
TLV_MEMBER(TlvString, userId, 0x4107)
TLV_MEMBER(TlvString, serviceType, 0x4104)
TLV_MEMBER(TlvBuffer, ext, 0x4105)
TLV_MEMBER(TlvDevAuthFixedLenInfo, info, 0x4106)
@@ -229,8 +229,12 @@ bool GenerateGroupEntryFromEntry(const TrustedGroupEntry *entry, TrustedGroupEnt
LOGE("[DB]: Failed to copy groupId!");
return false;
}
if (!StringSet(&returnEntry->userIdHash, entry->userIdHash)) {
LOGE("[DB]: Failed to copy userIdHash!");
if (!StringSet(&returnEntry->userId, entry->userId)) {
LOGE("[DB]: Failed to copy userId!");
return false;
}
if (!StringSet(&returnEntry->sharedUserId, entry->sharedUserId)) {
LOGE("[DB]: Failed to copy sharedUserId!");
return false;
}
returnEntry->type = entry->type;
@@ -265,12 +269,12 @@ bool GenerateDeviceEntryFromEntry(const TrustedDeviceEntry *entry, TrustedDevice
LOGE("[DB]: Failed to copy authId!");
return false;
}
if (!StringSet(&returnEntry->serviceType, entry->serviceType)) {
LOGE("[DB]: Failed to copy serviceType!");
if (!StringSet(&returnEntry->userId, entry->userId)) {
LOGE("[DB]: Failed to copy userId!");
return false;
}
if (!StringSet(&returnEntry->userIdHash, entry->userIdHash)) {
LOGE("[DB]: Failed to copy userIdHash!");
if (!StringSet(&returnEntry->serviceType, entry->serviceType)) {
LOGE("[DB]: Failed to copy serviceType!");
return false;
}
returnEntry->credential = entry->credential;
@@ -281,22 +285,28 @@ bool GenerateDeviceEntryFromEntry(const TrustedDeviceEntry *entry, TrustedDevice
static bool GenerateGroupEntryFromTlv(TlvGroupElement *group, TrustedGroupEntry *entry)
{
if (!LoadStringVectorFromParcel(&entry->managers, &group->managers.data)) {
return false;
}
if (!LoadStringVectorFromParcel(&entry->friends, &group->friends.data)) {
return false;
}
if (!LoadStringVectorFromParcel(&entry->sharedUserIdHashVec, &group->sharedUserIdHashVec.data)) {
return false;
}
if (!StringSet(&entry->name, group->name.data)) {
LOGE("[DB]: Failed to load groupName from tlv!");
return false;
}
if (!StringSet(&entry->id, group->id.data)) {
LOGE("[DB]: Failed to load groupId from tlv!");
return false;
}
if (!StringSet(&entry->userIdHash, group->userIdHash.data)) {
if (!StringSet(&entry->userId, group->userId.data)) {
LOGE("[DB]: Failed to load userId from tlv!");
return false;
}
if (!StringSet(&entry->sharedUserId, group->sharedUserId.data)) {
LOGE("[DB]: Failed to load sharedUserId from tlv!");
return false;
}
if (!LoadStringVectorFromParcel(&entry->managers, &group->managers.data)) {
LOGE("[DB]: Failed to load managers from tlv!");
return false;
}
if (!LoadStringVectorFromParcel(&entry->friends, &group->friends.data)) {
LOGE("[DB]: Failed to load friends from tlv!");
return false;
}
entry->type = group->type.data;
@@ -309,21 +319,27 @@ static bool GenerateDeviceEntryFromTlv(TlvDeviceElement *device, TrustedDeviceEn
{
deviceEntry->groupEntry = NULL;
if (!StringSet(&deviceEntry->groupId, device->groupId.data)) {
LOGE("[DB]: Failed to load groupId from tlv!");
return false;
}
if (!StringSet(&deviceEntry->udid, device->udid.data)) {
LOGE("[DB]: Failed to load udid from tlv!");
return false;
}
if (!StringSet(&deviceEntry->authId, device->authId.data)) {
LOGE("[DB]: Failed to load authId from tlv!");
return false;
}
if (!StringSet(&deviceEntry->userId, device->userId.data)) {
LOGE("[DB]: Failed to load userId from tlv!");
return false;
}
if (!StringSet(&deviceEntry->serviceType, device->serviceType.data)) {
return false;
}
if (!StringSet(&deviceEntry->userIdHash, device->userIdHash.data)) {
LOGE("[DB]: Failed to load serviceType from tlv!");
return false;
}
if (!ParcelCopy(&device->ext.data, &deviceEntry->ext)) {
LOGE("[DB]: Failed to load external data from tlv!");
return false;
}
deviceEntry->credential = device->info.data.credential;
@@ -497,24 +513,30 @@ static void LoadDeviceAuthDb(void)
static bool SetGroupElement(TlvGroupElement *element, TrustedGroupEntry *entry)
{
if (!StringSet(&element->name.data, entry->name)) {
LOGE("[DB]: Failed to copy groupName!");
return false;
}
if (!StringSet(&element->id.data, entry->id)) {
LOGE("[DB]: Failed to copy groupId!");
return false;
}
if (!StringSet(&element->userIdHash.data, entry->userIdHash)) {
if (!StringSet(&element->userId.data, entry->userId)) {
LOGE("[DB]: Failed to copy userId!");
return false;
}
if (!StringSet(&element->sharedUserId.data, entry->sharedUserId)) {
LOGE("[DB]: Failed to copy sharedUserId!");
return false;
}
element->type.data = entry->type;
element->visibility.data = entry->visibility;
element->expireTime.data = entry->expireTime;
if (!SaveStringVectorToParcel(&entry->managers, &element->managers.data)) {
LOGE("[DB]: Failed to copy managers!");
return false;
}
if (!SaveStringVectorToParcel(&entry->friends, &element->friends.data)) {
return false;
}
if (!SaveStringVectorToParcel(&entry->sharedUserIdHashVec, &element->sharedUserIdHashVec.data)) {
LOGE("[DB]: Failed to copy friends!");
return false;
}
return true;
@@ -523,21 +545,27 @@ static bool SetGroupElement(TlvGroupElement *element, TrustedGroupEntry *entry)
static bool SetDeviceElement(TlvDeviceElement *element, TrustedDeviceEntry *entry)
{
if (!StringSet(&element->groupId.data, entry->groupId)) {
LOGE("[DB]: Failed to copy groupId!");
return false;
}
if (!StringSet(&element->udid.data, entry->udid)) {
LOGE("[DB]: Failed to copy udid!");
return false;
}
if (!StringSet(&element->authId.data, entry->authId)) {
LOGE("[DB]: Failed to copy authId!");
return false;
}
if (!StringSet(&element->userId.data, entry->userId)) {
LOGE("[DB]: Failed to copy userId!");
return false;
}
if (!StringSet(&element->serviceType.data, entry->serviceType)) {
return false;
}
if (!StringSet(&element->userIdHash.data, entry->userIdHash)) {
LOGE("[DB]: Failed to copy serviceType!");
return false;
}
if (!ParcelCopy(&element->ext.data, &entry->ext)) {
LOGE("[DB]: Failed to copy external data!");
return false;
}
element->info.data.credential = entry->credential;
@@ -639,6 +667,9 @@ static bool CompareQueryGroupParams(const QueryGroupParams *params, const Truste
if ((params->groupName != NULL) && (strcmp(params->groupName, StringGet(&entry->name)) != 0)) {
return false;
}
if ((params->userId != NULL) && (strcmp(params->userId, StringGet(&entry->userId)) != 0)) {
return false;
}
if ((params->groupType != ALL_GROUP) && (params->groupType != entry->type)) {
return false;
}
@@ -747,6 +778,7 @@ QueryGroupParams InitQueryGroupParams(void)
.groupId = NULL,
.groupName = NULL,
.ownerName = NULL,
.userId = NULL,
.groupType = ALL_GROUP,
.groupVisibility = ALL_GROUP_VISIBILITY
};
@@ -772,8 +804,8 @@ TrustedGroupEntry *CreateGroupEntry(void)
}
ptr->name = CreateString();
ptr->id = CreateString();
ptr->userIdHash = CreateString();
ptr->sharedUserIdHashVec = CreateStrVector();
ptr->userId = CreateString();
ptr->sharedUserId = CreateString();
ptr->managers = CreateStrVector();
ptr->friends = CreateStrVector();
return ptr;
@@ -783,10 +815,10 @@ void DestroyGroupEntry(TrustedGroupEntry *groupEntry)
{
DeleteString(&groupEntry->name);
DeleteString(&groupEntry->id);
DeleteString(&groupEntry->userIdHash);
DeleteString(&groupEntry->userId);
DeleteString(&groupEntry->sharedUserId);
DestroyStrVector(&groupEntry->managers);
DestroyStrVector(&groupEntry->friends);
DestroyStrVector(&groupEntry->sharedUserIdHashVec);
HcFree(groupEntry);
}
@@ -813,8 +845,8 @@ TrustedDeviceEntry *CreateDeviceEntry(void)
ptr->groupId = CreateString();
ptr->udid = CreateString();
ptr->authId = CreateString();
ptr->userId = CreateString();
ptr->serviceType = CreateString();
ptr->userIdHash = CreateString();
ptr->ext = CreateParcel(0, 0);
return ptr;
}
@@ -824,8 +856,8 @@ void DestroyDeviceEntry(TrustedDeviceEntry *deviceEntry)
DeleteString(&deviceEntry->groupId);
DeleteString(&deviceEntry->udid);
DeleteString(&deviceEntry->authId);
DeleteString(&deviceEntry->userId);
DeleteString(&deviceEntry->serviceType);
DeleteString(&deviceEntry->userIdHash);
DeleteParcel(&deviceEntry->ext);
HcFree(deviceEntry);
}
-2
View File
@@ -25,7 +25,6 @@
#include "hc_init_protection.h"
#include "hc_log.h"
#include "json_utils.h"
#include "lcm_adapter.h"
#include "os_account_adapter.h"
#include "session_manager.h"
#include "task_manager.h"
@@ -280,7 +279,6 @@ DEVICE_AUTH_API_PUBLIC const DeviceGroupManager *GetGmInstance(void)
g_groupManagerInstance->addMemberToGroup = AddMemberToGroupImpl;
g_groupManagerInstance->deleteMemberFromGroup = DeleteMemberFromGroupImpl;
g_groupManagerInstance->processData = ProcessBindDataImpl;
g_groupManagerInstance->processCredential = ProcessCredential;
g_groupManagerInstance->getRegisterInfo = GetRegisterInfo;
g_groupManagerInstance->checkAccessToGroup = CheckAccessToGroupImpl;
g_groupManagerInstance->getPkInfoList = GetPkInfoListImpl;
+4 -7
View File
@@ -41,7 +41,6 @@ inc_path = [
"${group_manager_path}/inc/callback_manager",
"${group_manager_path}/inc/channel_manager",
"${group_manager_path}/inc/channel_manager/soft_bus_channel",
"${group_manager_path}/inc/lcm_adapter",
"${group_manager_path}/inc/session",
"${group_manager_path}/inc/session/bind_session",
"${group_manager_path}/inc/session/bind_session_lite",
@@ -82,6 +81,7 @@ deviceauth_common_files = [
"${protocol_path}/src/pake_protocol/pake_v1_protocol/pake_v1_protocol_common.c",
"${protocol_path}/src/pake_protocol/pake_protocol_dl_common/pake_protocol_dl_common.c",
"${protocol_path}/src/pake_protocol/pake_protocol_ec_common/pake_protocol_ec_common.c",
"${protocol_path}/src/pake_protocol/pake_v2_protocol/pake_v2_protocol_common.c",
]
dev_frameworks_files = [
@@ -222,9 +222,6 @@ broadcast_manager_files =
broadcast_manager_mock_files =
[ "${group_manager_path}/src/broadcast_manager/broadcast_manager_mock.c" ]
lcm_adapter_mock_files =
[ "${group_manager_path}/src/lcm_adapter_mock/lcm_adapter_mock.c" ]
deviceauth_files =
dev_frameworks_files + deviceauth_common_files + key_agree_mock_files
@@ -282,12 +279,12 @@ if (enable_p2p_auth_standard_protocol == true) {
}
if (enable_group == true && enable_account == true) {
import("//base/security/deviceauth_account/deviceauth_account.gni")
import("//base/security/deviceauth/services/deviceauth_account.gni")
deviceauth_defines += account_related_defines
inc_path += account_related_inc_path
deviceauth_files += account_related_files + bind_peer_files
} else if (enable_group == false && enable_account == true) {
import("//base/security/deviceauth_account/deviceauth_account.gni")
import("//base/security/deviceauth/services/deviceauth_account.gni")
deviceauth_defines += account_related_defines
inc_path += account_related_inc_path
deviceauth_files +=
@@ -298,7 +295,7 @@ if (enable_group == true && enable_account == true) {
group_auth_account_related_mock_files +
group_manager_identical_account_mock_files +
group_manager_across_account_mock_files + bind_peer_mock_files +
lcm_adapter_mock_files + authenticators_account_related_mock_files
authenticators_account_related_mock_files
}
if (enable_soft_bus_channel == true) {
+47
View File
@@ -0,0 +1,47 @@
# Copyright (C) 2022 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.
import("//base/security/deviceauth/deviceauth_env.gni")
account_related_defines = []
account_related_inc_path = []
deviceauth_account_group_manager_path = "${services_path}/group_manager"
deviceauth_account_group_auth_path = "${services_path}/group_auth"
group_manager_identical_account_files = [ "${deviceauth_account_group_manager_path}/src/group_operation/identical_account_group/identical_account_group.c" ]
group_manager_across_account_files = [ "${deviceauth_account_group_manager_path}/src/group_operation/across_account_group/across_account_group.c" ]
group_auth_account_related_files = [ "${deviceauth_account_group_auth_path}/src/group_auth_manager/account_related_group_auth/account_related_group_auth.c" ]
account_related_inc_path += [
"${services_path}/authenticators/inc",
"${services_path}/authenticators/inc/account_related",
"${services_path}/authenticators/inc/account_related/auth/pake_v2_auth_task",
"${services_path}/authenticators/inc/account_related/creds_manager/asysmetric_token_manager",
]
authenticators_account_related_files = [
"${services_path}/authenticators/src/account_related/account_module.c",
"${services_path}/authenticators/src/account_related/account_multi_task_manager.c",
"${services_path}/authenticators/src/account_related/account_task_main.c",
"${services_path}/authenticators/src/account_related/account_version_util.c",
"${services_path}/authenticators/src/account_related/creds_manager/asysmetric_token_manager/asy_token_manager.c",
"${services_path}/authenticators/src/account_related/auth/pake_v2_auth_task/pake_v2_auth_task_common.c",
"${services_path}/authenticators/src/account_related/auth/pake_v2_auth_task/pake_v2_auth_client_task.c",
"${services_path}/authenticators/src/account_related/auth/pake_v2_auth_task/pake_v2_auth_server_task.c",
]
account_related_files =
group_auth_account_related_files + group_manager_identical_account_files +
group_manager_across_account_files + authenticators_account_related_files
+24 -1
View File
@@ -22,6 +22,12 @@
#include "hc_vector.h"
#include "json_utils.h"
#define FIELD_DEVICE_PK "devicePk"
#define FIELD_UDID "udid"
#define FIELD_PK_INFO_SIGNATURE "pkInfoSignature"
#define FIELD_CREDENTIAL "credential"
#define FIELD_SERVER_PK "serverPk"
#define FIELD_ADD_TYPE "addType"
#define FIELD_ADD_ID "addId"
#define FIELD_ADD_KEY "addKey"
@@ -71,7 +77,6 @@
#define FIELD_NONCE "nonce"
#define FIELD_OPERATION_CODE "operationCode"
#define FIELD_OPERATION_PARAMS "operationParams"
#define FIELD_OS_ACCOUNT_ID "osAccountId"
#define FIELD_OWNER_ID "ownerId"
#define FIELD_OWNER_NAME "ownerName"
#define FIELD_PERMISSION "Permission"
@@ -79,9 +84,12 @@
#define FIELD_PEER_DEVICE_ID "peerDeviceId"
#define FIELD_PIN_CODE "pinCode"
#define FIELD_PUBLIC_KEY "publicKey"
#define FIELD_PK_INFO "pkInfo"
#define FIELD_PKG_NAME "pkgName"
#define FIELD_SELF_AUTH_ID "selfAuthId"
#define FIELD_SELF_DEVICE_ID "selfDeviceId"
#define FIELD_SELF_DEV_ID "selfDevId"
#define FIELD_SELF_USER_ID "selfUserId"
#define FIELD_REQUEST_ID "requestId"
#define FIELD_RECEIVED_DATA "receivedData"
#define FIELD_RETURN_CODE "returnCode"
@@ -104,6 +112,13 @@
#define FIELD_VERSION "version"
#define FIELD_MK_AGREE_MSG "mkaMsg"
#define FIELD_PEER_ID_FROM_REQUEST "peerIdFromRequest"
#define FIELD_STEP "step"
#define FIELD_DATA "data"
#define FIELD_SUPPORTED_VERSION "supportedVersion"
#define FIELD_EPK "epk"
#define FIELD_AUTH_KEY_ALG_ENCODE "authKeyAlgEncode"
#define FIELD_AUTH_PK_INFO "authPkInfo"
#define FIELD_AUTH_PK_INFO_SIGN "authPkInfoSign"
#define INVALID_MODULE_TYPE (-1)
#define GROUP_ERR_MSG 0x8080
@@ -175,6 +190,14 @@ typedef enum {
} \
} while (0)
#define GOTO_IF_CHECK_NULL(ptr, paramTag) \
do { \
if ((ptr) == NULL) { \
LOGE("%s is null ptr", (paramTag)); \
goto ERR; \
} \
} while (0)
#define GOTO_ERR_AND_SET_RET(x, res) do { \
res = x; \
if ((res) != HC_SUCCESS) { \
@@ -56,7 +56,7 @@ int32_t DeletePeerAuthInfo(const char *pkgName, const char *serviceType, Uint8Bu
int32_t GetPublicKey(int moduleType, AuthModuleParams *params, Uint8Buff *returnPk);
// for ACCOUNT
int32_t ProcessCredentials(int credentialOpCode, const CJson *in, CJson *out, int moduleType);
int32_t GetRegisterInfo(const char *reqJsonStr, char **returnRegisterInfo);
#ifdef __cplusplus
}
@@ -17,6 +17,7 @@
#include "common_defs.h"
#include "das_module.h"
#include "hc_log.h"
#include "hc_types.h"
#include "hc_vector.h"
#include "account_module.h"
#include "version_util.h"
@@ -257,6 +258,17 @@ static int32_t InitAccountModule(void)
return HC_SUCCESS;
}
static int32_t ProcessCredentials(int32_t osAccountId, int32_t credentialOpCode,
const CJson *in, CJson *out, int moduleType)
{
if (moduleType != ACCOUNT_MODULE) {
LOGE("Unsupported method in the module, moduleType: %d.", moduleType);
return HC_ERR_NOT_SUPPORT;
}
return ProcessAccountCredentials(osAccountId, credentialOpCode, in, out);
}
int32_t InitModules(void)
{
g_authModuleVec = CREATE_HC_VECTOR(AuthModuleVec);
@@ -297,12 +309,35 @@ void DestroyModules(void)
(void)memset_s(&g_version, sizeof(VersionStruct), 0, sizeof(VersionStruct));
}
int32_t ProcessCredentials(int credentialOpCode, const CJson *in, CJson *out, int moduleType)
int32_t GetRegisterInfo(const char *reqJsonStr, char **returnRegisterInfo)
{
if (moduleType != ACCOUNT_MODULE) {
LOGE("Unsupported method in the module, moduleType: %d.", moduleType);
return HC_ERR_NOT_SUPPORT;
if ((reqJsonStr == NULL) || (returnRegisterInfo == NULL)) {
LOGE("The input param is NULL!");
return HC_ERR_NULL_PTR;
}
return ProcessAccountCredentials(credentialOpCode, in, out);
CJson *requestJson = CreateJsonFromString(reqJsonStr);
if (requestJson == NULL) {
LOGE("Failed to create request json!");
return HC_ERR_JSON_CREATE;
}
CJson *registerInfo = CreateJson();
if (registerInfo == NULL) {
LOGE("Failed to allocate registerInfo memory!");
FreeJson(requestJson);
return HC_ERR_JSON_CREATE;
}
int32_t result = ProcessCredentials(0, REQUEST_SIGNATURE, requestJson, registerInfo, ACCOUNT_MODULE);
FreeJson(requestJson);
if (result != HC_SUCCESS) {
LOGE("Failed to get register info!");
FreeJson(registerInfo);
return result;
}
*returnRegisterInfo = PackJsonToString(registerInfo);
FreeJson(registerInfo);
if (*returnRegisterInfo == NULL) {
LOGE("Failed to convert json to string!");
return HC_ERR_PACKAGE_JSON_TO_STRING_FAIL;
}
return HC_SUCCESS;
}
@@ -20,8 +20,8 @@
#include "base_group_auth.h"
#include "data_manager.h"
typedef void (*GetAccountCandidateGroupFunc)(const CJson *param, const QueryGroupParams *queryParams,
GroupEntryVec *vec);
typedef void (*GetAccountCandidateGroupFunc)(int32_t osAccountId, const CJson *param,
QueryGroupParams *queryParams, GroupEntryVec *vec);
typedef struct {
BaseGroupAuth base;
@@ -27,6 +27,7 @@ int32_t GaGetTrustedDeviceEntryById(int32_t osAccountId, const char *deviceId,
bool isUdid, const char *groupId, TrustedDeviceEntry *returnDeviceEntry);
bool GaIsDeviceInGroup(int32_t groupType, int32_t osAccountId, const char *peerUdid, const char *peerAuthId,
const char *groupId);
int32_t GaGetLocalDeviceInfo(int32_t osAccountId, const char *groupId, TrustedDeviceEntry *localAuthInfo);
#ifdef __cplusplus
}
@@ -30,6 +30,7 @@ int32_t GetAuthModuleType(const CJson *in);
int32_t GetInfoHash(const uint8_t *info, uint32_t infoLen, char *str, uint32_t strLen);
bool IsBleAuthForAcrossAccount(const CJson *authParam);
int32_t GroupTypeToAuthForm(int32_t groupType);
int32_t AuthFormToGroupType(int32_t authForm);
#ifdef __cplusplus
}
@@ -26,7 +26,7 @@ extern "C" {
char *GetServerConfirmation(const CJson *paramsFromClient, const CJson *reqParam,
const DeviceAuthCallback *callback);
int32_t GetGeneralReqParams(const CJson *receiveData, CJson *reqParam);
bool IsUidHashEqual(const char *uidHashInDb, const char *peerUidHash);
bool IsUserIdEqual(const char *userIdInDb, const char *peerUserIdInDb);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,627 @@
/*
* Copyright (C) 2022 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 "account_related_group_auth.h"
#include "auth_session_common.h"
#include "auth_session_common_util.h"
#include "auth_session_util.h"
#include "common_defs.h"
#include "device_auth_defines.h"
#include "group_auth_data_operation.h"
#include "hc_dev_info.h"
#include "hc_log.h"
#include "hc_types.h"
#include "json_utils.h"
#include "string_util.h"
static void OnAccountFinish(int64_t requestId, const CJson *authParam, const CJson *out,
const DeviceAuthCallback *callback);
static void OnAccountError(int64_t requestId, const AuthSession *session, int errorCode);
static int32_t FillAccountAuthInfo(int32_t osAccountId, const TrustedGroupEntry *entry,
const TrustedDeviceEntry *localAuthInfo, CJson *paramsData);
static void GetAccountCandidateGroup(int32_t osAccountId, const CJson *param,
QueryGroupParams *queryParams, GroupEntryVec *vec);
static int32_t GetAccountAuthParamForServer(const CJson *dataFromClient, ParamsVec *authParamsVec);
static int32_t GetAccountReqParams(const CJson *receiveData, CJson *reqParam);
static int32_t CombineAccountServerConfirms(const CJson *confirmationJson, CJson *dataFromClient);
static AccountRelatedGroupAuth g_accountRelatedGroupAuth = {
.base.onFinish = OnAccountFinish,
.base.onError = OnAccountError,
.base.fillDeviceAuthInfo = FillAccountAuthInfo,
.base.getAuthParamForServer = GetAccountAuthParamForServer,
.base.getReqParams = GetAccountReqParams,
.base.combineServerConfirmParams = CombineAccountServerConfirms,
.base.authType = ACCOUNT_RELATED_GROUP_AUTH_TYPE,
.getAccountCandidateGroup = GetAccountCandidateGroup,
};
static int32_t GetSessionKeyForAccount(const CJson *sendToSelf, CJson *returnToSelf)
{
int32_t keyLen = DEFAULT_RETURN_KEY_LENGTH;
uint8_t *sessionKey = (uint8_t *)HcMalloc(keyLen, 0);
if (sessionKey == NULL) {
LOGE("Failed to allocate memory for sessionKey!");
return HC_ERR_ALLOC_MEMORY;
}
int32_t res = HC_SUCCESS;
do {
if (GetByteFromJson(sendToSelf, FIELD_SESSION_KEY, sessionKey, keyLen) != HC_SUCCESS) {
LOGE("Failed to get sessionKey!");
res = HC_ERR_JSON_GET;
break;
}
if (AddByteToJson(returnToSelf, FIELD_SESSION_KEY, (const uint8_t *)sessionKey, keyLen) != HC_SUCCESS) {
LOGE("Failed to add sessionKey for onFinish!");
res = HC_ERR_JSON_FAIL;
break;
}
} while (0);
(void)memset_s(sessionKey, keyLen, 0, keyLen);
HcFree(sessionKey);
sessionKey = NULL;
return res;
}
static int32_t GetUserIdForAccount(const CJson *sendToSelf, CJson *returnToSelf)
{
const char *peerUserId = GetStringFromJson(sendToSelf, FIELD_USER_ID);
if (peerUserId == NULL) {
LOGE("Failed to get peer uid!");
return HC_ERR_JSON_GET;
}
if (AddStringToJson(returnToSelf, FIELD_USER_ID, peerUserId) != HC_SUCCESS) {
LOGE("Failed to add peer uid!");
return HC_ERR_JSON_FAIL;
}
return HC_SUCCESS;
}
static bool IsPeerInAccountRelatedGroup(const TrustedGroupEntry *groupEntry, const char *peerUserId)
{
const char *peerUserIdInDb = StringGet(&groupEntry->userId);
if (peerUserIdInDb == NULL) {
LOGD("Failed to get peer userId from db!");
return false;
}
if (IsUserIdEqual(peerUserIdInDb, peerUserId)) {
LOGI("[Account auth]: the input peer-userId is in one across group, add across-group auth!");
return true;
}
return false;
}
static bool IsPeerInIdenticalGroup(int32_t osAccountId, const char *peerUserId)
{
bool isGroupExist = false;
GroupEntryVec accountVec = CreateGroupEntryVec();
QueryGroupParams queryParams = InitQueryGroupParams();
queryParams.groupType = IDENTICAL_ACCOUNT_GROUP;
do {
if (QueryGroups(osAccountId, &queryParams, &accountVec) != HC_SUCCESS) {
LOGD("No identical-account group in db, no identical-account auth!");
break;
}
uint32_t index = 0;
TrustedGroupEntry **ptr = NULL;
while (index < accountVec.size(&accountVec)) {
ptr = accountVec.getp(&accountVec, index);
if ((ptr == NULL) || (*ptr == NULL)) {
index++;
continue;
}
if (IsPeerInAccountRelatedGroup(*ptr, peerUserId)) {
isGroupExist = true;
break;
}
}
} while (0);
ClearGroupEntryVec(&accountVec);
return isGroupExist;
}
static void GaGetAccountGroup(int32_t osAccountId, GroupType type, const char *peerUserId,
QueryGroupParams *queryParams, GroupEntryVec *vec)
{
LOGI("Try to get account group info, groupType: %d.", type);
queryParams->groupType = type;
if (QueryGroups(osAccountId, queryParams, vec) != HC_SUCCESS) {
LOGD("Database don't have local device's across-account group info!");
return;
}
uint32_t index = 0;
TrustedGroupEntry **ptr = NULL;
while (index < vec->size(vec)) {
ptr = vec->getp(vec, index);
if ((ptr == NULL) || (*ptr == NULL)) {
index++;
continue;
}
if ((peerUserId == NULL) || IsPeerInAccountRelatedGroup(*ptr, peerUserId)) {
index++;
continue;
}
TrustedGroupEntry *tempEntry = NULL;
HC_VECTOR_POPELEMENT(vec, &tempEntry, index);
DestroyGroupEntry((TrustedGroupEntry *)tempEntry);
}
LOGI("The candidate account group size is:%d.", vec->size(vec));
}
static void GetAccountCandidateGroup(int32_t osAccountId, const CJson *param,
QueryGroupParams *queryParams, GroupEntryVec *vec)
{
/* Compare userId with local uid in DB. */
bool identicalFlag = false;
bool acrossAccountFlag = false;
const char *peerUserId = GetStringFromJson(param, FIELD_USER_ID);
if (peerUserId != NULL) {
acrossAccountFlag = true;
identicalFlag = IsPeerInIdenticalGroup(osAccountId, peerUserId);
} else {
LOGD("userId is null in authParam.");
identicalFlag = true;
}
if (identicalFlag) {
GaGetAccountGroup(osAccountId, IDENTICAL_ACCOUNT_GROUP, peerUserId, queryParams, vec);
} else if (acrossAccountFlag) {
GaGetAccountGroup(osAccountId, ACROSS_ACCOUNT_AUTHORIZE_GROUP, peerUserId, queryParams, vec);
}
}
static int32_t FillAccountAuthInfo(int32_t osAccountId, const TrustedGroupEntry *entry,
const TrustedDeviceEntry *localAuthInfo, CJson *paramsData)
{
(void)osAccountId;
const char *selfUserId = StringGet(&entry->userId);
const char *selfDeviceId = StringGet(&(localAuthInfo->udid));
const char *selfDevId = StringGet(&(localAuthInfo->authId));
if (selfUserId == NULL || selfDeviceId == NULL || selfDevId == NULL) {
LOGE("Failed to get self account info for client in account-related auth!");
return HC_ERR_JSON_GET;
}
if (AddStringToJson(paramsData, FIELD_SELF_USER_ID, selfUserId) != HC_SUCCESS) {
LOGE("Failed to add self userId for client in account-related auth!");
return HC_ERR_JSON_FAIL;
}
if (AddStringToJson(paramsData, FIELD_SELF_DEVICE_ID, selfDeviceId) != HC_SUCCESS) {
LOGE("Failed to add self deviceId for client in account-related auth!");
return HC_ERR_JSON_FAIL;
}
if (AddStringToJson(paramsData, FIELD_SELF_DEV_ID, selfDevId) != HC_SUCCESS) {
LOGE("Failed to add self devId for client in account-related auth!");
return HC_ERR_JSON_FAIL;
}
return HC_SUCCESS;
}
static void OnAccountError(int64_t requestId, const AuthSession *session, int errorCode)
{
AuthSession *realSession = (AuthSession *)session;
const DeviceAuthCallback *callback = session->base.callback;
ParamsVec list = realSession->paramsList;
CJson *authParam = list.get(&list, realSession->currentIndex);
if (authParam == NULL) {
LOGE("The json data in session is null!");
return;
}
int32_t authForm = AUTH_FORM_INVALID_TYPE;
if (GetIntFromJson(authParam, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
LOGE("Failed to get auth type!");
return;
}
/* If there is alternative group, do not return error. */
const char *altGroup = GetStringFromJson(authParam, FIELD_ALTERNATIVE);
if ((realSession->currentIndex < (list.size(&list) - 1)) || (altGroup != NULL)) {
LOGI("There are alternative groups.");
return;
}
if ((callback != NULL) && (callback->onError != NULL)) {
LOGE("Invoke OnAccountError!");
callback->onError(requestId, authForm, errorCode, NULL);
}
}
static int32_t GetAccountReqParams(const CJson *receiveData, CJson *reqParam)
{
const char *peerUserId = GetStringFromJson(receiveData, FIELD_USER_ID);
if (peerUserId == NULL) {
LOGE("Failed to get peer uid for server!");
return HC_ERR_JSON_GET;
}
if (AddStringToJson(reqParam, FIELD_USER_ID, peerUserId) != HC_SUCCESS) {
LOGE("Failed to add peer uid!");
return HC_ERR_JSON_FAIL;
}
const char *peerDeviceId = GetStringFromJson(receiveData, FIELD_DEVICE_ID);
if (peerDeviceId == NULL) {
LOGE("Failed to get deviceId from the data transmitted by the client!");
return HC_ERR_JSON_GET;
}
if (AddStringToJson(reqParam, FIELD_DEVICE_ID, peerDeviceId) != HC_SUCCESS) {
LOGE("Failed to add reqParam: deviceId for onRequest!");
return HC_ERR_JSON_FAIL;
}
return HC_SUCCESS;
}
static int32_t AddSelfUserIdForServer(int32_t osAccountId, GroupEntryVec *accountVec, CJson *data)
{
const char *peerUserId = GetStringFromJson(data, FIELD_USER_ID);
if (peerUserId == NULL) {
LOGE("Failed to get peerUserId.");
return HC_ERR_JSON_GET;
}
int32_t authForm = AUTH_FORM_INVALID_TYPE;
if (GetIntFromJson(data, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
LOGE("Failed to get auth form for server!");
return HC_ERR_JSON_GET;
}
int32_t groupType = AuthFormToGroupType(authForm);
if (groupType == GROUP_TYPE_INVALID) {
LOGE("Invalid authForm, authForm = %d.", authForm);
return HC_ERR_INVALID_PARAMS;
}
QueryGroupParams queryParams = InitQueryGroupParams();
queryParams.groupType = groupType;
queryParams.userId = peerUserId;
int32_t res = QueryGroups(osAccountId, &queryParams, accountVec);
if ((res != HC_SUCCESS) || (accountVec->size(accountVec) == 0)) {
LOGE("Database don't have local device's account group info for server!");
return res;
}
TrustedGroupEntry *groupEntry = accountVec->get(accountVec, 0);
if (groupEntry == NULL) {
LOGE("Group info is null.");
return HC_ERR_GROUP_NOT_EXIST;
}
const char *selfUserId = StringGet(&groupEntry->userId);
if (AddStringToJson(data, FIELD_SELF_USER_ID, selfUserId) != HC_SUCCESS) {
LOGE("Failed to add self userId for server in account-related auth!");
return HC_ERR_JSON_FAIL;
}
return HC_SUCCESS;
}
static int32_t AddSelfDevIdForServer(int32_t osAccountId, GroupEntryVec *accountVec, CJson *data)
{
TrustedDeviceEntry *localDevInfo = CreateDeviceEntry();
if (localDevInfo == NULL) {
LOGE("Failed to allocate memory for localDevInfo for server!");
return HC_ERR_ALLOC_MEMORY;
}
TrustedGroupEntry *groupEntry = accountVec->get(accountVec, 0);
int32_t res;
do {
const char *groupId = StringGet(&groupEntry->id);
if (groupId == NULL) {
LOGE("Failed to get groupId for server!");
res = HC_ERR_NULL_PTR;
break;
}
res = GaGetLocalDeviceInfo(osAccountId, groupId, localDevInfo);
const char *selfDevId = StringGet(&(localDevInfo->authId));
if (AddStringToJson(data, FIELD_SELF_DEV_ID, selfDevId) != HC_SUCCESS) {
LOGE("Failed to add self devId for server in account-related auth!");
res = HC_ERR_JSON_FAIL;
}
} while (0);
DestroyDeviceEntry(localDevInfo);
return res;
}
static int32_t AddSelfAccountInfoForServer(CJson *data)
{
int32_t osAccountId = INVALID_OS_ACCOUNT;
if (GetIntFromJson(data, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
LOGE("Failed to get osAccountId for server!");
return HC_ERR_JSON_GET;
}
GroupEntryVec accountVec = CreateGroupEntryVec();
int32_t res = AddSelfUserIdForServer(osAccountId, &accountVec, data);
if (res != HC_SUCCESS) {
LOGE("Failed to add self userId for server auth!");
ClearGroupEntryVec(&accountVec);
return res;
}
res = AddSelfDevIdForServer(osAccountId, &accountVec, data);
ClearGroupEntryVec(&accountVec);
return res;
}
static int32_t CombineAccountServerConfirms(const CJson *confirmationJson, CJson *dataFromClient)
{
bool isClient = false;
if (AddBoolToJson(dataFromClient, FIELD_IS_CLIENT, isClient) != HC_SUCCESS) {
LOGE("Failed to combine server param for isClient!");
return HC_ERR_JSON_FAIL;
}
if (AddSelfAccountInfoForServer(dataFromClient) != HC_SUCCESS) {
LOGE("Failed to add account info for server!");
return HC_ERR_GROUP_NOT_EXIST;
}
const char *peerUdid = GetStringFromJson(confirmationJson, FIELD_PEER_CONN_DEVICE_ID);
if (peerUdid != NULL) {
if (AddStringToJson(dataFromClient, FIELD_PEER_CONN_DEVICE_ID, peerUdid) != HC_SUCCESS) {
LOGE("Failed to combine server param for peerUdid!");
return HC_ERR_JSON_FAIL;
}
}
const char *tempChallenge = GetStringFromJson(confirmationJson, FIELD_BLE_CHALLENGE);
if (tempChallenge != NULL) {
if (AddStringToJson(dataFromClient, FIELD_BLE_CHALLENGE, tempChallenge) != HC_SUCCESS) {
LOGE("Failed to combine server param for tempChallenge!");
return HC_ERR_JSON_FAIL;
}
}
return HC_SUCCESS;
}
static int32_t GetAccountAuthParamForServer(const CJson *dataFromClient, ParamsVec *authParamsVec)
{
LOGI("Begin get account-related auth params for server.");
const char *peerUserId = GetStringFromJson(dataFromClient, FIELD_USER_ID);
if (peerUserId == NULL) {
LOGE("Failed to get peer userId in client's payload!");
return HC_ERR_JSON_GET;
}
char *localUdid = (char *)HcMalloc(INPUT_UDID_LEN, 0);
if (localUdid == NULL) {
LOGE("Failed to malloc for local udid!");
return HC_ERR_ALLOC_MEMORY;
}
int32_t res = HcGetUdid((uint8_t *)localUdid, INPUT_UDID_LEN);
if (res != HC_SUCCESS) {
LOGE("[Account-related auth]: Failed to get self udid for server!");
HcFree(localUdid);
return res;
}
CJson *dupData = DuplicateJson(dataFromClient);
if (dupData == NULL) {
LOGE("Failed to create dupData for dataFromClient!");
HcFree(localUdid);
return HC_ERR_JSON_FAIL;
}
if (AddStringToJson(dupData, FIELD_SELF_DEVICE_ID, localUdid) != HC_SUCCESS) {
LOGE("Failed to add self udid for server in account-related auth!");
FreeJson(dupData);
HcFree(localUdid);
return HC_ERR_JSON_FAIL;
}
if (AddStringToJson(dupData, FIELD_GROUP_ID, peerUserId) != HC_SUCCESS) {
LOGE("Failed to add groupId for server in account-related auth!");
FreeJson(dupData);
HcFree(localUdid);
return HC_ERR_JSON_FAIL;
}
HcFree(localUdid);
if (authParamsVec->pushBack(authParamsVec, (const void **)&dupData) == NULL) {
LOGE("Failed to push json data to vector in account-related auth!");
FreeJson(dupData);
return HC_ERR_ALLOC_MEMORY;
}
return HC_SUCCESS;
}
static int32_t AccountOnFinishToPeer(int64_t requestId, const CJson *out, const DeviceAuthCallback *callback)
{
int32_t res = HC_SUCCESS;
const CJson *sendToPeer = GetObjFromJson(out, FIELD_SEND_TO_PEER);
if (sendToPeer == NULL) {
LOGI("No need to transmit data to peer for account-related auth.");
return res;
}
char *sendToPeerStr = PackJsonToString(sendToPeer);
if (sendToPeerStr == NULL) {
LOGE("Failed to pack sendToPeerStr!");
return HC_ERR_ALLOC_MEMORY;
}
if ((callback != NULL) && (callback->onTransmit != NULL)) {
LOGD("Begin to transmit data to peer for auth in AccountOnFinishToPeer.");
if (!callback->onTransmit(requestId, (uint8_t *)sendToPeerStr, HcStrlen(sendToPeerStr) + 1)) {
LOGE("Failed to transmit data to peer!");
res = HC_ERR_TRANSMIT_FAIL;
}
LOGD("End to transmit data to peer for auth in AccountOnFinishToPeer.");
}
FreeJsonString(sendToPeerStr);
return res;
}
static int32_t PrepareTrustedDeviceInfo(int32_t osAccountId, const CJson *authParam,
const CJson *out, TrustedDeviceEntry *devEntry)
{
const CJson *sendToSelf = GetObjFromJson(out, FIELD_SEND_TO_SELF);
if (sendToSelf == NULL) {
LOGE("Failed to get sendToSelf data for account!");
return HC_ERR_JSON_GET;
}
const char *peerUdid = GetStringFromJson(authParam, FIELD_PEER_CONN_DEVICE_ID);
if (peerUdid == NULL) {
LOGE("Failed to get peer udid for account!");
return HC_ERR_JSON_GET;
}
const char *peerAuthId = GetStringFromJson(sendToSelf, FIELD_DEV_ID);
if (peerAuthId == NULL) {
LOGE("Failed to get peer authId for account!");
return HC_ERR_JSON_GET;
}
const char *groupId = GetStringFromJson(authParam, FIELD_GROUP_ID);
if (groupId == NULL) {
LOGE("Failed to get groupId from auth params when adding device info!");
return HC_ERR_JSON_GET;
}
const char *peerUserId = GetStringFromJson(sendToSelf, FIELD_USER_ID);
if (peerUserId == NULL) {
LOGE("Failed to get peer userId!");
return HC_ERR_JSON_GET;
}
if (!StringSetPointer(&(devEntry->userId), peerUserId) ||
!StringSetPointer(&(devEntry->udid), peerUdid) ||
!StringSetPointer(&(devEntry->authId), peerAuthId) ||
!StringSetPointer(&(devEntry->groupId), groupId) ||
!StringSetPointer(&(devEntry->serviceType), groupId)) {
LOGE("Failed to add device info when adding a trusted device!");
return HC_ERR_MEMORY_COPY;
}
return HC_SUCCESS;
}
static int32_t DeleteExistedDeviceInfoInDb(int32_t osAccountId, const CJson *authParam)
{
const char *peerUdid = GetStringFromJson(authParam, FIELD_PEER_CONN_DEVICE_ID);
if (peerUdid == NULL) {
LOGE("Failed to get peer udid!");
return HC_ERR_JSON_GET;
}
const char *groupId = GetStringFromJson(authParam, FIELD_GROUP_ID);
if (groupId == NULL) {
LOGE("Failed to get groupId from auth params when deleting device info!");
return HC_ERR_JSON_GET;
}
QueryDeviceParams devParams = InitQueryDeviceParams();
devParams.groupId = groupId;
devParams.udid = peerUdid;
int32_t result = DelTrustedDevice(osAccountId, &devParams);
if (result != HC_SUCCESS) {
LOGE("Failed to delete peer device from database!");
return result;
}
return HC_SUCCESS;
}
static int32_t AddTrustedDeviceForAccount(const CJson *authParam, const CJson *out)
{
int32_t osAccountId = ANY_OS_ACCOUNT;
if (GetIntFromJson(authParam, FIELD_OS_ACCOUNT_ID, &osAccountId) != HC_SUCCESS) {
LOGE("Failed to get osAccountId for account!");
return HC_ERR_JSON_GET;
}
int32_t res = DeleteExistedDeviceInfoInDb(osAccountId, authParam);
if (res != HC_SUCCESS) {
LOGE("Failed to delete the existed account device in db!");
return res;
}
TrustedDeviceEntry *devEntry = CreateDeviceEntry();
if (devEntry == NULL) {
LOGE("Failed to allocate device entry memory!");
return HC_ERR_ALLOC_MEMORY;
}
do {
res = PrepareTrustedDeviceInfo(osAccountId, authParam, out, devEntry);
if (res != HC_SUCCESS) {
LOGE("Failed to prepare trust device params!");
break;
}
res = AddTrustedDevice(osAccountId, devEntry);
if (res != HC_SUCCESS) {
LOGE("Failed to add trusted devices for account to database!");
break;
}
} while (0);
DestroyDeviceEntry(devEntry);
return res;
}
static int32_t PrepareAccountDataToSelf(const CJson *sendToSelf, CJson *returnToSelf)
{
int32_t res = GetSessionKeyForAccount(sendToSelf, returnToSelf);
if (res != HC_SUCCESS) {
LOGE("Failed to get session key info for account auth!");
return res;
}
res = GetUserIdForAccount(sendToSelf, returnToSelf);
if (res != HC_SUCCESS) {
LOGE("Failed to get user id for account auth!");
}
return res;
}
static int32_t AccountOnFinishToSelf(int64_t requestId, const CJson *authParam, const CJson *out,
const DeviceAuthCallback *callback)
{
const CJson *sendToSelf = GetObjFromJson(out, FIELD_SEND_TO_SELF);
if (sendToSelf == NULL) {
LOGE("No data to send to self for onFinish.");
return HC_ERR_LOST_DATA;
}
CJson *returnToSelf = CreateJson();
if (returnToSelf == NULL) {
LOGE("Failed to create json for account-related auth in onFinish!");
return HC_ERR_ALLOC_MEMORY;
}
int32_t res = PrepareAccountDataToSelf(sendToSelf, returnToSelf);
if (res != HC_SUCCESS) {
LOGE("Failed to add account-related returnToSelf data!");
ClearSensitiveStringInJson(returnToSelf, FIELD_SESSION_KEY);
FreeJson(returnToSelf);
return res;
}
char *returnStr = PackJsonToString(returnToSelf);
ClearSensitiveStringInJson(returnToSelf, FIELD_SESSION_KEY);
FreeJson(returnToSelf);
if (returnStr == NULL) {
LOGE("Failed to pack return data to string!");
return HC_ERR_ALLOC_MEMORY;
}
do {
int32_t authForm = AUTH_FORM_INVALID_TYPE;
if (GetIntFromJson(authParam, FIELD_AUTH_FORM, &authForm) != HC_SUCCESS) {
LOGE("Failed to get auth type!");
res = HC_ERR_JSON_GET;
break;
}
if ((callback != NULL) && (callback->onFinish != NULL)) {
LOGD("Group auth call onFinish for account related auth.");
callback->onFinish(requestId, authForm, returnStr);
}
} while (0);
ClearAndFreeJsonString(returnStr);
return res;
}
static void OnAccountFinish(int64_t requestId, const CJson *authParam, const CJson *out,
const DeviceAuthCallback *callback)
{
LOGI("Begin call onFinish for account-related auth.");
if (AccountOnFinishToPeer(requestId, out, callback) != HC_SUCCESS) {
LOGE("Failed to send data to peer when account-related auth finished!");
return;
}
if (ReturnSessionKey(requestId, authParam, out, callback) != HC_SUCCESS) {
LOGE("Failed to return session key for account-related auth!");
return;
}
if (AddTrustedDeviceForAccount(authParam, out) != HC_SUCCESS) {
LOGD("Failed to add peer trusted devices to database for account-related auth!");
}
if (AccountOnFinishToSelf(requestId, authParam, out, callback) != HC_SUCCESS) {
LOGE("Failed to send data to self when account-related auth finished!");
return;
}
LOGI("Call onFinish for account-related auth successfully.");
}
BaseGroupAuth *GetAccountRelatedGroupAuth(void)
{
return (BaseGroupAuth *)&g_accountRelatedGroupAuth;
}
@@ -18,8 +18,10 @@
#include "common_defs.h"
#include "device_auth.h"
#include "device_auth_defines.h"
#include "hc_dev_info.h"
#include "hc_log.h"
#include "hc_string.h"
#include "hc_types.h"
#include "hc_vector.h"
static bool GaDeepCopyDeviceEntry(const TrustedDeviceEntry *entry, TrustedDeviceEntry *returnEntry)
@@ -41,8 +43,8 @@ static bool GaDeepCopyDeviceEntry(const TrustedDeviceEntry *entry, TrustedDevice
LOGE("[GA]: Failed to copy serviceType!");
return false;
}
if (!StringSet(&returnEntry->userIdHash, entry->userIdHash)) {
LOGE("[GA]: Failed to copy userIdHash!");
if (!StringSet(&returnEntry->userId, entry->userId)) {
LOGE("[GA]: Failed to copy userId!");
return false;
}
returnEntry->credential = entry->credential;
@@ -66,8 +68,8 @@ static bool GaDeepCopyGroupEntry(const TrustedGroupEntry *entry, TrustedGroupEnt
LOGE("[GA]: Failed to copy groupId!");
return false;
}
if (!StringSet(&returnEntry->userIdHash, entry->userIdHash)) {
LOGE("[GA]: Failed to copy userIdHash!");
if (!StringSet(&returnEntry->userId, entry->userId)) {
LOGE("[GA]: Failed to copy userId!");
return false;
}
returnEntry->type = entry->type;
@@ -235,4 +237,25 @@ bool GaIsDeviceInGroup(int32_t groupType, int32_t osAccountId, const char *peerU
return false;
}
return true;
}
int32_t GaGetLocalDeviceInfo(int32_t osAccountId, const char *groupId, TrustedDeviceEntry *localAuthInfo)
{
char *localUdid = (char *)HcMalloc(INPUT_UDID_LEN, 0);
if (localUdid == NULL) {
LOGE("Failed to malloc for local udid!");
return HC_ERR_ALLOC_MEMORY;
}
int32_t res = HcGetUdid((uint8_t *)localUdid, INPUT_UDID_LEN);
if (res != HC_SUCCESS) {
LOGE("Failed to get local udid!");
HcFree(localUdid);
return res;
}
res = GaGetTrustedDeviceEntryById(osAccountId, localUdid, true, groupId, localAuthInfo);
HcFree(localUdid);
if (res != HC_SUCCESS) {
LOGE("Failed to get local device info from database!");
}
return res;
}
@@ -119,29 +119,6 @@ static int32_t AddGeneralParams(const char *groupId, int32_t groupType, const Tr
return HC_SUCCESS;
}
static int32_t GetLocalDeviceInfoFromDatabase(int32_t osAccountId, const char *groupId,
TrustedDeviceEntry *localAuthInfo)
{
char *localUdid = (char *)HcMalloc(INPUT_UDID_LEN, 0);
if (localUdid == NULL) {
LOGE("Failed to malloc for local udid!");
return HC_ERR_ALLOC_MEMORY;
}
int32_t res = HcGetUdid((uint8_t *)localUdid, INPUT_UDID_LEN);
if (res != HC_SUCCESS) {
LOGE("[DB]: Failed to get local udid! res: %d", res);
HcFree(localUdid);
return res;
}
res = GaGetTrustedDeviceEntryById(osAccountId, localUdid, true, groupId, localAuthInfo);
HcFree(localUdid);
if (res != HC_SUCCESS) {
LOGE("Failed to get local device info from database!");
}
return res;
}
static int32_t ExtractAndAddParams(int32_t osAccountId, const char *groupId,
const TrustedGroupEntry *groupInfo, CJson *paramsData)
{
@@ -154,7 +131,7 @@ static int32_t ExtractAndAddParams(int32_t osAccountId, const char *groupId,
int32_t groupType = groupInfo->type;
int32_t authForm = GroupTypeToAuthForm(groupType);
do {
res = GetLocalDeviceInfoFromDatabase(osAccountId, groupId, localAuthInfo);
res = GaGetLocalDeviceInfo(osAccountId, groupId, localAuthInfo);
if (res != HC_SUCCESS) {
break;
}
@@ -227,7 +204,7 @@ static void GetCandidateGroupByOrder(int32_t osAccountId, const CJson *param,
BaseGroupAuth *groupAuth = GetGroupAuth(ACCOUNT_RELATED_GROUP_AUTH_TYPE);
if (groupAuth != NULL) {
AccountRelatedGroupAuth *realGroupAuth = (AccountRelatedGroupAuth *)groupAuth;
realGroupAuth->getAccountCandidateGroup(param, queryParams, vec);
realGroupAuth->getAccountCandidateGroup(osAccountId, param, queryParams, vec);
}
queryParams->groupType = PEER_TO_PEER_GROUP;
if (QueryGroups(osAccountId, queryParams, vec) != HC_SUCCESS) {
@@ -767,14 +744,16 @@ int32_t ProcessTaskStatusForAuth(const AuthSession *session, const CJson *param,
int32_t CreateAndProcessTask(AuthSession *session, CJson *paramInSession, CJson *out, int32_t *status)
{
int32_t moduleType = GetAuthModuleType(paramInSession);
const char *pkgName = GetStringFromJson(paramInSession, FIELD_SERVICE_PKG_NAME);
if (pkgName == NULL) {
LOGE("Pkg name is null!");
return HC_ERR_NULL_PTR;
}
if (AddStringToJson(paramInSession, FIELD_PKG_NAME, pkgName) != HC_SUCCESS) {
LOGE("Failed to add pkg name to json!");
return HC_ERR_JSON_FAIL;
if (moduleType == DAS_MODULE) {
const char *pkgName = GetStringFromJson(paramInSession, FIELD_SERVICE_PKG_NAME);
if (pkgName == NULL) {
LOGE("Pkg name is null!");
return HC_ERR_NULL_PTR;
}
if (AddStringToJson(paramInSession, FIELD_PKG_NAME, pkgName) != HC_SUCCESS) {
LOGE("Failed to add pkg name to json!");
return HC_ERR_JSON_FAIL;
}
}
session->curTaskId = 0;
int32_t res = CreateTask(&(session->curTaskId), paramInSession, out, moduleType);
@@ -136,4 +136,25 @@ int32_t GroupTypeToAuthForm(int32_t groupType)
break;
}
return authForm;
}
int32_t AuthFormToGroupType(int32_t authForm)
{
int32_t groupType;
switch (authForm) {
case AUTH_FORM_ACCOUNT_UNRELATED:
groupType = PEER_TO_PEER_GROUP;
break;
case AUTH_FORM_IDENTICAL_ACCOUNT:
groupType = IDENTICAL_ACCOUNT_GROUP;
break;
case AUTH_FORM_ACROSS_ACCOUNT:
groupType = ACROSS_ACCOUNT_AUTHORIZE_GROUP;
break;
default:
LOGE("Invalid auth form!");
groupType = GROUP_TYPE_INVALID;
break;
}
return groupType;
}
@@ -19,13 +19,13 @@
#include "device_auth_defines.h"
#include "hc_log.h"
#include "hc_types.h"
#define UID_HASH_HEX_STRING_LEN_MAX 64
#define UID_HASH_HEX_STRING_LEN_MIN 10
#define UID_HEX_STRING_LEN_MAX 64
#define UID_HEX_STRING_LEN_MIN 10
static bool IsPeerUidHashLenValid(uint32_t peerUidHashLen)
static bool IsPeerUidLenValid(uint32_t peerUserIdLen)
{
if ((peerUidHashLen < UID_HASH_HEX_STRING_LEN_MIN) || (peerUidHashLen > UID_HASH_HEX_STRING_LEN_MAX)) {
LOGE("The input uid hash len is invalid, input uid hash in hex string len = %d", peerUidHashLen);
if ((peerUserIdLen < UID_HEX_STRING_LEN_MIN) || (peerUserIdLen > UID_HEX_STRING_LEN_MAX)) {
LOGE("The input userId len is invalid, input userId in hex string len = %d", peerUserIdLen);
return false;
}
return true;
@@ -143,32 +143,31 @@ int32_t GetGeneralReqParams(const CJson *receiveData, CJson *reqParam)
return HC_SUCCESS;
}
bool IsUidHashEqual(const char *uidHashInDb, const char *peerUidHash)
bool IsUserIdEqual(const char *userIdInDb, const char *peerUserIdInDb)
{
if ((uidHashInDb == NULL) || (peerUidHash == NULL)) {
LOGE("Input is null for uid hash!");
if ((userIdInDb == NULL) || (peerUserIdInDb == NULL)) {
LOGE("Input is null for user id!");
return false;
}
char *peerUidHashToUpper = NULL;
int32_t result = ToUpperCase(peerUidHash, &peerUidHashToUpper);
if (result != HC_SUCCESS) {
LOGE("Failed to convert the input uidHash to upper case!");
return result;
}
uint32_t uidHashInDbLen = strlen(uidHashInDb);
uint32_t peerUidHashLen = strlen(peerUidHash);
if (!IsPeerUidHashLenValid(peerUidHashLen)) {
HcFree(peerUidHashToUpper);
peerUidHashToUpper = NULL;
char *peerUidToUpper = NULL;
if (ToUpperCase(peerUserIdInDb, &peerUidToUpper) != HC_SUCCESS) {
LOGE("Failed to convert the input userId to upper case!");
return false;
}
uint32_t cmpHashLen = (uidHashInDbLen > peerUidHashLen) ? peerUidHashLen : uidHashInDbLen;
if (memcmp(uidHashInDb, peerUidHashToUpper, cmpHashLen) == EOK) {
HcFree(peerUidHashToUpper);
peerUidHashToUpper = NULL;
uint32_t userIdInDbLen = HcStrlen(userIdInDb);
uint32_t peerUserIdLen = HcStrlen(peerUserIdInDb);
if (!IsPeerUidLenValid(peerUserIdLen)) {
HcFree(peerUidToUpper);
peerUidToUpper = NULL;
return false;
}
uint32_t cmpLen = (userIdInDbLen > peerUserIdLen) ? peerUserIdLen : userIdInDbLen;
if (memcmp(userIdInDb, peerUidToUpper, cmpLen) == EOK) {
HcFree(peerUidToUpper);
peerUidToUpper = NULL;
return true;
}
HcFree(peerUidHashToUpper);
peerUidHashToUpper = NULL;
HcFree(peerUidToUpper);
peerUidToUpper = NULL;
return false;
}
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Copyright (C) 2021-2022 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
@@ -24,9 +24,6 @@ extern "C" {
typedef struct {
BaseGroup base;
int32_t (*syncGroup)(const char *appId, const char *userIdHash, const char *deviceId,
const CJson *sharedUserIdHashList);
int32_t (*generateGroupId)(const char *userIdHash, const char *sharedUserIdHash, char **returnGroupId);
} AcrossAccountGroup;
bool IsAcrossAccountGroupSupported(void);
@@ -32,10 +32,6 @@ int32_t AddMemberToGroupImpl(int32_t osAccountId, int64_t requestId, const char
int32_t DeleteMemberFromGroupImpl(int32_t osAccountId, int64_t requestId, const char *appId, const char *deleteParams);
int32_t ProcessBindDataImpl(int64_t requestId, const uint8_t *data, uint32_t dataLen);
int32_t ConfirmRequestImpl(int32_t osAccountId, int64_t requestId, const char *appId, const char *confirmParams);
int32_t GenerateAccountGroupIdImpl(int32_t groupType, const char *userIdHash, const char *sharedUserIdHash,
char **returnGroupId);
int32_t SyncAcrossAccountGroupImpl(const char *appId, const char *userIdHash, const char *deviceId,
const CJson *sharedUserIdHashList);
int32_t AddGroupManagerImpl(int32_t osAccountId, const char *appId, const char *groupId, const char *managerAppId);
int32_t AddGroupFriendImpl(int32_t osAccountId, const char *appId, const char *groupId, const char *friendAppId);
int32_t DeleteGroupManagerImpl(int32_t osAccountId, const char *appId, const char *groupId, const char *managerAppId);
@@ -30,10 +30,6 @@ typedef struct {
int32_t (*deleteMember)(int32_t osAccountId, int64_t requestId, const char *appId, const char *deleteParams);
int32_t (*processBindData)(int64_t requestId, const uint8_t *data, uint32_t dataLen);
int32_t (*confirmRequest)(int32_t osAccountId, int64_t requestId, const char *appId, const char *confirmParams);
int32_t (*generateAccountGroupId)(int32_t groupType, const char *userIdHash, const char *sharedUserIdHash,
char **returnGroupId);
int32_t (*syncAcrossAccountGroup)(const char *appId, const char *userIdHash, const char *deviceId,
const CJson *sharedUserIdHashList);
int32_t (*addGroupRole)(int32_t osAccountId, bool isManager, const char *appId, const char *groupId,
const char *roleAppId);
int32_t (*deleteGroupRole)(int32_t osAccountId, bool isManager, const char *appId, const char *groupId,
@@ -35,7 +35,8 @@ bool IsGroupVisibilityValid(int groupVisibility);
int32_t ProcessKeyPair(int action, const CJson *jsonParams, const char *groupId);
int32_t GetHashMessage(const Uint8Buff *first, const Uint8Buff *second, uint8_t **hashMessage, uint32_t *messageSize);
int32_t AssertUserIdHashExist(const CJson *jsonParams);
int32_t AssertUserIdExist(const CJson *jsonParams);
int32_t AssertSharedUserIdExist(const CJson *jsonParams);
int32_t CheckGroupExist(int32_t osAccountId, const char *groupId);
int32_t CheckGroupNumLimit(int32_t osAccountId, int32_t groupType, const char *appId);
int32_t CheckDeviceNumLimit(int32_t osAccountId, const char *groupId, const char *peerUdid);
@@ -50,14 +51,15 @@ int32_t AddGroupOwnerToParams(const char *owner, TrustedGroupEntry *groupParams)
int32_t AddGroupTypeToParams(int groupType, TrustedGroupEntry *groupParams);
int32_t AddGroupVisibilityOrDefault(const CJson *jsonParams, TrustedGroupEntry *groupParams);
int32_t AddExpireTimeOrDefault(const CJson *jsonParams, TrustedGroupEntry *groupParams);
int32_t AddUserIdHashToGroupParams(const CJson *jsonParams, TrustedGroupEntry *groupParams);
int32_t AddUserIdToGroupParams(const CJson *jsonParams, TrustedGroupEntry *groupParams);
int32_t AddSharedUserIdToGroupParams(const CJson *jsonParams, TrustedGroupEntry *groupParams);
int32_t AddUdidToParams(TrustedDeviceEntry *devParams);
int32_t AddAuthIdToParamsOrDefault(const CJson *jsonParams, TrustedDeviceEntry *devParams);
int32_t AddUserTypeToParamsOrDefault(const CJson *jsonParams, TrustedDeviceEntry *devParams);
int32_t AddServiceTypeToParams(const char *groupId, TrustedDeviceEntry *devParams);
int32_t AddGroupIdToDevParams(const char *groupId, TrustedDeviceEntry *devParams);
int32_t AddUserIdHashToDevParams(const CJson *jsonParams, TrustedDeviceEntry *devParams);
int32_t AddUserIdToDevParams(const CJson *jsonParams, TrustedDeviceEntry *devParams);
int32_t AddGroupToDatabaseByJson(int32_t osAccountId, int32_t (*generateGroupParams)(const CJson*,
const char *, TrustedGroupEntry*), const CJson *jsonParams, const char *groupId);
@@ -70,7 +72,8 @@ int32_t GenerateBindSuccessData(const char *peerAuthId, const char *groupId, cha
int32_t GenerateUnbindSuccessData(const char *peerAuthId, const char *groupId, char **returnDataStr);
int32_t GetGroupTypeFromDb(int32_t osAccountId, const char *groupId, int32_t *returnGroupType);
int32_t GetUserIdHashFromJson(const CJson *jsonParams, char **userIdHash);
int32_t GetUserIdFromJson(const CJson *jsonParams, char **userId);
int32_t GetSharedUserIdFromJson(const CJson *jsonParams, char **sharedUserId);
int32_t GetGroupIdFromJson(const CJson *jsonParams, const char **groupId);
int32_t GetAppIdFromJson(const CJson *jsonParams, const char **appId);
@@ -138,7 +138,8 @@ int32_t RequestBindPeer(int64_t requestId, const char *appId, const char *bindPa
FreeJson(params);
return HC_ERR_JSON_FAIL;
}
if (InitAndPushGMTask(OP_BIND, requestId, params, DoClientTask) != HC_SUCCESS) {
int32_t osAccountId = ANY_OS_ACCOUNT;
if (InitAndPushGMTask(osAccountId, OP_BIND, requestId, params, DoClientTask) != HC_SUCCESS) {
FreeJson(params);
return HC_ERR_INIT_TASK_FAIL;
}
@@ -162,7 +163,8 @@ int32_t RequestUnbindPeer(int64_t requestId, const char *appId, const char *unbi
FreeJson(params);
return HC_ERR_JSON_FAIL;
}
if (InitAndPushGMTask(OP_UNBIND, requestId, params, DoClientTask) != HC_SUCCESS) {
int32_t osAccountId = ANY_OS_ACCOUNT;
if (InitAndPushGMTask(osAccountId, OP_UNBIND, requestId, params, DoClientTask) != HC_SUCCESS) {
FreeJson(params);
return HC_ERR_INIT_TASK_FAIL;
}
@@ -186,7 +188,8 @@ int32_t RequestProcessLiteData(int64_t requestId, const char *appId, const uint8
FreeJson(params);
return HC_ERR_JSON_FAIL;
}
if (InitAndPushGMTask(GetOpCodeWhenLite(params), requestId, params, DoServerTask) != HC_SUCCESS) {
int32_t osAccountId = ANY_OS_ACCOUNT;
if (InitAndPushGMTask(osAccountId, GetOpCodeWhenLite(params), requestId, params, DoServerTask) != HC_SUCCESS) {
FreeJson(params);
return HC_ERR_INIT_TASK_FAIL;
}
@@ -56,20 +56,6 @@ int32_t ConfirmRequestImpl(int32_t osAccountId, int64_t requestId, const char *a
confirmParams) : HC_ERR_NOT_SUPPORT;
}
int32_t GenerateAccountGroupIdImpl(int32_t groupType, const char *userIdHash, const char *sharedUserIdHash,
char **returnGroupId)
{
return IsGroupSupport() ? GetGroupImplInstance()->generateAccountGroupId(groupType, userIdHash, sharedUserIdHash,
returnGroupId) : HC_ERR_NOT_SUPPORT;
}
int32_t SyncAcrossAccountGroupImpl(const char *appId, const char *userIdHash, const char *deviceId,
const CJson *sharedUserIdHashList)
{
return IsGroupSupport() ? GetGroupImplInstance()->syncAcrossAccountGroup(appId, userIdHash, deviceId,
sharedUserIdHashList) : HC_ERR_NOT_SUPPORT;
}
int32_t AddGroupManagerImpl(int32_t osAccountId, const char *appId, const char *groupId, const char *managerAppId)
{
return IsGroupSupport() ? GetGroupImplInstance()->addGroupRole(osAccountId, true, appId, groupId,
@@ -0,0 +1,265 @@
/*
* Copyright (C) 2022 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 "across_account_group.h"
#include "alg_defs.h"
#include "callback_manager.h"
#include "common_defs.h"
#include "data_manager.h"
#include "device_auth_defines.h"
#include "group_operation_common.h"
#include "hc_log.h"
#include "string_util.h"
/* 1: s1 > s2, -1: s1 <= s2 */
static int32_t CompareString(const char *s1, const char *s2)
{
if ((s1 == NULL) || (s2 == NULL)) {
LOGE("The input string contains NULL value!");
return 0;
}
const char *tempChar1 = s1;
const char *tempChar2 = s2;
while ((*tempChar1 != '\0') && (*tempChar2 != '\0')) {
if (*tempChar1 > *tempChar2) {
return 1;
} else if (*tempChar1 < *tempChar2) {
return -1;
}
tempChar1++;
tempChar2++;
}
if (*tempChar1 != '\0') {
return 1;
}
return -1;
}
static int32_t GenerateGroupId(const char *userId, const char *sharedUserId, char **returnGroupId)
{
/* across account group: groupId = sha256(userId1 | userId2) */
uint8_t *hashMessage = NULL;
uint32_t messageSize = 0;
const char *firstUserId = userId;
const char *secondUserId = sharedUserId;
if (CompareString(firstUserId, secondUserId) > 0) {
firstUserId = sharedUserId;
secondUserId = userId;
}
Uint8Buff firstUserIdBuff = { (uint8_t *)firstUserId, HcStrlen(firstUserId) };
Uint8Buff secondUserIdBuff = { (uint8_t *)secondUserId, HcStrlen(secondUserId) };
int32_t result = GetHashMessage(&firstUserIdBuff, &secondUserIdBuff, &hashMessage, &messageSize);
if (result != HC_SUCCESS) {
return result;
}
int hashStrLen = SHA256_LEN * BYTE_TO_HEX_OPER_LENGTH + 1;
*returnGroupId = (char *)HcMalloc(hashStrLen, 0);
if (*returnGroupId == NULL) {
LOGE("Failed to allocate returnGroupId memory!");
HcFree(hashMessage);
return HC_ERR_ALLOC_MEMORY;
}
result = GetHashResult(hashMessage, messageSize, *returnGroupId, hashStrLen);
HcFree(hashMessage);
if (result != HC_SUCCESS) {
LOGE("Failed to get hash for groupId!");
HcFree(*returnGroupId);
*returnGroupId = NULL;
return HC_ERR_HASH_FAIL;
}
return HC_SUCCESS;
}
static int32_t GenerateDevParams(const CJson *jsonParams, const char *groupId, TrustedDeviceEntry *devParams)
{
int32_t result;
if (((result = AddUdidToParams(devParams)) != HC_SUCCESS) ||
((result = AddAuthIdToParamsOrDefault(jsonParams, devParams)) != HC_SUCCESS) ||
((result = AddUserIdToDevParams(jsonParams, devParams)) != HC_SUCCESS) ||
((result = AddUserTypeToParamsOrDefault(jsonParams, devParams)) != HC_SUCCESS) ||
((result = AddGroupIdToDevParams(groupId, devParams)) != HC_SUCCESS) ||
((result = AddServiceTypeToParams(groupId, devParams)) != HC_SUCCESS)) {
return result;
}
return HC_SUCCESS;
}
static int32_t GenerateGroupParams(const CJson *jsonParams, const char *groupId, TrustedGroupEntry *groupParams)
{
const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
if (appId == NULL) {
LOGE("Failed to get appId from jsonParams!");
return HC_ERR_JSON_GET;
}
int32_t result;
if (((result = AddGroupTypeToParams(ACROSS_ACCOUNT_AUTHORIZE_GROUP, groupParams)) != HC_SUCCESS) ||
((result = AddGroupNameToParams(groupId, groupParams)) != HC_SUCCESS) ||
((result = AddGroupIdToParams(groupId, groupParams)) != HC_SUCCESS) ||
((result = AddUserIdToGroupParams(jsonParams, groupParams)) != HC_SUCCESS) ||
((result = AddSharedUserIdToGroupParams(jsonParams, groupParams)) != HC_SUCCESS) ||
((result = AddGroupOwnerToParams(appId, groupParams)) != HC_SUCCESS) ||
((result = AddGroupVisibilityOrDefault(jsonParams, groupParams)) != HC_SUCCESS) ||
((result = AddExpireTimeOrDefault(jsonParams, groupParams)) != HC_SUCCESS)) {
return result;
}
return HC_SUCCESS;
}
static int32_t GenerateAcrossAccountGroupId(const CJson *jsonParams, char **returnGroupId)
{
char *userId = NULL;
char *sharedUserId = NULL;
int32_t result = GetUserIdFromJson(jsonParams, &userId);
if (result != HC_SUCCESS) {
return result;
}
result = GetSharedUserIdFromJson(jsonParams, &sharedUserId);
if (result != HC_SUCCESS) {
HcFree(userId);
return result;
}
result = GenerateGroupId(userId, sharedUserId, returnGroupId);
HcFree(userId);
HcFree(sharedUserId);
if (result != HC_SUCCESS) {
LOGE("Failed to generate groupId!");
return result;
}
return HC_SUCCESS;
}
static int32_t AssertIdenticalGroupExist(int32_t osAccountId, const CJson *jsonParams)
{
char *userId = NULL;
int32_t result = GetUserIdFromJson(jsonParams, &userId);
if (result != HC_SUCCESS) {
return result;
}
GroupEntryVec groupEntryVec = CreateGroupEntryVec();
QueryGroupParams params = InitQueryGroupParams();
params.groupType = IDENTICAL_ACCOUNT_GROUP;
result = QueryGroups(osAccountId, &params, &groupEntryVec);
if (result != HC_SUCCESS) {
LOGE("Failed to query groups!");
HcFree(userId);
ClearGroupEntryVec(&groupEntryVec);
return result;
}
bool isExist = false;
uint32_t index;
TrustedGroupEntry **entry = NULL;
FOR_EACH_HC_VECTOR(groupEntryVec, index, entry) {
if ((entry != NULL) && (*entry != NULL) && (strcmp(userId, StringGet(&((*entry)->userId))) == 0)) {
isExist = true;
break;
}
}
HcFree(userId);
ClearGroupEntryVec(&groupEntryVec);
if (!isExist) {
LOGE("The identical account group has not been created!");
return HC_ERR_GROUP_NOT_EXIST;
}
return HC_SUCCESS;
}
static int32_t CheckCreateParams(int32_t osAccountId, const CJson *jsonParams)
{
const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
if (appId == NULL) {
LOGE("Failed to get appId from jsonParams!");
return HC_ERR_JSON_GET;
}
int32_t result;
if (((result = CheckUserTypeIfExist(jsonParams)) != HC_SUCCESS) ||
((result = CheckGroupVisibilityIfExist(jsonParams)) != HC_SUCCESS) ||
((result = CheckExpireTimeIfExist(jsonParams)) != HC_SUCCESS) ||
((result = AssertUserIdExist(jsonParams)) != HC_SUCCESS) ||
((result = AssertSharedUserIdExist(jsonParams)) != HC_SUCCESS) ||
((result = AssertIdenticalGroupExist(osAccountId, jsonParams)) != HC_SUCCESS)) {
return result;
}
return HC_SUCCESS;
}
static int32_t CreateGroupInner(int32_t osAccountId, const CJson *jsonParams, char **returnGroupId)
{
char *groupId = NULL;
int32_t result;
if (((result = CheckCreateParams(osAccountId, jsonParams)) != HC_SUCCESS) ||
((result = GenerateAcrossAccountGroupId(jsonParams, &groupId)) != HC_SUCCESS) ||
((result = AddGroupToDatabaseByJson(osAccountId, GenerateGroupParams, jsonParams, groupId)) != HC_SUCCESS) ||
((result = AddDeviceToDatabaseByJson(osAccountId, GenerateDevParams, jsonParams, groupId)) != HC_SUCCESS) ||
((result = SaveOsAccountDb(osAccountId)) != HC_SUCCESS)) {
HcFree(groupId);
return result;
}
*returnGroupId = groupId;
return HC_SUCCESS;
}
static int32_t CreateGroup(int32_t osAccountId, CJson *jsonParams, char **returnJsonStr)
{
LOGI("[Start]: Start to create a across account group!");
if ((jsonParams == NULL) || (returnJsonStr == NULL)) {
LOGE("The input parameters contains NULL value!");
return HC_ERR_INVALID_PARAMS;
}
char *groupId = NULL;
int32_t result;
if (((result = CreateGroupInner(osAccountId, jsonParams, &groupId)) != HC_SUCCESS) ||
((result = ConvertGroupIdToJsonStr(groupId, returnJsonStr)) != HC_SUCCESS)) {
HcFree(groupId);
return result;
}
HcFree(groupId);
LOGI("[End]: Create a across account group successfully!");
return HC_SUCCESS;
}
static int32_t DeleteGroup(int32_t osAccountId, CJson *jsonParams, char **returnJsonStr)
{
LOGI("[Start]: Start to delete a across account group!");
if ((jsonParams == NULL) || (returnJsonStr == NULL)) {
LOGE("The input parameters contains NULL value!");
return HC_ERR_INVALID_PARAMS;
}
int32_t result;
const char *groupId = NULL;
if (((result = GetGroupIdFromJson(jsonParams, &groupId)) != HC_SUCCESS) ||
((result = DelGroupFromDb(osAccountId, groupId)) != HC_SUCCESS) ||
((result = ConvertGroupIdToJsonStr(groupId, returnJsonStr)) != HC_SUCCESS)) {
return result;
}
LOGI("[End]: Delete a across account group successfully!");
return HC_SUCCESS;
}
static AcrossAccountGroup g_acrossAccountGroup = {
.base.type = ACROSS_ACCOUNT_AUTHORIZE_GROUP,
.base.createGroup = CreateGroup,
.base.deleteGroup = DeleteGroup,
};
BaseGroup *GetAcrossAccountGroupInstance(void)
{
return (BaseGroup *)&g_acrossAccountGroup;
}
bool IsAcrossAccountGroupSupported(void)
{
return true;
}
@@ -484,48 +484,6 @@ static int32_t ProcessBindData(int64_t requestId, CJson *jsonParams, const Devic
return instance->processData(requestId, jsonParams, callback);
}
static int32_t GenerateAccountGroupId(int32_t groupType, const char *userIdHash, const char *sharedUserIdHash,
char **returnGroupId)
{
if ((!IsAccountRelatedGroup(groupType)) || (!IsGroupTypeSupported(groupType))) {
LOGE("This type of group is not supported!");
return HC_ERR_INVALID_PARAMS;
}
if (groupType == IDENTICAL_ACCOUNT_GROUP) {
IdenticalAccountGroup *instance = (IdenticalAccountGroup *)GetIdenticalAccountGroupInstance();
if ((instance == NULL) || (instance->generateGroupId == NULL)) {
LOGE("The group instance is NULL or its function ptr is NULL!");
return HC_ERR_NULL_PTR;
}
return instance->generateGroupId(userIdHash, returnGroupId);
}
AcrossAccountGroup *instance = (AcrossAccountGroup *)GetAcrossAccountGroupInstance();
if ((instance == NULL) || (instance->generateGroupId == NULL)) {
LOGE("The group instance is NULL or its function ptr is NULL!");
return HC_ERR_NULL_PTR;
}
return instance->generateGroupId(userIdHash, sharedUserIdHash, returnGroupId);
}
static int32_t SyncAcrossAccountGroup(const char *appId, const char *userIdHash, const char *deviceId,
const CJson *sharedUserIdHashList)
{
if ((appId == NULL) || (deviceId == NULL) || (userIdHash == NULL) || (sharedUserIdHashList == NULL)) {
LOGE("The input parameters contains NULL value!");
return HC_ERR_INVALID_PARAMS;
}
if (!IsAcrossAccountGroupSupported()) {
LOGE("Across account group is not supported!");
return HC_ERR_NOT_SUPPORT;
}
AcrossAccountGroup *instance = (AcrossAccountGroup *)GetAcrossAccountGroupInstance();
if ((instance == NULL) || (instance->syncGroup == NULL)) {
LOGE("The group instance is NULL or its function ptr is NULL!");
return HC_ERR_NULL_PTR;
}
return instance->syncGroup(appId, userIdHash, deviceId, sharedUserIdHashList);
}
static int32_t AddGroupRoleWithCheck(int32_t osAccuntId, bool isManager, const char *appId, const char *groupId,
const char *roleAppId)
{
@@ -1172,8 +1130,6 @@ static const GroupImpl g_groupImplInstance = {
.deleteMember = RequestDeleteMemberFromGroup,
.processBindData = RequestProcessBindData,
.confirmRequest = RequestConfirmRequest,
.generateAccountGroupId = GenerateAccountGroupId,
.syncAcrossAccountGroup = SyncAcrossAccountGroup,
.addGroupRole = AddGroupRoleWithCheck,
.deleteGroupRole = DeleteGroupRoleWithCheck,
.getGroupRoles = GetGroupRolesWithCheck,
@@ -671,19 +671,35 @@ int32_t AddExpireTimeOrDefault(const CJson *jsonParams, TrustedGroupEntry *group
return HC_SUCCESS;
}
int32_t AddUserIdHashToGroupParams(const CJson *jsonParams, TrustedGroupEntry *groupParams)
int32_t AddUserIdToGroupParams(const CJson *jsonParams, TrustedGroupEntry *groupParams)
{
char *userIdHash = NULL;
int32_t result = GetUserIdHashFromJson(jsonParams, &userIdHash);
char *userId = NULL;
int32_t result = GetUserIdFromJson(jsonParams, &userId);
if (result != HC_SUCCESS) {
return result;
}
if (!StringSetPointer(&groupParams->userIdHash, userIdHash)) {
LOGE("Failed to copy userIdHash!");
HcFree(userIdHash);
if (!StringSetPointer(&groupParams->userId, userId)) {
LOGE("Failed to copy userId!");
HcFree(userId);
return HC_ERR_MEMORY_COPY;
}
HcFree(userIdHash);
HcFree(userId);
return HC_SUCCESS;
}
int32_t AddSharedUserIdToGroupParams(const CJson *jsonParams, TrustedGroupEntry *groupParams)
{
char *sharedUserId = NULL;
int32_t result = GetSharedUserIdFromJson(jsonParams, &sharedUserId);
if (result != HC_SUCCESS) {
return result;
}
if (!StringSetPointer(&groupParams->sharedUserId, sharedUserId)) {
LOGE("Failed to copy sharedUserId!");
HcFree(sharedUserId);
return HC_ERR_MEMORY_COPY;
}
HcFree(sharedUserId);
return HC_SUCCESS;
}
@@ -748,27 +764,37 @@ int32_t AddGroupIdToDevParams(const char *groupId, TrustedDeviceEntry *devParams
return HC_SUCCESS;
}
int32_t AddUserIdHashToDevParams(const CJson *jsonParams, TrustedDeviceEntry *devParams)
int32_t AddUserIdToDevParams(const CJson *jsonParams, TrustedDeviceEntry *devParams)
{
char *userIdHash = NULL;
int32_t result = GetUserIdHashFromJson(jsonParams, &userIdHash);
char *userId = NULL;
int32_t result = GetUserIdFromJson(jsonParams, &userId);
if (result != HC_SUCCESS) {
return result;
}
if (!StringSetPointer(&devParams->userIdHash, userIdHash)) {
LOGE("Failed to copy userIdHash!");
HcFree(userIdHash);
if (!StringSetPointer(&devParams->userId, userId)) {
LOGE("Failed to copy userId!");
HcFree(userId);
return HC_ERR_MEMORY_COPY;
}
HcFree(userIdHash);
HcFree(userId);
return HC_SUCCESS;
}
int32_t AssertUserIdHashExist(const CJson *jsonParams)
int32_t AssertUserIdExist(const CJson *jsonParams)
{
const char *userIdHash = GetStringFromJson(jsonParams, FIELD_USER_ID);
if (userIdHash == NULL) {
LOGE("Failed to get userIdHash from jsonParams!");
const char *userId = GetStringFromJson(jsonParams, FIELD_USER_ID);
if (userId == NULL) {
LOGE("Failed to get userId from jsonParams!");
return HC_ERR_JSON_GET;
}
return HC_SUCCESS;
}
int32_t AssertSharedUserIdExist(const CJson *jsonParams)
{
const char *sharedUserId = GetStringFromJson(jsonParams, FIELD_PEER_USER_ID);
if (sharedUserId == NULL) {
LOGE("Failed to get sharedUserId from jsonParams!");
return HC_ERR_JSON_GET;
}
return HC_SUCCESS;
@@ -1034,18 +1060,32 @@ int32_t GetGroupTypeFromDb(int32_t osAccountId, const char *groupId, int32_t *re
return HC_SUCCESS;
}
int32_t GetUserIdHashFromJson(const CJson *jsonParams, char **userIdHash)
int32_t GetUserIdFromJson(const CJson *jsonParams, char **userId)
{
if ((jsonParams == NULL) || (userIdHash == NULL)) {
if ((jsonParams == NULL) || (userId == NULL)) {
LOGE("The input parameters contains NULL value!");
return HC_ERR_INVALID_PARAMS;
}
const char *oriUserIdHash = GetStringFromJson(jsonParams, FIELD_USER_ID);
if (oriUserIdHash == NULL) {
LOGE("Failed to get userIdHash from jsonParams!");
const char *oriUserId = GetStringFromJson(jsonParams, FIELD_USER_ID);
if (oriUserId == NULL) {
LOGE("Failed to get userId from jsonParams!");
return HC_ERR_JSON_GET;
}
return ToUpperCase(oriUserIdHash, userIdHash);
return ToUpperCase(oriUserId, userId);
}
int32_t GetSharedUserIdFromJson(const CJson *jsonParams, char **sharedUserId)
{
if ((jsonParams == NULL) || (sharedUserId == NULL)) {
LOGE("The input parameters contains NULL value!");
return HC_ERR_INVALID_PARAMS;
}
const char *oriUserId = GetStringFromJson(jsonParams, FIELD_PEER_USER_ID);
if (oriUserId == NULL) {
LOGE("Failed to get sharedUserId from jsonParams!");
return HC_ERR_JSON_GET;
}
return ToUpperCase(oriUserId, sharedUserId);
}
int32_t GetGroupIdFromJson(const CJson *jsonParams, const char **groupId)
@@ -0,0 +1,347 @@
/*
* Copyright (C) 2022 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 "identical_account_group.h"
#include "alg_defs.h"
#include "callback_manager.h"
#include "common_defs.h"
#include "data_manager.h"
#include "device_auth_defines.h"
#include "group_operation_common.h"
#include "hc_log.h"
#include "string_util.h"
#include "account_module.h"
static int32_t GenerateDevParams(const CJson *jsonParams, const char *groupId, TrustedDeviceEntry *devParams)
{
int32_t result;
if (((result = AddUdidToParams(devParams)) != HC_SUCCESS) ||
((result = AddUserIdToDevParams(jsonParams, devParams)) != HC_SUCCESS) ||
((result = AddAuthIdToParamsOrDefault(jsonParams, devParams)) != HC_SUCCESS) ||
((result = AddUserTypeToParamsOrDefault(jsonParams, devParams)) != HC_SUCCESS) ||
((result = AddGroupIdToDevParams(groupId, devParams)) != HC_SUCCESS) ||
((result = AddServiceTypeToParams(groupId, devParams)) != HC_SUCCESS)) {
return result;
}
return HC_SUCCESS;
}
static int32_t GenerateGroupParams(const CJson *jsonParams, const char *groupId, TrustedGroupEntry *groupParams)
{
const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
if (appId == NULL) {
LOGE("Failed to get appId from jsonParams!");
return HC_ERR_JSON_GET;
}
int32_t result;
if (((result = AddGroupTypeToParams(IDENTICAL_ACCOUNT_GROUP, groupParams)) != HC_SUCCESS) ||
((result = AddGroupNameToParams(groupId, groupParams)) != HC_SUCCESS) ||
((result = AddGroupIdToParams(groupId, groupParams)) != HC_SUCCESS) ||
((result = AddUserIdToGroupParams(jsonParams, groupParams)) != HC_SUCCESS) ||
((result = AddGroupOwnerToParams(appId, groupParams)) != HC_SUCCESS) ||
((result = AddGroupVisibilityOrDefault(jsonParams, groupParams)) != HC_SUCCESS) ||
((result = AddExpireTimeOrDefault(jsonParams, groupParams)) != HC_SUCCESS)) {
return result;
}
return HC_SUCCESS;
}
static int32_t GenerateGroupId(const char *userId, char **returnGroupId)
{
if ((userId == NULL) || (returnGroupId == NULL)) {
LOGE("The input parameters contains NULL value!");
return HC_ERR_INVALID_PARAMS;
}
/* identical account group: groupId = sha256(userId) */
int hashStrLen = SHA256_LEN * BYTE_TO_HEX_OPER_LENGTH + 1;
*returnGroupId = (char *)HcMalloc(hashStrLen, 0);
if (*returnGroupId == NULL) {
LOGE("Failed to allocate returnGroupId memory!");
return HC_ERR_ALLOC_MEMORY;
}
if (memcpy_s(*returnGroupId, hashStrLen, userId, HcStrlen(userId)) != EOK) {
LOGE("Failed to copy userId for groupId!");
HcFree(*returnGroupId);
*returnGroupId = NULL;
return HC_ERR_MEMORY_COPY;
}
return HC_SUCCESS;
}
static int32_t GenerateIdenticalGroupId(const CJson *jsonParams, char **returnGroupId)
{
char *userId = NULL;
int32_t result = GetUserIdFromJson(jsonParams, &userId);
if (result != HC_SUCCESS) {
return result;
}
result = GenerateGroupId(userId, returnGroupId);
HcFree(userId);
if (result != HC_SUCCESS) {
LOGE("Failed to generate groupId!");
return result;
}
return HC_SUCCESS;
}
static int32_t AssertCredentialExist(const CJson *jsonParams)
{
CJson *credJson = GetObjFromJson(jsonParams, FIELD_CREDENTIAL);
if (credJson == NULL) {
LOGE("Failed to get credJson!");
return HC_ERR_JSON_GET;
}
int32_t credType;
int32_t ret = GetIntFromJson(credJson, FIELD_CREDENTIAL_TYPE, &credType);
if (ret != HC_SUCCESS) {
LOGE("Failed to get credential type");
return ret;
}
const char *serverPk = GetStringFromJson(credJson, FIELD_SERVER_PK);
if (serverPk == NULL) {
LOGE("Failed to get serverPk");
return HC_ERR_JSON_GET;
}
const char *pkInfoSignature = GetStringFromJson(credJson, FIELD_PK_INFO_SIGNATURE);
if (pkInfoSignature == NULL) {
LOGE("Failed to get pkInfoSignature");
return HC_ERR_JSON_GET;
}
CJson *pkInfoJson = GetObjFromJson(credJson, FIELD_PK_INFO);
if (pkInfoJson == NULL) {
LOGE("Failed to get pkInfoJson");
return HC_ERR_JSON_GET;
}
return HC_SUCCESS;
}
static int32_t CheckCreateParams(int32_t osAccountId, const CJson *jsonParams)
{
const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
if (appId == NULL) {
LOGE("Failed to get appId from jsonParams!");
return HC_ERR_JSON_GET;
}
int32_t result;
if (((result = AssertUserIdExist(jsonParams)) != HC_SUCCESS) ||
((result = AssertCredentialExist(jsonParams)) != HC_SUCCESS) ||
((result = CheckUserTypeIfExist(jsonParams)) != HC_SUCCESS) ||
((result = CheckGroupVisibilityIfExist(jsonParams)) != HC_SUCCESS) ||
((result = CheckExpireTimeIfExist(jsonParams)) != HC_SUCCESS) ||
((result = CheckGroupNumLimit(osAccountId, IDENTICAL_ACCOUNT_GROUP, appId)) != HC_SUCCESS)) {
return result;
}
return HC_SUCCESS;
}
static int32_t DeleteGroupById(int32_t osAccountId, const char *groupId)
{
QueryGroupParams queryGroupParams = InitQueryGroupParams();
queryGroupParams.groupId = groupId;
return DelGroup(osAccountId, &queryGroupParams);
}
static int32_t DeleteDeviceById(int32_t osAccountId, const char *groupId)
{
QueryDeviceParams queryDeviceParams = InitQueryDeviceParams();
queryDeviceParams.groupId = groupId;
return DelTrustedDevice(osAccountId, &queryDeviceParams);
}
static int32_t CreateIdenticalGroup(int32_t osAccountId, const CJson *jsonParams, char *groupId)
{
int32_t result = AddGroupToDatabaseByJson(osAccountId, GenerateGroupParams, jsonParams, groupId);
if (result != HC_SUCCESS) {
LOGE("Add group to database failed");
return result;
}
result = ProcessAccountCredentials(osAccountId, IMPORT_SELF_CREDENTIAL, jsonParams, NULL);
if (result != HC_SUCCESS) {
LOGE("Import credential failed");
DeleteGroupById(osAccountId, groupId);
return result;
}
result = AddDeviceToDatabaseByJson(osAccountId, GenerateDevParams, jsonParams, groupId);
if (result != HC_SUCCESS) {
LOGE("Add device to database failed");
DeleteGroupById(osAccountId, groupId);
ProcessAccountCredentials(osAccountId, DELETE_SELF_CREDENTIAL, jsonParams, NULL);
return result;
}
result = SaveOsAccountDb(osAccountId);
if (result != HC_SUCCESS) {
LOGE("Save data to db file failed");
DeleteGroupById(osAccountId, groupId);
ProcessAccountCredentials(osAccountId, DELETE_SELF_CREDENTIAL, jsonParams, NULL);
DeleteDeviceById(osAccountId, groupId);
}
return result;
}
static int32_t CreateGroupInner(int32_t osAccountId, const CJson *jsonParams, char **returnGroupId)
{
char *groupId = NULL;
int32_t result;
if (((result = CheckCreateParams(osAccountId, jsonParams)) != HC_SUCCESS) ||
((result = GenerateIdenticalGroupId(jsonParams, &groupId)) != HC_SUCCESS)) {
LOGE("Check create params or generate groupId failed");
return result;
}
if (IsGroupExistByGroupId(osAccountId, groupId)) {
LOGE("Group already exists, do not create it again");
HcFree(groupId);
return HC_ERR_GROUP_DUPLICATE;
}
result = CreateIdenticalGroup(osAccountId, jsonParams, groupId);
if (result != HC_SUCCESS) {
HcFree(groupId);
return result;
}
*returnGroupId = groupId;
return HC_SUCCESS;
}
static int32_t CreateGroup(int32_t osAccountId, CJson *jsonParams, char **returnJsonStr)
{
LOGI("[Start]: Start to create a identical account group!");
if ((jsonParams == NULL) || (returnJsonStr == NULL)) {
LOGE("The input parameters contains NULL value!");
return HC_ERR_INVALID_PARAMS;
}
int32_t result;
char *groupId = NULL;
if (((result = CreateGroupInner(osAccountId, jsonParams, &groupId)) != HC_SUCCESS) ||
((result = ConvertGroupIdToJsonStr(groupId, returnJsonStr)) != HC_SUCCESS)) {
HcFree(groupId);
LOGE("Create identical group failed, result:%d", result);
return result;
}
HcFree(groupId);
LOGI("[End]: Create a identical account group successfully!");
return HC_SUCCESS;
}
static int32_t DeleteAcrossAccountGroup(int32_t osAccountId, const char *identicalGroupId)
{
TrustedGroupEntry *groupInfo = CreateGroupEntry();
if (groupInfo == NULL) {
LOGE("Failed to allocate groupInfo memory!");
return HC_ERR_ALLOC_MEMORY;
}
int32_t ret = GetGroupInfoById(osAccountId, identicalGroupId, groupInfo);
if (ret != HC_SUCCESS) {
LOGE("Failed to obtain the group information from the database!");
DestroyGroupEntry(groupInfo);
return ret;
}
const char *userId = StringGet(&groupInfo->userId);
DestroyGroupEntry(groupInfo);
GroupEntryVec groupEntryVec = CreateGroupEntryVec();
QueryGroupParams groupParams = InitQueryGroupParams();
groupParams.userId = userId;
groupParams.groupType = ACROSS_ACCOUNT_AUTHORIZE_GROUP;
ret = QueryGroups(osAccountId, &groupParams, &groupEntryVec);
if (ret != HC_SUCCESS) {
LOGE("query across account groups failed!");
ClearGroupEntryVec(&groupEntryVec);
return ret;
}
uint32_t groupIndex;
TrustedGroupEntry **entry = NULL;
FOR_EACH_HC_VECTOR(groupEntryVec, groupIndex, entry) {
if ((entry != NULL) && (*entry != NULL)) {
if (DeleteDeviceById(osAccountId, StringGet(&(*entry)->id)) != HC_SUCCESS) {
LOGE("Delete across account device failed");
ret = HC_ERR_DEL_GROUP;
}
if (DeleteGroupById(osAccountId, StringGet(&(*entry)->id)) != HC_SUCCESS) {
LOGE("Delete across account group failed");
ret = HC_ERR_DEL_GROUP;
}
}
}
ClearGroupEntryVec(&groupEntryVec);
return ret;
}
static int32_t DeleteGroupInner(int32_t osAccountId, const char *groupId, CJson *jsonParams)
{
int32_t ret = DeleteAcrossAccountGroup(osAccountId, groupId);
if ((ret != HC_SUCCESS) && (ret != HC_ERR_DEL_GROUP)) {
return ret;
}
if (DeleteDeviceById(osAccountId, groupId) != HC_SUCCESS) {
LOGE("Delete identical account device failed");
ret = HC_ERR_DEL_GROUP;
}
if (DeleteGroupById(osAccountId, groupId) != HC_SUCCESS) {
LOGE("Delete identical account group failed");
ret = HC_ERR_DEL_GROUP;
}
if (SaveOsAccountDb(osAccountId) != HC_SUCCESS) {
LOGE("Save data to db file failed");
ret = HC_ERR_DEL_GROUP;
}
if ((AddStringToJson(jsonParams, FIELD_USER_ID, groupId) != HC_SUCCESS) ||
(ProcessAccountCredentials(osAccountId, DELETE_SELF_CREDENTIAL, jsonParams, NULL) != HC_SUCCESS)) {
LOGE("Delete credential failed");
ret = HC_ERR_DEL_GROUP;
}
return ret;
}
static int32_t DeleteGroup(int32_t osAccountId, CJson *jsonParams, char **returnJsonStr)
{
LOGI("[Start]: Start to delete the identical account group!");
if ((jsonParams == NULL) || (returnJsonStr == NULL)) {
LOGE("The input parameters contains NULL value!");
return HC_ERR_INVALID_PARAMS;
}
const char *groupId = NULL;
int32_t ret = GetGroupIdFromJson(jsonParams, &groupId);
if (ret != HC_SUCCESS) {
LOGE("Failed to get groupId");
return ret;
}
ret = DeleteGroupInner(osAccountId, groupId, jsonParams);
if (ret != HC_SUCCESS) {
LOGE("Delete group inner failed");
return ret;
}
ret = ConvertGroupIdToJsonStr(groupId, returnJsonStr);
if (ret != HC_SUCCESS) {
LOGE("Failed to convert groupId to json");
return ret;
}
LOGI("[End]: Delete the identical account group successfully!");
return HC_SUCCESS;
}
static IdenticalAccountGroup g_identicalAccountGroup = {
.base.type = IDENTICAL_ACCOUNT_GROUP,
.base.createGroup = CreateGroup,
.base.deleteGroup = DeleteGroup,
.generateGroupId = GenerateGroupId
};
BaseGroup *GetIdenticalAccountGroupInstance(void)
{
return (BaseGroup *)&g_identicalAccountGroup;
}
bool IsIdenticalAccountGroupSupported(void)
{
return true;
}
@@ -24,5 +24,5 @@ BaseGroup *GetPeerToPeerGroupInstance(void)
bool IsPeerToPeerGroupSupported(void)
{
return true;
return false;
}
@@ -108,7 +108,8 @@ int32_t RequestAuthKeyAgree(int64_t requestId, const char *appId, const char *ag
FreeJson(params);
return HC_ERR_JSON_FAIL;
}
if (InitAndPushGMTask(AUTH_KEY_AGREEMENT, requestId, params, DoClientTask) != HC_SUCCESS) {
int32_t osAccountId = ANY_OS_ACCOUNT;
if (InitAndPushGMTask(osAccountId, AUTH_KEY_AGREEMENT, requestId, params, DoClientTask) != HC_SUCCESS) {
FreeJson(params);
return HC_ERR_INIT_TASK_FAIL;
}
@@ -132,7 +133,8 @@ int32_t RequestProcessKeyAgreeData(int64_t requestId, const char *appId, const u
FreeJson(params);
return HC_ERR_JSON_FAIL;
}
if (InitAndPushGMTask(AUTH_KEY_AGREEMENT, requestId, params, DoServerTask) != HC_SUCCESS) {
int32_t osAccountId = ANY_OS_ACCOUNT;
if (InitAndPushGMTask(osAccountId, AUTH_KEY_AGREEMENT, requestId, params, DoServerTask) != HC_SUCCESS) {
FreeJson(params);
return HC_ERR_INIT_TASK_FAIL;
}
@@ -94,7 +94,7 @@ static int FillDlKeysLenAccordingToMod(PakeBaseParams *params)
static int32_t InitDlPakeParams(PakeBaseParams *params)
{
int res;
int32_t res;
if (params->isClient) {
res = FillDlKeysLenAccordingToEpkPeer(params);
} else {
@@ -33,9 +33,8 @@ static int32_t GenerateEsk(PakeBaseParams *params)
{
int32_t res;
if (params->curveType == CURVE_256) {
LOGE("CURVE_256 is not supported.");
return HC_ERR_NOT_SUPPORT;
} else { // CURVE_25519
return params->loader->generateRandom(&(params->eskSelf));
} else if (params->curveType == CURVE_25519) {
res = params->loader->generateRandom(&(params->eskSelf));
if (res != HC_SUCCESS) {
LOGE("CURVE_25519: GenerateRandom for eskSelf failed, res: %x.", res);
@@ -44,8 +43,11 @@ static int32_t GenerateEsk(PakeBaseParams *params)
params->eskSelf.val[PAKE_EC_KEY_LEN - 1] &= PAKE_PRIVATE_KEY_AND_MASK_HIGH;
params->eskSelf.val[0] &= PAKE_PRIVATE_KEY_AND_MASK_LOW;
params->eskSelf.val[0] |= PAKE_PRIVATE_KEY_OR_MASK_LOW;
return HC_SUCCESS;
} else {
LOGE("Unsupported curve: %d.", params->curveType);
return HC_ERR_UNSUPPORTED_CURVE;
}
return res;
}
static int32_t InitEcPakeParams(PakeBaseParams *params)
@@ -107,11 +109,6 @@ CLEAN_UP:
int32_t AgreeEcSharedSecret(PakeBaseParams *params, Uint8Buff *sharedSecret)
{
if (params->curveType == CURVE_256) {
LOGE("CURVE_256 is not supported.");
CleanPakeSensitiveKeys(params);
return HC_ERR_NOT_SUPPORT;
}
int32_t res;
/* P256 requires buffer for both X and Y coordinates. */
uint32_t validKeyBufferLen = (params->curveType == CURVE_256) ? (PAKE_EC_KEY_LEN * 2) : (PAKE_EC_KEY_LEN);
@@ -122,6 +119,11 @@ int32_t AgreeEcSharedSecret(PakeBaseParams *params, Uint8Buff *sharedSecret)
}
Algorithm alg = (params->curveType == CURVE_256) ? P256 : X25519;
if (!params->loader->checkEcPublicKey(&(params->epkPeer), alg)) {
LOGE("Check public key failed.");
res = HC_ERR_INVALID_PUBLIC_KEY;
goto CLEAN_UP;
}
KeyBuff eskSelfBuff = { params->eskSelf.val, params->eskSelf.length, false };
KeyBuff epkPeerBuff = { params->epkPeer.val, params->epkPeer.length, false };
res = params->loader->agreeSharedSecret(&eskSelfBuff, &epkPeerBuff, alg, sharedSecret);
@@ -0,0 +1,662 @@
/*
* Copyright (C) 2021 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 "pake_v2_protocol_common.h"
#include "alg_loader.h"
#include "device_auth_defines.h"
#include "hc_log.h"
#include "hc_types.h"
#include "pake_defs.h"
#include "pake_protocol_dl_common.h"
#include "pake_protocol_ec_common.h"
#include "protocol_common.h"
#include "string_util.h"
#define KCF_CODE_LEN 1
#define PAKE_SESSION_KEY_LEN 32
static const uint8_t g_kcfCodeClient[KCF_CODE_LEN] = { 0x04 };
static const uint8_t g_kcfCodeServer[KCF_CODE_LEN] = { 0x03 };
void DestroyPakeV2BaseParams(PakeBaseParams *params)
{
if (params == NULL) {
return;
}
CleanPakeSensitiveKeys(params);
HcFree(params->salt.val);
params->salt.val = NULL;
HcFree(params->challengeSelf.val);
params->challengeSelf.val = NULL;
HcFree(params->challengePeer.val);
params->challengePeer.val = NULL;
HcFree(params->epkSelf.val);
params->epkSelf.val = NULL;
HcFree(params->epkPeer.val);
params->epkPeer.val = NULL;
HcFree(params->idSelf.val);
params->idSelf.val = NULL;
HcFree(params->idPeer.val);
params->idPeer.val = NULL;
HcFree(params->kcfData.val);
params->kcfData.val = NULL;
HcFree(params->kcfDataPeer.val);
params->kcfDataPeer.val = NULL;
}
static int32_t AllocDefaultParams(PakeBaseParams *params)
{
params->salt.length = PAKE_SALT_LEN;
params->salt.val = (uint8_t *)HcMalloc(params->salt.length, 0);
if (params->salt.val == NULL) {
LOGE("Malloc for salt failed.");
return HC_ERR_ALLOC_MEMORY;
}
params->sharedSecret.length = SHA256_LEN;
params->sharedSecret.val = (uint8_t *)HcMalloc(params->sharedSecret.length, 0);
if (params->sharedSecret.val == NULL) {
LOGE("Malloc for sharedSecret failed.");
return HC_ERR_ALLOC_MEMORY;
}
params->sessionKey.length = PAKE_SESSION_KEY_LEN;
params->sessionKey.val = (uint8_t *)HcMalloc(params->sessionKey.length, 0);
if (params->sessionKey.val == NULL) {
LOGE("Malloc for sessionKey failed.");
return HC_ERR_ALLOC_MEMORY;
}
params->kcfData.length = HMAC_LEN;
params->kcfData.val = (uint8_t *)HcMalloc(params->kcfData.length, 0);
if (params->kcfData.val == NULL) {
LOGE("Malloc for kcfData failed.");
return HC_ERR_ALLOC_MEMORY;
}
params->kcfDataPeer.length = HMAC_LEN;
params->kcfDataPeer.val = (uint8_t *)HcMalloc(params->kcfDataPeer.length, 0);
if (params->kcfDataPeer.val == NULL) {
LOGE("Malloc for kcfDataPeer failed.");
return HC_ERR_ALLOC_MEMORY;
}
return HC_SUCCESS;
}
static void FillDefaultValue(PakeBaseParams *params)
{
params->psk.val = NULL;
params->psk.length = 0;
params->challengeSelf.val = NULL;
params->challengeSelf.length = 0;
params->challengePeer.val = NULL;
params->challengePeer.length = 0;
params->eskSelf.val = NULL;
params->eskSelf.length = 0;
params->epkSelf.val = NULL;
params->epkSelf.length = 0;
params->epkPeer.val = NULL;
params->epkPeer.length = 0;
params->base.val = NULL;
params->base.length = 0;
params->idSelf.val = NULL;
params->idSelf.length = 0;
params->idPeer.val = NULL;
params->idPeer.length = 0;
params->hmacKey.val = NULL;
params->hmacKey.length = 0;
params->supportedDlPrimeMod = DL_PRIME_MOD_NONE;
params->largePrimeNumHex = NULL;
params->innerKeyLen = 0;
params->supportedPakeAlg = PAKE_ALG_NONE;
params->curveType = CURVE_NONE;
params->isClient = true;
}
int32_t InitPakeV2BaseParams(PakeBaseParams *params)
{
if (params == NULL) {
LOGE("Params is null.");
return HC_ERR_NULL_PTR;
}
int32_t res = AllocDefaultParams(params);
if (res != HC_SUCCESS) {
goto CLEAN_UP;
}
FillDefaultValue(params);
params->loader = GetLoaderInstance();
if (params->loader == NULL) {
res = HC_ERROR;
goto CLEAN_UP;
}
return HC_SUCCESS;
CLEAN_UP:
DestroyPakeV2BaseParams(params);
return res;
}
static int32_t GeneratePakeParams(PakeBaseParams *params)
{
int32_t res;
uint8_t secretVal[PAKE_SECRET_LEN] = { 0 };
Uint8Buff secret = { secretVal, PAKE_SECRET_LEN };
if (!params->isClient) {
res = params->loader->generateRandom(&(params->salt));
if (res != HC_SUCCESS) {
LOGE("Generate salt failed, res: %x.", res);
goto CLEAN_UP;
}
}
Uint8Buff keyInfo = { (uint8_t *)HICHAIN_SPEKE_BASE_INFO, HcStrlen(HICHAIN_SPEKE_BASE_INFO) };
res = params->loader->computeHkdf(&(params->psk), &(params->salt), &keyInfo, &secret, false);
if (res != HC_SUCCESS) {
LOGE("Derive secret from psk failed, res: %x.", res);
goto CLEAN_UP;
}
FreeAndCleanKey(&params->psk);
if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_EC) != 0) {
res = GenerateEcPakeParams(params, &secret);
} else if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_DL) != 0) {
res = GenerateDlPakeParams(params, &secret);
} else {
res = HC_ERR_INVALID_ALG;
}
if (res != HC_SUCCESS) {
LOGE("GeneratePakeParams failed, pakeAlgType: 0x%x, res: 0x%x.", params->supportedPakeAlg, res);
goto CLEAN_UP;
}
(void)memset_s(secret.val, secret.length, 0, secret.length);
return res;
CLEAN_UP:
(void)memset_s(secret.val, secret.length, 0, secret.length);
CleanPakeSensitiveKeys(params);
return res;
}
static int32_t ComputeSidSelf(const PakeBaseParams *params, Uint8Buff *sidSelf)
{
int res;
Uint8Buff idSelfMsg = { NULL, params->idSelf.length + params->innerKeyLen };
idSelfMsg.val = (uint8_t *)HcMalloc(idSelfMsg.length, 0);
if (idSelfMsg.val == NULL) {
LOGE("Malloc for idSelfMsg failed.");
res = HC_ERR_ALLOC_MEMORY;
goto CLEAN_UP;
}
if (memcpy_s(idSelfMsg.val, idSelfMsg.length, params->idSelf.val, params->idSelf.length) != EOK) {
LOGE("Memcpy for idSelf failed.");
res = HC_ERR_MEMORY_COPY;
goto CLEAN_UP;
}
if (memcpy_s(idSelfMsg.val + params->idSelf.length, idSelfMsg.length - params->idSelf.length,
params->epkSelf.val, params->innerKeyLen) != EOK) { // only need x-coordinate
LOGE("Memcpy for epkSelf failed.");
res = HC_ERR_MEMORY_COPY;
goto CLEAN_UP;
}
res = params->loader->sha256(&idSelfMsg, sidSelf);
if (res != HC_SUCCESS) {
LOGE("Sha256 for idSelfMsg failed, res: %x.", res);
goto CLEAN_UP;
}
CLEAN_UP:
HcFree(idSelfMsg.val);
return res;
}
static int32_t ComputeSidPeer(const PakeBaseParams *params, Uint8Buff *sidPeer)
{
int res;
Uint8Buff idPeerMsg = { NULL, params->idPeer.length + params->innerKeyLen };
idPeerMsg.val = (uint8_t *)HcMalloc(idPeerMsg.length, 0);
if (idPeerMsg.val == NULL) {
LOGE("Malloc for idPeerMsg failed.");
res = HC_ERR_ALLOC_MEMORY;
goto CLEAN_UP;
}
if (memcpy_s(idPeerMsg.val, idPeerMsg.length, params->idPeer.val, params->idPeer.length) != EOK) {
LOGE("Memcpy for idPeer failed.");
res = HC_ERR_MEMORY_COPY;
goto CLEAN_UP;
}
if (memcpy_s(idPeerMsg.val + params->idPeer.length, idPeerMsg.length - params->idPeer.length,
params->epkPeer.val, params->innerKeyLen) != EOK) { // only need x-coordinate
LOGE("Memcpy for epkPeer failed.");
res = HC_ERR_MEMORY_COPY;
goto CLEAN_UP;
}
res = params->loader->sha256(&idPeerMsg, sidPeer);
if (res != HC_SUCCESS) {
LOGE("Sha256 for idPeerMsg failed, res: %x.", res);
goto CLEAN_UP;
}
CLEAN_UP:
HcFree(idPeerMsg.val);
return res;
}
static int32_t ComputeSid(const PakeBaseParams *params, Uint8Buff *sid)
{
int32_t res = HC_SUCCESS;
Uint8Buff sidSelf = { NULL, SHA256_LEN };
Uint8Buff sidPeer = { NULL, SHA256_LEN };
sidSelf.val = (uint8_t *)HcMalloc(sidSelf.length, 0);
if (sidSelf.val == NULL) {
LOGE("Malloc for sidSelf failed.");
res = HC_ERR_ALLOC_MEMORY;
goto CLEAN_UP;
}
sidPeer.val = (uint8_t *)HcMalloc(sidPeer.length, 0);
if (sidPeer.val == NULL) {
LOGE("Malloc for sidPeer failed.");
res = HC_ERR_ALLOC_MEMORY;
goto CLEAN_UP;
}
res = ComputeSidSelf(params, &sidSelf);
if (res != HC_SUCCESS) {
LOGE("ComputeSidSelf failed, res: %x", res);
goto CLEAN_UP;
}
res = ComputeSidPeer(params, &sidPeer);
if (res != HC_SUCCESS) {
LOGE("ComputeSidPeer failed, res: %x", res);
goto CLEAN_UP;
}
Uint8Buff *maxId = NULL;
Uint8Buff *minId = NULL;
int result = params->loader->bigNumCompare(&sidSelf, &sidPeer);
if (result <= 0) {
maxId = &sidSelf;
minId = &sidPeer;
} else {
maxId = &sidPeer;
minId = &sidSelf;
}
if (memcpy_s(sid->val, sid->length, maxId->val, maxId->length) != EOK) {
LOGE("Memcpy for maxId failed.");
res = HC_ERR_MEMORY_COPY;
goto CLEAN_UP;
}
if (memcpy_s(sid->val + maxId->length, sid->length - maxId->length, minId->val, minId->length) != EOK) {
LOGE("Memcpy for minId failed.");
res = HC_ERR_MEMORY_COPY;
goto CLEAN_UP;
}
CLEAN_UP:
HcFree(sidSelf.val);
HcFree(sidPeer.val);
return res;
}
static int32_t ComputeSharedSecret(PakeBaseParams *params, const Uint8Buff *sid, const Uint8Buff *tmpSharedSecret)
{
int32_t res;
Uint8Buff sharedSecretMsg = { NULL, 0 };
sharedSecretMsg.length = sid->length + params->innerKeyLen + HcStrlen(SHARED_SECRET_DERIVED_FACTOR);
sharedSecretMsg.val = (uint8_t *)HcMalloc(sharedSecretMsg.length, 0);
if (sharedSecretMsg.val == NULL) {
LOGE("Malloc for sharedSecretMsg failed.");
return HC_ERR_ALLOC_MEMORY;
}
int32_t usedLen = 0;
if (memcpy_s(sharedSecretMsg.val, sharedSecretMsg.length, sid->val, sid->length) != EOK) {
LOGE("Memcpy for sidHex failed.");
res = HC_ERR_MEMORY_COPY;
goto CLEAN_UP;
}
usedLen += sid->length;
if (memcpy_s(sharedSecretMsg.val + usedLen, sharedSecretMsg.length - usedLen,
tmpSharedSecret->val, params->innerKeyLen) != EOK) { // Only need x-coordinate
LOGE("Memcpy for tmpSharedSecret failed.");
res = HC_ERR_MEMORY_COPY;
goto CLEAN_UP;
}
usedLen += params->innerKeyLen;
if (memcpy_s(sharedSecretMsg.val + usedLen, sharedSecretMsg.length - usedLen,
SHARED_SECRET_DERIVED_FACTOR, HcStrlen(SHARED_SECRET_DERIVED_FACTOR)) != EOK) {
LOGE("Memcpy for sharedSecret derived factor failed.");
res = HC_ERR_MEMORY_COPY;
goto CLEAN_UP;
}
res = params->loader->sha256(&sharedSecretMsg, &params->sharedSecret);
if (res != HC_SUCCESS) {
LOGE("Sha256 for sharedSecretMsg failed, res: %x.", res);
goto CLEAN_UP;
}
CLEAN_UP:
FreeAndCleanKey(&sharedSecretMsg);
return res;
}
/*
* '|' means joint
* Z = epkB . eskA
* A = hash(idA | epkA_X)
* B = hash(idB | epkB_X)
* sid = MAX(A, B) | MIN(A, B)
* sharedSecret = hash(hex(sid) | Z_X | derivedFactor)
*/
static int32_t GenerateSharedSecret(PakeBaseParams *params)
{
int32_t res;
Uint8Buff tmpSharedSecret = { NULL, 0 };
Uint8Buff sid = { NULL, SHA256_LEN * 2 }; // sid is composed of client sid and server sid, so need twice SHA256_LEN
/* The key of P256 requires both X and Y coordinates values to represent it. */
tmpSharedSecret.length = (params->curveType == CURVE_256) ? (params->innerKeyLen * 2) : (params->innerKeyLen);
tmpSharedSecret.val = (uint8_t *)HcMalloc(tmpSharedSecret.length, 0);
if (tmpSharedSecret.val == NULL) {
LOGE("Malloc for tmpSharedSecret failed.");
res = HC_ERR_ALLOC_MEMORY;
goto CLEAN_UP;
}
if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_EC) != 0) {
res = AgreeEcSharedSecret(params, &tmpSharedSecret);
} else if (((uint32_t)params->supportedPakeAlg & PAKE_ALG_DL) != 0) {
res = AgreeDlSharedSecret(params, &tmpSharedSecret);
} else {
res = HC_ERR_INVALID_ALG;
}
if (res != HC_SUCCESS) {
LOGE("Agree intermediate sharedSecret failed, pakeAlgType: 0x%x, res: %x.", params->supportedPakeAlg, res);
goto CLEAN_UP;
}
FreeAndCleanKey(&params->eskSelf);
sid.val = (uint8_t *)HcMalloc(sid.length, 0);
if (sid.val == NULL) {
LOGE("Malloc for sid failed.");
res = HC_ERR_ALLOC_MEMORY;
goto CLEAN_UP;
}
res = ComputeSid(params, &sid);
if (res != HC_SUCCESS) {
LOGE("Compute sid failed, res: %x.", res);
goto CLEAN_UP;
}
res = ComputeSharedSecret(params, &sid, &tmpSharedSecret);
if (res != HC_SUCCESS) {
LOGE("ComputeSharedSecret failed, res: %x.", res);
goto CLEAN_UP;
}
goto OUT;
CLEAN_UP:
CleanPakeSensitiveKeys(params);
OUT:
FreeAndCleanKey(&sid);
FreeAndCleanKey(&tmpSharedSecret);
return res;
}
static int32_t CombineEpk(const Uint8Buff *epkClient, const Uint8Buff *epkServer, uint32_t epkLenX,
Uint8Buff *proofMsg, uint32_t *usedLen)
{
if (memcpy_s(proofMsg->val + *usedLen, proofMsg->length - *usedLen,
epkClient->val, epkLenX) != EOK) { // Only the x-coordinate of epk is required
LOGE("Memcpy for epkClient failed.");
return HC_ERR_MEMORY_COPY;
}
*usedLen += epkLenX;
if (memcpy_s(proofMsg->val + *usedLen, proofMsg->length - *usedLen,
epkServer->val, epkLenX) != EOK) { // Only the x-coordinate of epk is required
LOGE("Memcpy for epkServer failed.");
return HC_ERR_MEMORY_COPY;
}
*usedLen += epkLenX;
return HC_SUCCESS;
}
static int32_t CombineProofMsg(const PakeBaseParams *params, Uint8Buff *proofMsg, bool isVerify)
{
int32_t res;
uint32_t usedLen = 0;
const uint8_t *kcfCode = NULL;
if ((params->isClient && !isVerify) || (!params->isClient && isVerify)) {
kcfCode = g_kcfCodeClient;
} else {
kcfCode = g_kcfCodeServer;
}
if (memcpy_s(proofMsg->val, proofMsg->length, kcfCode, KCF_CODE_LEN) != HC_SUCCESS) {
LOGE("Memcpy for g_kcfCode failed.");
return HC_ERR_MEMORY_COPY;
}
usedLen += KCF_CODE_LEN;
if (params->isClient) {
res = CombineEpk(&params->epkSelf, &params->epkPeer, params->innerKeyLen, proofMsg, &usedLen);
} else {
res = CombineEpk(&params->epkPeer, &params->epkSelf, params->innerKeyLen, proofMsg, &usedLen);
}
if (res != HC_SUCCESS) {
LOGE("CombineEpk failed, res: %x.", res);
return res;
}
if (memcpy_s(proofMsg->val + usedLen, proofMsg->length - usedLen,
params->sharedSecret.val, params->sharedSecret.length) != EOK) {
LOGE("Memcpy for sharedSecret failed.");
return HC_ERR_MEMORY_COPY;
}
usedLen += params->sharedSecret.length;
/* base only need x-coordinate */
if (memcpy_s(proofMsg->val + usedLen, proofMsg->length - usedLen, params->base.val, params->innerKeyLen) != EOK) {
LOGE("Memcpy for base failed.");
return HC_ERR_MEMORY_COPY;
}
return res;
}
/*
* msg = challenge_self + challenge_peer
* kcfdata = SHA256(byte(code), PK_CLIENT_X, PK_SERVER_X, sharedSecret, base_X)
*/
static int32_t GenerateProof(PakeBaseParams *params)
{
int res;
Uint8Buff proofMsg = { NULL, 0 };
proofMsg.length = KCF_CODE_LEN + params->innerKeyLen + params->innerKeyLen +
params->sharedSecret.length + params->innerKeyLen;
proofMsg.val = (uint8_t *)HcMalloc(proofMsg.length, 0);
if (proofMsg.val == NULL) {
LOGE("Malloc for proofMsg failed.");
res = HC_ERR_ALLOC_MEMORY;
goto CLEAN_UP;
}
res = CombineProofMsg(params, &proofMsg, false);
if (res != HC_SUCCESS) {
LOGE("CombineProofMsg failed, res: %x.", res);
goto CLEAN_UP;
}
res = params->loader->sha256(&proofMsg, &params->kcfData);
if (res != HC_SUCCESS) {
LOGE("Sha256 for proofMsg failed, res: %x.", res);
goto CLEAN_UP;
}
goto OUT;
CLEAN_UP:
CleanPakeSensitiveKeys(params);
OUT:
FreeAndCleanKey(&proofMsg);
return res;
}
static int32_t VerifyProof(PakeBaseParams *params)
{
int res;
Uint8Buff proofMsg = { NULL, 0 };
proofMsg.length = KCF_CODE_LEN + params->innerKeyLen + params->innerKeyLen +
params->sharedSecret.length + params->innerKeyLen;
proofMsg.val = (uint8_t *)HcMalloc(proofMsg.length, 0);
if (proofMsg.val == NULL) {
LOGE("Malloc for proofMsg failed.");
res = HC_ERR_ALLOC_MEMORY;
goto CLEAN_UP;
}
res = CombineProofMsg(params, &proofMsg, true);
if (res != HC_SUCCESS) {
LOGE("CombineProofMsg failed, res: %x.", res);
goto CLEAN_UP;
}
uint8_t tmpKcfDataVal[SHA256_LEN] = { 0 };
Uint8Buff tmpKcfData = { tmpKcfDataVal, SHA256_LEN };
res = params->loader->sha256(&proofMsg, &tmpKcfData);
if (res != HC_SUCCESS) {
LOGE("Sha256 for proofMsg failed, res: %x.", res);
goto CLEAN_UP;
}
if (memcmp(tmpKcfData.val, params->kcfDataPeer.val, tmpKcfData.length) != EOK) {
LOGE("Compare kcfData failed.");
res = HC_ERR_PROOF_NOT_MATCH;
goto CLEAN_UP;
}
goto OUT;
CLEAN_UP:
CleanPakeSensitiveKeys(params);
OUT:
FreeAndCleanKey(&proofMsg);
return res;
}
static int32_t GenerateSessionKey(PakeBaseParams *params)
{
Uint8Buff keyInfo = { (uint8_t *)HICHAIN_SPEKE_SESSIONKEY_INFO, HcStrlen(HICHAIN_SPEKE_SESSIONKEY_INFO) };
int res = params->loader->computeHkdf(&params->sharedSecret, &params->salt, &keyInfo, &params->sessionKey, false);
if (res != HC_SUCCESS) {
LOGE("ComputeHkdf for sessionKey failed, res: %x.", res);
CleanPakeSensitiveKeys(params);
}
FreeAndCleanKey(&params->base);
FreeAndCleanKey(&params->sharedSecret);
return res;
}
int32_t ClientConfirmPakeV2Protocol(PakeBaseParams *params)
{
if (params == NULL) {
LOGE("Params is null.");
return HC_ERR_NULL_PTR;
}
int32_t res = GeneratePakeParams(params);
if (res != HC_SUCCESS) {
LOGE("GeneratePakeParams failed, res: %x.", res);
goto CLEAN_UP;
}
res = GenerateSharedSecret(params);
if (res != HC_SUCCESS) {
LOGE("GenerateSharedSecret failed, res: %x.", res);
goto CLEAN_UP;
}
res = GenerateProof(params);
if (res != HC_SUCCESS) {
LOGE("GenerateProof failed, res: %x.", res);
goto CLEAN_UP;
}
return res;
CLEAN_UP:
CleanPakeSensitiveKeys(params);
return res;
}
int32_t ClientVerifyConfirmPakeV2Protocol(PakeBaseParams *params)
{
if (params == NULL) {
LOGE("Params is null.");
return HC_ERR_NULL_PTR;
}
int32_t res = VerifyProof(params);
if (res != HC_SUCCESS) {
LOGE("VerifyProof failed, res: %x.", res);
goto CLEAN_UP;
}
res = GenerateSessionKey(params);
if (res != HC_SUCCESS) {
LOGE("GenerateSessionKey failed, res: %x.", res);
goto CLEAN_UP;
}
return res;
CLEAN_UP:
CleanPakeSensitiveKeys(params);
return res;
}
int32_t ServerResponsePakeV2Protocol(PakeBaseParams *params)
{
if (params == NULL) {
LOGE("Params is null.");
return HC_ERR_NULL_PTR;
}
int32_t res = GeneratePakeParams(params);
if (res != HC_SUCCESS) {
LOGE("GeneratePakeParams failed, res: %x.", res);
CleanPakeSensitiveKeys(params);
}
return res;
}
int32_t ServerConfirmPakeV2Protocol(PakeBaseParams *params)
{
if (params == NULL) {
LOGE("Params is null.");
return HC_ERR_NULL_PTR;
}
int32_t res = GenerateSharedSecret(params);
if (res != HC_SUCCESS) {
LOGE("GenerateSharedSecret failed, res: %x.", res);
goto CLEAN_UP;
}
res = VerifyProof(params);
if (res != HC_SUCCESS) {
LOGE("VerifyProof failed, res: %x.", res);
goto CLEAN_UP;
}
res = GenerateProof(params);
if (res != HC_SUCCESS) {
LOGE("GenerateProof failed, res: %x.", res);
goto CLEAN_UP;
}
res = GenerateSessionKey(params);
if (res != HC_SUCCESS) {
LOGE("GenerateSessionKey failed, res: %x.", res);
goto CLEAN_UP;
}
return res;
CLEAN_UP:
CleanPakeSensitiveKeys(params);
return res;
}
+4
View File
@@ -26,6 +26,8 @@ ohos_unittest("deviceauth_llt") {
include_dirs += [
"./include",
"//third_party/json/include",
"//third_party/mbedtls/include",
"//third_party/mbedtls/include/mbedtls",
"//utils/native/base/include",
"//foundation/communication/dsoftbus/interfaces/kits/common",
"//foundation/communication/dsoftbus/interfaces/kits/transport",
@@ -44,6 +46,7 @@ ohos_unittest("deviceauth_llt") {
"${key_management_adapter_path}/impl/src/alg_loader.c",
"${key_management_adapter_path}/impl/src/standard/crypto_hash_to_point.c",
"${key_management_adapter_path}/impl/src/standard/huks_adapter.c",
"${key_management_adapter_path}/impl/src/standard/mbedtls_ec_adapter.c",
"${os_adapter_path}/impl/src/hc_mutex.c",
"${os_adapter_path}/impl/src/hc_task_thread.c",
"${os_adapter_path}/impl/src/hc_time.c",
@@ -63,6 +66,7 @@ ohos_unittest("deviceauth_llt") {
"//third_party/cJSON:cjson_static",
"//third_party/googletest:gmock_main",
"//third_party/googletest:gtest_main",
"//third_party/mbedtls:mbedtls_shared",
"//third_party/openssl:libcrypto_static",
"//utils/native/base:utils",
]
@@ -554,7 +554,7 @@ HWTEST_F(GmGetJoinedGroupsTest, GmGetJoinedGroupsTest002, TestSize.Level0)
char *returnData = NULL;
uint32_t returnNum = 0;
int32_t ret = gm->getJoinedGroups(TEST_REQ_ID, TEST_APP_ID, IDENTICAL_ACCOUNT_GROUP, &returnData, &returnNum);
EXPECT_NE(ret, HC_SUCCESS);
EXPECT_EQ(ret, HC_SUCCESS);
}
class GmGetRelatedGroupsTest : public testing::Test {