diff --git a/frameworks/crypto_operation/signature.c b/frameworks/crypto_operation/signature.c index d5fbedf807f7df494c3de4d95fecdf1cd8d66860..01f73e527661e84ffc3b375feb4e54c5f163d3a4 100644 --- a/frameworks/crypto_operation/signature.c +++ b/frameworks/crypto_operation/signature.c @@ -18,6 +18,7 @@ #include #include "config.h" +#include "dsa_openssl.h" #include "ecdsa_openssl.h" #include "log.h" #include "memory.h" @@ -59,12 +60,14 @@ typedef struct { static const HcfSignGenAbility SIGN_GEN_ABILITY_SET[] = { { HCF_ALG_ECC, HcfSignSpiEcdsaCreate }, - { HCF_ALG_RSA, HcfSignSpiRsaCreate } + { HCF_ALG_RSA, HcfSignSpiRsaCreate }, + { HCF_ALG_DSA, HcfSignSpiDsaCreate } }; static const HcfVerifyGenAbility VERIFY_GEN_ABILITY_SET[] = { { HCF_ALG_ECC, HcfVerifySpiEcdsaCreate }, - { HCF_ALG_RSA, HcfVerifySpiRsaCreate } + { HCF_ALG_RSA, HcfVerifySpiRsaCreate }, + { HCF_ALG_DSA, HcfVerifySpiDsaCreate } }; static HcfSignSpiCreateFunc FindSignAbility(HcfSignatureParams *params) @@ -89,6 +92,24 @@ static HcfVerifySpiCreateFunc FindVerifyAbility(HcfSignatureParams *params) return NULL; } +static void SetKeyTypeDefault(HCF_ALG_PARA_VALUE value, HcfSignatureParams *paramsObj) +{ + switch (value) { + case HCF_ALG_ECC_DEFAULT: + paramsObj->algo = HCF_ALG_ECC; + break; + case HCF_ALG_RSA_DEFAULT: + paramsObj->algo = HCF_ALG_RSA; + break; + case HCF_ALG_DSA_DEFAULT: + paramsObj->algo = HCF_ALG_DSA; + break; + default: + LOGE("Invalid algo %u.", value); + break; + } +} + static void SetKeyType(HCF_ALG_PARA_VALUE value, HcfSignatureParams *paramsObj) { switch (value) { @@ -96,7 +117,6 @@ static void SetKeyType(HCF_ALG_PARA_VALUE value, HcfSignatureParams *paramsObj) case HCF_ALG_ECC_256: case HCF_ALG_ECC_384: case HCF_ALG_ECC_521: - paramsObj->keyLen = value; paramsObj->algo = HCF_ALG_ECC; break; case HCF_OPENSSL_RSA_512: @@ -108,6 +128,11 @@ static void SetKeyType(HCF_ALG_PARA_VALUE value, HcfSignatureParams *paramsObj) case HCF_OPENSSL_RSA_8192: paramsObj->algo = HCF_ALG_RSA; break; + case HCF_ALG_DSA_1024: + case HCF_ALG_DSA_2048: + case HCF_ALG_DSA_3072: + paramsObj->algo = HCF_ALG_DSA; + break; default: LOGE("there is not matched algorithm."); break; @@ -121,8 +146,10 @@ static HcfResult ParseSignatureParams(const HcfParaConfig* config, void *params) } HcfResult ret = HCF_SUCCESS; HcfSignatureParams *paramsObj = (HcfSignatureParams *)params; - LOGI("Set Parameter: %s", config->tag); + LOGD("Set Parameter: %s", config->tag); switch (config->paraType) { + case HCF_ALG_TYPE: + SetKeyTypeDefault(config->paraValue, paramsObj); case HCF_ALG_KEY_TYPE: SetKeyType(config->paraValue, paramsObj); break; @@ -204,6 +231,64 @@ static void DestroyVerify(HcfObjectBase *self) HcfFree(impl); } +static HcfResult SetSignSpecInt(HcfSign *self, SignSpecItem item, int32_t saltLen) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (item != PSS_SALT_LEN_INT) { + LOGE("Spec item not support."); + return HCF_INVALID_PARAMS; + } + if (saltLen < 0) { + if (saltLen != OPENSSL_RSA_PSS_SALTLEN_DIGEST && saltLen != OPENSSL_RSA_PSS_SALTLEN_AUTO && + saltLen != OPENSSL_RSA_PSS_SALTLEN_MAX) { + LOGE("negative saltLen is not defined."); + return HCF_INVALID_PARAMS; + } + } + if (!IsClassMatch((HcfObjectBase *)self, GetSignClass())) { + return HCF_INVALID_PARAMS; + } + HcfSignImpl *tmpSelf = (HcfSignImpl *)self; + return tmpSelf->spiObj->engineSetSignSpecInt(tmpSelf->spiObj, item, saltLen); +} + +static HcfResult GetSignSpecString(HcfSign *self, SignSpecItem item, char **returnString) +{ + if (self == NULL || returnString == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (item != PSS_MD_NAME_STR && item != PSS_MGF_NAME_STR && item != PSS_MGF1_MD_STR) { + LOGE("Spec item not support."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSignClass())) { + return HCF_INVALID_PARAMS; + } + HcfSignImpl *tmpSelf = (HcfSignImpl *)self; + return tmpSelf->spiObj->engineGetSignSpecString(tmpSelf->spiObj, item, returnString); +} + +static HcfResult GetSignSpecInt(HcfSign *self, SignSpecItem item, int32_t *returnInt) +{ + if (self == NULL || returnInt == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (item != PSS_SALT_LEN_INT && item != PSS_TRAILER_FIELD_INT) { + LOGE("Spec item not support."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetSignClass())) { + return HCF_INVALID_PARAMS; + } + HcfSignImpl *tmpSelf = (HcfSignImpl *)self; + return tmpSelf->spiObj->engineGetSignSpecInt(tmpSelf->spiObj, item, returnInt); +} + static HcfResult SignInit(HcfSign *self, HcfParamsSpec *params, HcfPriKey *privateKey) { if (self == NULL) { @@ -243,6 +328,67 @@ static HcfResult SignDoFinal(HcfSign *self, HcfBlob *data, HcfBlob *returnSignat return ((HcfSignImpl *)self)->spiObj->engineSign(((HcfSignImpl *)self)->spiObj, data, returnSignatureData); } +static HcfResult SetVerifySpecInt(HcfVerify *self, SignSpecItem item, int32_t saltLen) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (item != PSS_SALT_LEN_INT) { + LOGE("Spec item not support."); + return HCF_INVALID_PARAMS; + } + if (saltLen < 0) { + // OPENSSL_RSA_PSS_SALTLEN_AUTO is used only by verify. + if (saltLen != OPENSSL_RSA_PSS_SALTLEN_DIGEST && saltLen != OPENSSL_RSA_PSS_SALTLEN_AUTO && + saltLen != OPENSSL_RSA_PSS_SALTLEN_MAX) { + LOGE("negative saltLen is not defined."); + return HCF_INVALID_PARAMS; + } + } + if (!IsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { + return HCF_INVALID_PARAMS; + } + HcfVerifyImpl *tmpSelf = (HcfVerifyImpl *)self; + return tmpSelf->spiObj->engineSetVerifySpecInt(tmpSelf->spiObj, item, saltLen); +} + +static HcfResult GetVerifySpecString(HcfVerify *self, SignSpecItem item, char **returnString) +{ + if (self == NULL || returnString == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (item != PSS_MD_NAME_STR && item != PSS_MGF_NAME_STR && item != PSS_MGF1_MD_STR) { + LOGE("Spec item not support."); + return HCF_INVALID_PARAMS; + } + + if (!IsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { + return HCF_INVALID_PARAMS; + } + HcfVerifyImpl *tmpSelf = (HcfVerifyImpl *)self; + return tmpSelf->spiObj->engineGetVerifySpecString(tmpSelf->spiObj, item, returnString); +} + +static HcfResult GetVerifySpecInt(HcfVerify *self, SignSpecItem item, int32_t *returnInt) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (item != PSS_SALT_LEN_INT && item != PSS_TRAILER_FIELD_INT) { + LOGE("Spec item not support."); + return HCF_INVALID_PARAMS; + } + + if (!IsClassMatch((HcfObjectBase *)self, GetVerifyClass())) { + return HCF_INVALID_PARAMS; + } + HcfVerifyImpl *tmpSelf = (HcfVerifyImpl *)self; + return tmpSelf->spiObj->engineGetVerifySpecInt(tmpSelf->spiObj, item, returnInt); +} + static HcfResult VerifyInit(HcfVerify *self, HcfParamsSpec *params, HcfPubKey *publicKey) { if (self == NULL) { @@ -283,7 +429,7 @@ static bool VerifyDoFinal(HcfVerify *self, HcfBlob *data, HcfBlob *signatureData HcfResult HcfSignCreate(const char *algoName, HcfSign **returnObj) { - LOGI("HcfSignCreate start"); + LOGD("HcfSignCreate start"); if ((!IsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) { return HCF_INVALID_PARAMS; } @@ -308,10 +454,10 @@ HcfResult HcfSignCreate(const char *algoName, HcfSign **returnObj) if (strcpy_s(returnSign->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) { LOGE("Failed to copy algoName!"); HcfFree(returnSign); - return HCF_ERR_COPY; + return HCF_INVALID_PARAMS; } HcfSignSpi *spiObj = NULL; - int32_t res = createSpiFunc(¶ms, &spiObj); + HcfResult res = createSpiFunc(¶ms, &spiObj); if (res != HCF_SUCCESS) { LOGE("Failed to create spi object!"); HcfFree(returnSign); @@ -323,16 +469,19 @@ HcfResult HcfSignCreate(const char *algoName, HcfSign **returnObj) returnSign->base.init = SignInit; returnSign->base.update = SignUpdate; returnSign->base.sign = SignDoFinal; + returnSign->base.setSignSpecInt = SetSignSpecInt; + returnSign->base.getSignSpecInt = GetSignSpecInt; + returnSign->base.getSignSpecString = GetSignSpecString; returnSign->spiObj = spiObj; *returnObj = (HcfSign *)returnSign; - LOGI("HcfSignCreate end"); + LOGD("HcfSignCreate end"); return HCF_SUCCESS; } HcfResult HcfVerifyCreate(const char *algoName, HcfVerify **returnObj) { - LOGI("HcfVerifyCreate start"); + LOGD("HcfVerifyCreate start"); if ((!IsStrValid(algoName, HCF_MAX_ALGO_NAME_LEN)) || (returnObj == NULL)) { return HCF_INVALID_PARAMS; } @@ -355,10 +504,10 @@ HcfResult HcfVerifyCreate(const char *algoName, HcfVerify **returnObj) if (strcpy_s(returnVerify->algoName, HCF_MAX_ALGO_NAME_LEN, algoName) != EOK) { LOGE("Failed to copy algoName!"); HcfFree(returnVerify); - return HCF_ERR_COPY; + return HCF_INVALID_PARAMS; } HcfVerifySpi *spiObj = NULL; - int32_t res = createSpiFunc(¶ms, &spiObj); + HcfResult res = createSpiFunc(¶ms, &spiObj); if (res != HCF_SUCCESS) { LOGE("Failed to create spi object!"); HcfFree(returnVerify); @@ -370,8 +519,11 @@ HcfResult HcfVerifyCreate(const char *algoName, HcfVerify **returnObj) returnVerify->base.init = VerifyInit; returnVerify->base.update = VerifyUpdate; returnVerify->base.verify = VerifyDoFinal; + returnVerify->base.setVerifySpecInt = SetVerifySpecInt; + returnVerify->base.getVerifySpecInt = GetVerifySpecInt; + returnVerify->base.getVerifySpecString = GetVerifySpecString; returnVerify->spiObj = spiObj; *returnObj = (HcfVerify *)returnVerify; - LOGI("HcfVerifyCreate end"); + LOGD("HcfVerifyCreate end"); return HCF_SUCCESS; } diff --git a/frameworks/js/napi/crypto/inc/napi_sign.h b/frameworks/js/napi/crypto/inc/napi_sign.h index e4f77763f4ba7ddc5b1ed82ef97b651c51bee122..483380650a27014017ca23079e58404cc7ca4643 100644 --- a/frameworks/js/napi/crypto/inc/napi_sign.h +++ b/frameworks/js/napi/crypto/inc/napi_sign.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -39,6 +39,9 @@ public: static napi_value JsUpdate(napi_env env, napi_callback_info info); static napi_value JsSign(napi_env env, napi_callback_info info); + static napi_value JsSetSignSpec(napi_env env, napi_callback_info info); + static napi_value JsGetSignSpec(napi_env env, napi_callback_info info); + static thread_local napi_ref classRef_; private: diff --git a/frameworks/js/napi/crypto/inc/napi_verify.h b/frameworks/js/napi/crypto/inc/napi_verify.h index 705c067a79bef0caad441b020e5c1fbb1e64be2d..f7211ab5c9641b15abb10d3b6698f99e61174ae7 100644 --- a/frameworks/js/napi/crypto/inc/napi_verify.h +++ b/frameworks/js/napi/crypto/inc/napi_verify.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -39,6 +39,9 @@ public: static napi_value JsUpdate(napi_env env, napi_callback_info info); static napi_value JsVerify(napi_env env, napi_callback_info info); + static napi_value JsSetVerifySpec(napi_env env, napi_callback_info info); + static napi_value JsGetVerifySpec(napi_env env, napi_callback_info info); + static thread_local napi_ref classRef_; private: diff --git a/frameworks/js/napi/crypto/src/napi_sign.cpp b/frameworks/js/napi/crypto/src/napi_sign.cpp index dee597aa3a35f499ba9b6567696bc2ccb3dfb556..a2b6d7edbb25c5bfb9c264654bd727d5020aa8a1 100644 --- a/frameworks/js/napi/crypto/src/napi_sign.cpp +++ b/frameworks/js/napi/crypto/src/napi_sign.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -39,7 +39,8 @@ struct SignInitCtx { HcfParamsSpec *params; HcfPriKey *priKey; - HcfResult result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; }; struct SignUpdateCtx { @@ -54,7 +55,8 @@ struct SignUpdateCtx { HcfSign *sign; HcfBlob *data; - HcfResult result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; }; struct SignDoFinalCtx { @@ -69,7 +71,8 @@ struct SignDoFinalCtx { HcfSign *sign; HcfBlob *data; - HcfResult result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; HcfBlob returnSignatureData; }; @@ -147,16 +150,14 @@ static bool BuildSignJsInitCtx(napi_env env, napi_callback_info info, SignInitCt napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if (argc != expectedArgc && argc != expectedArgc - 1) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } - ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiSign *napiSign = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiSign)); if (status != napi_ok) { LOGE("failed to unwrap napi sign obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } @@ -165,7 +166,6 @@ static bool BuildSignJsInitCtx(napi_env env, napi_callback_info info, SignInitCt status = napi_unwrap(env, argv[index], reinterpret_cast(&napiPriKey)); if (status != napi_ok) { LOGE("failed to unwrap napi priKey obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[PriKey]: param unwarp error.")); return false; } @@ -190,7 +190,6 @@ static bool BuildSignJsUpdateCtx(napi_env env, napi_callback_info info, SignUpda napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if ((argc != expectedArgc) && (argc != expectedArgc - 1)) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } ctx->asyncType = (argc == PARAMS_NUM_TWO) ? ASYNC_CALLBACK : ASYNC_PROMISE; @@ -199,7 +198,6 @@ static bool BuildSignJsUpdateCtx(napi_env env, napi_callback_info info, SignUpda napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiSign)); if (status != napi_ok) { LOGE("failed to unwrap napi sign obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } @@ -207,8 +205,6 @@ static bool BuildSignJsUpdateCtx(napi_env env, napi_callback_info info, SignUpda HcfBlob *blob = GetBlobFromNapiValue(env, argv[index]); if (blob == nullptr) { LOGE("failed to get data."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "[Data]: must be of the DataBlob type.")); return false; } @@ -232,16 +228,14 @@ static bool BuildSignJsDoFinalCtx(napi_env env, napi_callback_info info, SignDoF napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if ((argc != expectedArgc) && (argc != expectedArgc - 1)) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } - ctx->asyncType = (argc == PARAMS_NUM_TWO) ? ASYNC_CALLBACK : ASYNC_PROMISE; + ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiSign *napiSign = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiSign)); if (status != napi_ok) { LOGE("failed to unwrap napi sign obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } @@ -253,8 +247,6 @@ static bool BuildSignJsDoFinalCtx(napi_env env, napi_callback_info info, SignDoF data = GetBlobFromNapiValue(env, argv[index]); if (data == nullptr) { LOGE("failed to get data."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "[Data]: must be of the DataBlob type.")); return false; } } @@ -273,8 +265,8 @@ static bool BuildSignJsDoFinalCtx(napi_env env, napi_callback_info info, SignDoF static void ReturnInitCallbackResult(napi_env env, SignInitCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_ONE] = { businessError }; @@ -290,19 +282,18 @@ static void ReturnInitCallbackResult(napi_env env, SignInitCtx *ctx, napi_value static void ReturnInitPromiseResult(napi_env env, SignInitCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { - napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->result, - COMMON_ERR_MSG.c_str())); + napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } static void ReturnUpdateCallbackResult(napi_env env, SignUpdateCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_ONE] = { businessError }; @@ -318,19 +309,18 @@ static void ReturnUpdateCallbackResult(napi_env env, SignUpdateCtx *ctx, napi_va static void ReturnUpdatePromiseResult(napi_env env, SignUpdateCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { - napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->result, - COMMON_ERR_MSG.c_str())); + napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } static void ReturnDoFinalCallbackResult(napi_env env, SignDoFinalCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_TWO] = { businessError, result }; @@ -346,11 +336,10 @@ static void ReturnDoFinalCallbackResult(napi_env env, SignDoFinalCtx *ctx, napi_ static void ReturnDoFinalPromiseResult(napi_env env, SignDoFinalCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { - napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->result, - COMMON_ERR_MSG.c_str())); + napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } @@ -358,11 +347,11 @@ void SignJsInitAsyncWorkProcess(napi_env env, void *data) { SignInitCtx *ctx = static_cast(data); - HcfResult res = ctx->sign->init(ctx->sign, ctx->params, ctx->priKey); - - ctx->result = res; - if (res != HCF_SUCCESS) { + ctx->errCode = ctx->sign->init(ctx->sign, ctx->params, ctx->priKey); + if (ctx->errCode != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, ctx->errCode, "sign init fail.")); LOGE("sign init fail."); + ctx->errMsg = "sign init fail."; } } @@ -382,11 +371,11 @@ void SignJsUpdateAsyncWorkProcess(napi_env env, void *data) { SignUpdateCtx *ctx = static_cast(data); - HcfResult res = ctx->sign->update(ctx->sign, ctx->data); - - ctx->result = res; - if (res != HCF_SUCCESS) { + ctx->errCode = ctx->sign->update(ctx->sign, ctx->data); + if (ctx->errCode != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, ctx->errCode, "sign update fail.")); LOGE("sign update fail."); + ctx->errMsg = "sign update fail."; } } @@ -406,11 +395,11 @@ void SignJsDoFinalAsyncWorkProcess(napi_env env, void *data) { SignDoFinalCtx *ctx = static_cast(data); - HcfResult res = ctx->sign->sign(ctx->sign, ctx->data, &ctx->returnSignatureData); - - ctx->result = res; - if (res != HCF_SUCCESS) { + ctx->errCode = ctx->sign->sign(ctx->sign, ctx->data, &ctx->returnSignatureData); + if (ctx->errCode != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, ctx->errCode, "sign doFinal fail.")); LOGE("sign doFinal fail."); + ctx->errMsg = "sign doFinal fail."; } } @@ -419,7 +408,7 @@ void SignJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, void *data) SignDoFinalCtx *ctx = static_cast(data); napi_value dataBlob = nullptr; - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { dataBlob = ConvertBlobToNapiValue(env, &ctx->returnSignatureData); } @@ -434,9 +423,9 @@ void SignJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, void *data) static napi_value NewSignJsInitAsyncWork(napi_env env, SignInitCtx *ctx) { napi_value resourceName = nullptr; - napi_create_string_utf8(env, "init", NAPI_AUTO_LENGTH, &resourceName); + NAPI_CALL(env, napi_create_string_utf8(env, "init", NAPI_AUTO_LENGTH, &resourceName)); - napi_create_async_work( + NAPI_CALL(env, napi_create_async_work( env, nullptr, resourceName, [](napi_env env, void *data) { SignJsInitAsyncWorkProcess(env, data); @@ -447,24 +436,22 @@ static napi_value NewSignJsInitAsyncWork(napi_env env, SignInitCtx *ctx) return; }, static_cast(ctx), - &ctx->asyncWork); + &ctx->asyncWork)); - napi_queue_async_work(env, ctx->asyncWork); + NAPI_CALL(env, napi_queue_async_work(env, ctx->asyncWork)); if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } static napi_value NewSignJsUpdateAsyncWork(napi_env env, SignUpdateCtx *ctx) { napi_value resourceName = nullptr; - napi_create_string_utf8(env, "update", NAPI_AUTO_LENGTH, &resourceName); + NAPI_CALL(env, napi_create_string_utf8(env, "update", NAPI_AUTO_LENGTH, &resourceName)); - napi_create_async_work( + NAPI_CALL(env, napi_create_async_work( env, nullptr, resourceName, [](napi_env env, void *data) { SignJsUpdateAsyncWorkProcess(env, data); @@ -475,24 +462,22 @@ static napi_value NewSignJsUpdateAsyncWork(napi_env env, SignUpdateCtx *ctx) return; }, static_cast(ctx), - &ctx->asyncWork); + &ctx->asyncWork)); - napi_queue_async_work(env, ctx->asyncWork); + NAPI_CALL(env, napi_queue_async_work(env, ctx->asyncWork)); if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } static napi_value NewSignJsDoFinalAsyncWork(napi_env env, SignDoFinalCtx *ctx) { napi_value resourceName = nullptr; - napi_create_string_utf8(env, "sign", NAPI_AUTO_LENGTH, &resourceName); + NAPI_CALL(env, napi_create_string_utf8(env, "sign", NAPI_AUTO_LENGTH, &resourceName)); - napi_create_async_work( + NAPI_CALL(env, napi_create_async_work( env, nullptr, resourceName, [](napi_env env, void *data) { SignJsDoFinalAsyncWorkProcess(env, data); @@ -503,15 +488,13 @@ static napi_value NewSignJsDoFinalAsyncWork(napi_env env, SignDoFinalCtx *ctx) return; }, static_cast(ctx), - &ctx->asyncWork); + &ctx->asyncWork)); - napi_queue_async_work(env, ctx->asyncWork); + NAPI_CALL(env, napi_queue_async_work(env, ctx->asyncWork)); if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } @@ -532,14 +515,15 @@ HcfSign *NapiSign::GetSign() napi_value NapiSign::JsInit(napi_env env, napi_callback_info info) { - LOGI("enter ..."); SignInitCtx *ctx = static_cast(HcfMalloc(sizeof(SignInitCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildSignJsInitCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeSignInitCtx(env, ctx); return nullptr; @@ -550,14 +534,15 @@ napi_value NapiSign::JsInit(napi_env env, napi_callback_info info) napi_value NapiSign::JsUpdate(napi_env env, napi_callback_info info) { - LOGI("enter ..."); SignUpdateCtx *ctx = static_cast(HcfMalloc(sizeof(SignUpdateCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildSignJsUpdateCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeSignUpdateCtx(env, ctx); return nullptr; @@ -568,14 +553,15 @@ napi_value NapiSign::JsUpdate(napi_env env, napi_callback_info info) napi_value NapiSign::JsSign(napi_env env, napi_callback_info info) { - LOGI("enter ..."); SignDoFinalCtx *ctx = static_cast(HcfMalloc(sizeof(SignDoFinalCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildSignJsDoFinalCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeSignDoFinalCtx(env, ctx); return nullptr; @@ -586,65 +572,190 @@ napi_value NapiSign::JsSign(napi_env env, napi_callback_info info) napi_value NapiSign::SignConstructor(napi_env env, napi_callback_info info) { - LOGI("enter ..."); - napi_value thisVar = nullptr; - napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - - LOGI("out ..."); + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); return thisVar; } +static napi_value NapiWrapSign(napi_env env, napi_value instance, NapiSign *napiSign) +{ + napi_status status = napi_wrap( + env, instance, napiSign, + [](napi_env env, void *data, void *hint) { + NapiSign *napiSign = static_cast(data); + delete napiSign; + return; + }, + nullptr, + nullptr); + if (status != napi_ok) { + LOGE("failed to wrap napiSign obj!"); + delete napiSign; + napiSign = nullptr; + return nullptr; + } + return instance; +} + napi_value NapiSign::CreateJsSign(napi_env env, napi_callback_info info) { - LOGI("enter ..."); size_t expectedArgc = PARAMS_NUM_ONE; size_t argc = expectedArgc; napi_value argv[PARAMS_NUM_ONE] = { nullptr }; - napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); LOGE("The input args num is invalid."); return nullptr; } napi_value instance; napi_value constructor = nullptr; - napi_get_reference_value(env, classRef_, &constructor); - napi_new_instance(env, constructor, argc, argv, &instance); + NAPI_CALL(env, napi_get_reference_value(env, classRef_, &constructor)); + NAPI_CALL(env, napi_new_instance(env, constructor, argc, argv, &instance)); std::string algName; if (!GetStringFromJSParams(env, argv[0], algName)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get algName fail.")); return nullptr; } HcfSign *sign = nullptr; - int32_t res = HcfSignCreate(algName.c_str(), &sign); + HcfResult res = HcfSignCreate(algName.c_str(), &sign); if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create c sign fail.")); LOGE("create c sign fail."); return nullptr; } - NapiSign *napiSign = new NapiSign(sign); - - napi_wrap( - env, instance, napiSign, - [](napi_env env, void *data, void *hint) { - NapiSign *napiSign = static_cast(data); - delete napiSign; - return; - }, - nullptr, - nullptr); + NapiSign *napiSign = new (std::nothrow) NapiSign(sign); + if (napiSign == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi sign failed")); + LOGE("new napi sign failed"); + return nullptr; + } napi_value napiAlgName = nullptr; - napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName); - napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName); + NAPI_CALL(env, napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName)); + NAPI_CALL(env, napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName)); + + return NapiWrapSign(env, instance, napiSign); +} - LOGI("out ..."); +// sign setSignSpec(itemType :signSpecItem, itemValue : number) +napi_value NapiSign::JsSetSignSpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiSign *napiSign = nullptr; + size_t expectedArgc = ARGS_SIZE_TWO; + size_t argc = ARGS_SIZE_TWO; + napi_value argv[ARGS_SIZE_TWO] = { nullptr }; + // thisVar means the js this argument for the call (sign.() means this = sign) + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num.")); + LOGE("wrong argument num. require 2 arguments. [Argc]: %zu!", argc); + return nullptr; + } + SignSpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get signSpecItem failed!")); + LOGE("get signspecitem failed!"); + return nullptr; + } + int32_t saltLen; + if (napi_get_value_int32(env, argv[1], &saltLen) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get signSpec saltLen failed!")); + LOGE("get signSpec saltLen failed!"); + return nullptr; + } + NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast(&napiSign))); + HcfSign *sign = napiSign->GetSign(); + HcfResult res = sign->setSignSpecInt(sign, item, saltLen); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "c setSignSpecNumber fail.")); + LOGE("c setSignSpecNumber fail."); + return nullptr; + } + return thisVar; +} + +static napi_value GetSignSpecString(napi_env env, SignSpecItem item, HcfSign *sign) +{ + char *returnString = nullptr; + HcfResult res = sign->getSignSpecString(sign, item, &returnString); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getSignSpecString failed.")); + LOGE("c getSignSpecString fail."); + return nullptr; + } + + napi_value instance = nullptr; + NAPI_CALL(env, napi_create_string_utf8(env, returnString, NAPI_AUTO_LENGTH, &instance)); + HcfFree(returnString); + return instance; +} + +static napi_value GetSignSpecNumber(napi_env env, SignSpecItem item, HcfSign *sign) +{ + int returnInt; + HcfResult res = sign->getSignSpecInt(sign, item, &returnInt); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getSignSpecInt failed.")); + LOGE("c getSignSpecInt fail."); + return nullptr; + } + + napi_value instance = nullptr; + NAPI_CALL(env, napi_create_int32(env, returnInt, &instance)); return instance; } +napi_value NapiSign::JsGetSignSpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiSign *napiSign = nullptr; + size_t expectedArgc = ARGS_SIZE_ONE; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num.")); + LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc); + return nullptr; + } + SignSpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get getSignSpecString failed!")); + LOGE("get getSignSpecString failed!"); + return nullptr; + } + + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiSign)); + if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiSign obj!")); + LOGE("failed to unwrap napiSign obj!"); + return nullptr; + } + HcfSign *sign = napiSign->GetSign(); + if (sign == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get sign obj!")); + LOGE("failed to get sign obj!"); + return nullptr; + } + + int32_t type = GetSignSpecType(item); + if (type == SPEC_ITEM_TYPE_STR) { + return GetSignSpecString(env, item, sign); + } else if (type == SPEC_ITEM_TYPE_NUM) { + return GetSignSpecNumber(env, item, sign); + } else { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "SignSpecItem not support!")); + return nullptr; + } +} + void NapiSign::DefineSignJSClass(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { @@ -656,6 +767,8 @@ void NapiSign::DefineSignJSClass(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("init", NapiSign::JsInit), DECLARE_NAPI_FUNCTION("update", NapiSign::JsUpdate), DECLARE_NAPI_FUNCTION("sign", NapiSign::JsSign), + DECLARE_NAPI_FUNCTION("setSignSpec", NapiSign::JsSetSignSpec), + DECLARE_NAPI_FUNCTION("getSignSpec", NapiSign::JsGetSignSpec), }; napi_value constructor = nullptr; napi_define_class(env, "Sign", NAPI_AUTO_LENGTH, NapiSign::SignConstructor, nullptr, diff --git a/frameworks/js/napi/crypto/src/napi_verify.cpp b/frameworks/js/napi/crypto/src/napi_verify.cpp index 5d4c1e8fc0fcc94b080ef92df8447a73dacc6b5b..053a4890a2bd9d8092372f829eff2ae5bfa62b93 100644 --- a/frameworks/js/napi/crypto/src/napi_verify.cpp +++ b/frameworks/js/napi/crypto/src/napi_verify.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -39,7 +39,8 @@ struct VerifyInitCtx { HcfParamsSpec *params; HcfPubKey *pubKey; - HcfResult result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; }; struct VerifyUpdateCtx { @@ -54,7 +55,8 @@ struct VerifyUpdateCtx { HcfVerify *verify; HcfBlob *data; - HcfResult result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; }; struct VerifyDoFinalCtx { @@ -70,7 +72,8 @@ struct VerifyDoFinalCtx { HcfBlob *data; HcfBlob *signatureData; - int32_t result; + HcfResult errCode = HCF_SUCCESS; + const char *errMsg = nullptr; bool isVerifySucc; }; @@ -148,7 +151,6 @@ static bool BuildVerifyJsInitCtx(napi_env env, napi_callback_info info, VerifyIn napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if ((argc != expectedArgc) && (argc != expectedArgc - 1)) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; @@ -157,7 +159,6 @@ static bool BuildVerifyJsInitCtx(napi_env env, napi_callback_info info, VerifyIn napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify)); if (status != napi_ok) { LOGE("failed to unwrap napi verify obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } @@ -166,7 +167,6 @@ static bool BuildVerifyJsInitCtx(napi_env env, napi_callback_info info, VerifyIn status = napi_unwrap(env, argv[index], reinterpret_cast(&napiPubKey)); if (status != napi_ok) { LOGE("failed to unwrap napi pubKey obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[PubKey]: param unwarp error.")); return false; } @@ -191,23 +191,20 @@ static bool BuildVerifyJsUpdateCtx(napi_env env, napi_callback_info info, Verify napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if ((argc != expectedArgc) && (argc != expectedArgc - 1)) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } - ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiVerify *napiVerify = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify)); if (status != napi_ok) { LOGE("failed to unwrap napi verify obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } size_t index = 0; HcfBlob *blob = GetBlobFromNapiValue(env, argv[index]); if (blob == nullptr) { - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Data]: must be of the DataBlob type.")); return false; } @@ -232,8 +229,6 @@ static bool GetDataBlobAndSignatureFromInput(napi_env env, napi_value dataValue, data = GetBlobFromNapiValue(env, dataValue); if (data == nullptr) { LOGE("failed to get data."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "[Data]: must be of the DataBlob type.")); return false; } } @@ -241,8 +236,6 @@ static bool GetDataBlobAndSignatureFromInput(napi_env env, napi_value dataValue, HcfBlob *signatureData = GetBlobFromNapiValue(env, signatureDataValue); if (signatureData == nullptr) { LOGE("failed to get signature."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, - "[SignatureData]: must be of the DataBlob type.")); HcfBlobDataFree(data); HcfFree(data); return false; @@ -262,16 +255,14 @@ static bool BuildVerifyJsDoFinalCtx(napi_env env, napi_callback_info info, Verif napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr); if ((argc != expectedArgc) && (argc != expectedArgc - 1)) { LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.")); return false; } - ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; + ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE; NapiVerify *napiVerify = nullptr; napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify)); if (status != napi_ok) { LOGE("failed to unwrap napi verify obj."); - napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.")); return false; } @@ -284,7 +275,6 @@ static bool BuildVerifyJsDoFinalCtx(napi_env env, napi_callback_info info, Verif ctx->verify = napiVerify->GetVerify(); ctx->data = data; ctx->signatureData = signatureData; - ctx->result = HCF_ERR_CRYPTO_OPERATION; if (ctx->asyncType == ASYNC_PROMISE) { napi_create_promise(env, &ctx->deferred, &ctx->promise); @@ -297,8 +287,8 @@ static bool BuildVerifyJsDoFinalCtx(napi_env env, napi_callback_info info, Verif static void ReturnInitCallbackResult(napi_env env, VerifyInitCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_ONE] = { businessError }; @@ -314,19 +304,19 @@ static void ReturnInitCallbackResult(napi_env env, VerifyInitCtx *ctx, napi_valu static void ReturnInitPromiseResult(napi_env env, VerifyInitCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { napi_reject_deferred(env, ctx->deferred, - GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str())); + GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } static void ReturnUpdateCallbackResult(napi_env env, VerifyUpdateCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_ONE] = { businessError }; @@ -342,19 +332,19 @@ static void ReturnUpdateCallbackResult(napi_env env, VerifyUpdateCtx *ctx, napi_ static void ReturnUpdatePromiseResult(napi_env env, VerifyUpdateCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { napi_reject_deferred(env, ctx->deferred, - GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str())); + GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } static void ReturnDoFinalCallbackResult(napi_env env, VerifyDoFinalCtx *ctx, napi_value result) { napi_value businessError = nullptr; - if (ctx->result != HCF_SUCCESS) { - businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str()); + if (ctx->errCode != HCF_SUCCESS) { + businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg); } napi_value params[ARGS_SIZE_TWO] = { businessError, result }; @@ -370,11 +360,11 @@ static void ReturnDoFinalCallbackResult(napi_env env, VerifyDoFinalCtx *ctx, nap static void ReturnDoFinalPromiseResult(napi_env env, VerifyDoFinalCtx *ctx, napi_value result) { - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_resolve_deferred(env, ctx->deferred, result); } else { napi_reject_deferred(env, ctx->deferred, - GenerateBusinessError(env, HCF_ERR_CRYPTO_OPERATION, COMMON_ERR_MSG.c_str())); + GenerateBusinessError(env, ctx->errCode, ctx->errMsg)); } } @@ -382,11 +372,11 @@ void VerifyJsInitAsyncWorkProcess(napi_env env, void *data) { VerifyInitCtx *ctx = static_cast(data); - HcfResult res = ctx->verify->init(ctx->verify, ctx->params, ctx->pubKey); - - ctx->result = res; - if (res != HCF_SUCCESS) { + ctx->errCode = ctx->verify->init(ctx->verify, ctx->params, ctx->pubKey); + if (ctx->errCode != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, ctx->errCode, "verify init fail.")); LOGE("verify init fail."); + ctx->errMsg = "verify init fail."; } } @@ -406,11 +396,11 @@ void VerifyJsUpdateAsyncWorkProcess(napi_env env, void *data) { VerifyUpdateCtx *ctx = static_cast(data); - HcfResult res = ctx->verify->update(ctx->verify, ctx->data); - - ctx->result = res; - if (res != HCF_SUCCESS) { + ctx->errCode = ctx->verify->update(ctx->verify, ctx->data); + if (ctx->errCode != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, ctx->errCode, "verify update fail.")); LOGE("verify update fail."); + ctx->errMsg = "verify update fail."; } } @@ -431,12 +421,14 @@ void VerifyJsDoFinalAsyncWorkProcess(napi_env env, void *data) VerifyDoFinalCtx *ctx = static_cast(data); ctx->isVerifySucc = ctx->verify->verify(ctx->verify, ctx->data, ctx->signatureData); - ctx->result = HCF_SUCCESS; - if (!ctx->isVerifySucc) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_CRYPTO_OPERATION, "verify doFinal fail.")); LOGE("verify doFinal fail."); + ctx->errCode = HCF_ERR_CRYPTO_OPERATION; + ctx->errMsg = "verify doFinal fail."; return; } + ctx->errCode = HCF_SUCCESS; } void VerifyJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, void *data) @@ -444,7 +436,7 @@ void VerifyJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, void *data VerifyDoFinalCtx *ctx = static_cast(data); napi_value result = nullptr; - if (ctx->result == HCF_SUCCESS) { + if (ctx->errCode == HCF_SUCCESS) { napi_get_boolean(env, ctx->isVerifySucc, &result); } @@ -459,9 +451,9 @@ void VerifyJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, void *data static napi_value NewVerifyJsInitAsyncWork(napi_env env, VerifyInitCtx *ctx) { napi_value resourceName = nullptr; - napi_create_string_utf8(env, "init", NAPI_AUTO_LENGTH, &resourceName); + NAPI_CALL(env, napi_create_string_utf8(env, "init", NAPI_AUTO_LENGTH, &resourceName)); - napi_create_async_work( + NAPI_CALL(env, napi_create_async_work( env, nullptr, resourceName, [](napi_env env, void *data) { VerifyJsInitAsyncWorkProcess(env, data); @@ -472,24 +464,22 @@ static napi_value NewVerifyJsInitAsyncWork(napi_env env, VerifyInitCtx *ctx) return; }, static_cast(ctx), - &ctx->asyncWork); + &ctx->asyncWork)); - napi_queue_async_work(env, ctx->asyncWork); + NAPI_CALL(env, napi_queue_async_work(env, ctx->asyncWork)); if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } static napi_value NewVerifyJsUpdateAsyncWork(napi_env env, VerifyUpdateCtx *ctx) { napi_value resourceName = nullptr; - napi_create_string_utf8(env, "update", NAPI_AUTO_LENGTH, &resourceName); + NAPI_CALL(env, napi_create_string_utf8(env, "update", NAPI_AUTO_LENGTH, &resourceName)); - napi_create_async_work( + NAPI_CALL(env, napi_create_async_work( env, nullptr, resourceName, [](napi_env env, void *data) { VerifyJsUpdateAsyncWorkProcess(env, data); @@ -500,24 +490,22 @@ static napi_value NewVerifyJsUpdateAsyncWork(napi_env env, VerifyUpdateCtx *ctx) return; }, static_cast(ctx), - &ctx->asyncWork); + &ctx->asyncWork)); - napi_queue_async_work(env, ctx->asyncWork); + NAPI_CALL(env, napi_queue_async_work(env, ctx->asyncWork)); if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } static napi_value NewVerifyJsDoFinalAsyncWork(napi_env env, VerifyDoFinalCtx *ctx) { napi_value resourceName = nullptr; - napi_create_string_utf8(env, "verify", NAPI_AUTO_LENGTH, &resourceName); + NAPI_CALL(env, napi_create_string_utf8(env, "verify", NAPI_AUTO_LENGTH, &resourceName)); - napi_create_async_work( + NAPI_CALL(env, napi_create_async_work( env, nullptr, resourceName, [](napi_env env, void *data) { VerifyJsDoFinalAsyncWorkProcess(env, data); @@ -528,15 +516,13 @@ static napi_value NewVerifyJsDoFinalAsyncWork(napi_env env, VerifyDoFinalCtx *ct return; }, static_cast(ctx), - &ctx->asyncWork); + &ctx->asyncWork)); - napi_queue_async_work(env, ctx->asyncWork); + NAPI_CALL(env, napi_queue_async_work(env, ctx->asyncWork)); if (ctx->asyncType == ASYNC_PROMISE) { return ctx->promise; } else { - napi_value result = nullptr; - napi_get_null(env, &result); - return result; + return NapiGetNull(env); } } @@ -557,14 +543,15 @@ HcfVerify *NapiVerify::GetVerify() napi_value NapiVerify::JsInit(napi_env env, napi_callback_info info) { - LOGI("enter ..."); VerifyInitCtx *ctx = static_cast(HcfMalloc(sizeof(VerifyInitCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildVerifyJsInitCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeVerifyInitCtx(env, ctx); return nullptr; @@ -575,14 +562,15 @@ napi_value NapiVerify::JsInit(napi_env env, napi_callback_info info) napi_value NapiVerify::JsUpdate(napi_env env, napi_callback_info info) { - LOGI("enter ..."); VerifyUpdateCtx *ctx = static_cast(HcfMalloc(sizeof(VerifyUpdateCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildVerifyJsUpdateCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeVerifyUpdateCtx(env, ctx); return nullptr; @@ -593,14 +581,15 @@ napi_value NapiVerify::JsUpdate(napi_env env, napi_callback_info info) napi_value NapiVerify::JsVerify(napi_env env, napi_callback_info info) { - LOGI("enter ..."); VerifyDoFinalCtx *ctx = static_cast(HcfMalloc(sizeof(VerifyDoFinalCtx), 0)); if (ctx == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail.")); LOGE("create context fail."); return nullptr; } if (!BuildVerifyJsDoFinalCtx(env, info, ctx)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail.")); LOGE("build context fail."); FreeVerifyDoFinalCtx(env, ctx); return nullptr; @@ -611,66 +600,191 @@ napi_value NapiVerify::JsVerify(napi_env env, napi_callback_info info) napi_value NapiVerify::VerifyConstructor(napi_env env, napi_callback_info info) { - LOGI("enter ..."); - napi_value thisVar = nullptr; - napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr); - - LOGI("out ..."); + NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr)); return thisVar; } +static napi_value NapiWrapVerify(napi_env env, napi_value instance, NapiVerify *napiVerify) +{ + napi_status status = napi_wrap( + env, instance, napiVerify, + [](napi_env env, void *data, void *hint) { + NapiVerify *napiVerify = static_cast(data); + delete napiVerify; + return; + }, + nullptr, + nullptr); + if (status != napi_ok) { + LOGE("failed to wrap napiVerify obj!"); + delete napiVerify; + napiVerify = nullptr; + return nullptr; + } + return instance; +} + napi_value NapiVerify::CreateJsVerify(napi_env env, napi_callback_info info) { - LOGI("enter ..."); size_t expectedArgc = PARAMS_NUM_ONE; size_t argc = expectedArgc; napi_value argv[PARAMS_NUM_ONE] = { nullptr }; - napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr)); if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid.")); LOGE("The input args num is invalid."); return nullptr; } napi_value instance; napi_value constructor = nullptr; - napi_get_reference_value(env, classRef_, &constructor); - napi_new_instance(env, constructor, argc, argv, &instance); + NAPI_CALL(env, napi_get_reference_value(env, classRef_, &constructor)); + NAPI_CALL(env, napi_new_instance(env, constructor, argc, argv, &instance)); std::string algName; if (!GetStringFromJSParams(env, argv[0], algName)) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get algoName.")); LOGE("failed to get algoName."); return nullptr; } HcfVerify *verify = nullptr; - int32_t res = HcfVerifyCreate(algName.c_str(), &verify); + HcfResult res = HcfVerifyCreate(algName.c_str(), &verify); if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "create c verify fail.")); LOGE("create c verify fail."); return nullptr; } - NapiVerify *napiVerify = new NapiVerify(verify); - - napi_wrap( - env, instance, napiVerify, - [](napi_env env, void *data, void *hint) { - NapiVerify *napiVerify = static_cast(data); - delete napiVerify; - return; - }, - nullptr, - nullptr); + NapiVerify *napiVerify = new (std::nothrow) NapiVerify(verify); + if (napiVerify == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi verify failed")); + LOGE("new napi verify failed"); + return nullptr; + } napi_value napiAlgName = nullptr; - napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName); - napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName); + NAPI_CALL(env, napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName)); + NAPI_CALL(env, napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName)); + + return NapiWrapVerify(env, instance, napiVerify); +} - LOGI("out ..."); +// verify setVerifySpec(itemType :VerifySpecItem, itemValue : number) +napi_value NapiVerify::JsSetVerifySpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiVerify *napiVerify = nullptr; + size_t expectedArgc = ARGS_SIZE_TWO; + size_t argc = ARGS_SIZE_TWO; + napi_value argv[ARGS_SIZE_TWO] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num.")); + LOGE("wrong argument num. require 2 arguments. [Argc]: %zu!", argc); + return nullptr; + } + SignSpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get signSpecItem failed!")); + LOGE("get signspecitem failed!"); + return nullptr; + } + int32_t saltLen; + if (napi_get_value_int32(env, argv[1], &saltLen) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get VerifySpec saltLen failed!")); + LOGE("get VerifySpec saltLen failed!"); + return nullptr; + } + NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify))); + HcfVerify *verify = napiVerify->GetVerify(); + HcfResult res = verify->setVerifySpecInt(verify, item, saltLen); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "c setVerifySpecNumber fail.")); + LOGE("c setVerifySpecNumber fail."); + return nullptr; + } + return thisVar; +} + +static napi_value GetVerifySpecString(napi_env env, SignSpecItem item, HcfVerify *verify) +{ + char *returnString = nullptr; + HcfResult res = verify->getVerifySpecString(verify, item, &returnString); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getVerifySpecString failed.")); + LOGE("c getVerifySpecString fail."); + return nullptr; + } + + napi_value instance = nullptr; + NAPI_CALL(env, napi_create_string_utf8(env, returnString, NAPI_AUTO_LENGTH, &instance)); + HcfFree(returnString); + return instance; +} + +static napi_value GetVerifySpecNumber(napi_env env, SignSpecItem item, HcfVerify *verify) +{ + int returnInt; + HcfResult res = verify->getVerifySpecInt(verify, item, &returnInt); + if (res != HCF_SUCCESS) { + napi_throw(env, GenerateBusinessError(env, res, "C getVerifySpecInt failed.")); + LOGE("c getVerifySpecInt fail."); + return nullptr; + } + + napi_value instance = nullptr; + NAPI_CALL(env, napi_create_int32(env, returnInt, &instance)); return instance; } +napi_value NapiVerify::JsGetVerifySpec(napi_env env, napi_callback_info info) +{ + napi_value thisVar = nullptr; + NapiVerify *napiVerify = nullptr; + // 入参只有一个,为item + size_t expectedArgc = ARGS_SIZE_ONE; + size_t argc = ARGS_SIZE_ONE; + napi_value argv[ARGS_SIZE_ONE] = { nullptr }; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr)); + if (argc != expectedArgc) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num.")); + LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc); + return nullptr; + } + SignSpecItem item; + if (napi_get_value_uint32(env, argv[0], reinterpret_cast(&item)) != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get getVerifySpecString failed!")); + LOGE("get getVerifySpecString failed!"); + return nullptr; + } + + napi_status status = napi_unwrap(env, thisVar, reinterpret_cast(&napiVerify)); + if (status != napi_ok) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiVerify obj!")); + LOGE("failed to unwrap napiVerify obj!"); + return nullptr; + } + HcfVerify *verify = napiVerify->GetVerify(); + if (verify == nullptr) { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get verify obj!")); + LOGE("failed to get verfiy obj!"); + return nullptr; + } + + int32_t type = GetSignSpecType(item); + if (type == SPEC_ITEM_TYPE_STR) { + return GetVerifySpecString(env, item, verify); + } else if (type == SPEC_ITEM_TYPE_NUM) { + return GetVerifySpecNumber(env, item, verify); + } else { + napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "VerifySpecItem not support!")); + return nullptr; + } +} + void NapiVerify::DefineVerifyJSClass(napi_env env, napi_value exports) { napi_property_descriptor desc[] = { @@ -682,6 +796,8 @@ void NapiVerify::DefineVerifyJSClass(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("init", NapiVerify::JsInit), DECLARE_NAPI_FUNCTION("update", NapiVerify::JsUpdate), DECLARE_NAPI_FUNCTION("verify", NapiVerify::JsVerify), + DECLARE_NAPI_FUNCTION("setVerifySpec", NapiVerify::JsSetVerifySpec), + DECLARE_NAPI_FUNCTION("getVerifySpec", NapiVerify::JsGetVerifySpec), }; napi_value constructor = nullptr; napi_define_class(env, "Verify", NAPI_AUTO_LENGTH, NapiVerify::VerifyConstructor, nullptr, diff --git a/frameworks/spi/signature_spi.h b/frameworks/spi/signature_spi.h index 971a07a5407a95d8b0826ef07352634cb662201a..f1cb9d25d919d70320e0b613247719620f2075d7 100644 --- a/frameworks/spi/signature_spi.h +++ b/frameworks/spi/signature_spi.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -21,6 +21,7 @@ #include "pri_key.h" #include "pub_key.h" #include "result.h" +#include "signature.h" #define OPENSSL_RSA_SIGN_CLASS "OPENSSL.RSA.SIGN" @@ -36,6 +37,12 @@ struct HcfSignSpi { HcfResult (*engineUpdate)(HcfSignSpi *self, HcfBlob *data); HcfResult (*engineSign)(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData); + + HcfResult (*engineSetSignSpecInt)(HcfSignSpi *self, SignSpecItem item, int32_t saltLen); + + HcfResult (*engineGetSignSpecString)(HcfSignSpi *self, SignSpecItem item, char **returnString); + + HcfResult (*engineGetSignSpecInt)(HcfSignSpi *self, SignSpecItem item, int32_t *returnInt); }; typedef struct HcfVerifySpi HcfVerifySpi; @@ -48,6 +55,12 @@ struct HcfVerifySpi { HcfResult (*engineUpdate)(HcfVerifySpi *self, HcfBlob *data); bool (*engineVerify)(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData); + + HcfResult (*engineSetVerifySpecInt)(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen); + + HcfResult (*engineGetVerifySpecString)(HcfVerifySpi *self, SignSpecItem item, char **returnString); + + HcfResult (*engineGetVerifySpecInt)(HcfVerifySpi *self, SignSpecItem item, int32_t *returnInt); }; #endif diff --git a/interfaces/innerkits/algorithm_parameter/detailed_dsa_key_params.h b/interfaces/innerkits/algorithm_parameter/detailed_dsa_key_params.h new file mode 100644 index 0000000000000000000000000000000000000000..3d1f31eb0acc8473a6a9e8ade6998121b7e70da7 --- /dev/null +++ b/interfaces/innerkits/algorithm_parameter/detailed_dsa_key_params.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 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 HCF_DETAILED_DSA_KEY_PARAMS_H +#define HCF_DETAILED_DSA_KEY_PARAMS_H + +#include "asy_key_params.h" +#include "big_integer.h" + +typedef struct HcfDsaCommParamsSpec HcfDsaCommParamsSpec; + +struct HcfDsaCommParamsSpec { + HcfAsyKeyParamsSpec base; + HcfBigInteger p; + HcfBigInteger q; + HcfBigInteger g; +}; + +typedef struct HcfDsaPubKeyParamsSpec HcfDsaPubKeyParamsSpec; + +struct HcfDsaPubKeyParamsSpec { + HcfDsaCommParamsSpec base; + HcfBigInteger pk; +}; + +typedef struct HcfDsaKeyPairParamsSpec HcfDsaKeyPairParamsSpec; + +struct HcfDsaKeyPairParamsSpec { + HcfDsaCommParamsSpec base; + HcfBigInteger pk; + HcfBigInteger sk; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +void FreeDsaCommParamsSpec(HcfDsaCommParamsSpec *spec); + +void DestroyDsaPubKeySpec(HcfDsaPubKeyParamsSpec *spec); + +void DestroyDsaKeyPairSpec(HcfDsaKeyPairParamsSpec *spec); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/interfaces/innerkits/crypto_operation/signature.h b/interfaces/innerkits/crypto_operation/signature.h index ea5b2be0e9485a8ed3e72866e4f5fe2405f3cc39..9186904a9d74545b571b612e8166a7782169de3a 100644 --- a/interfaces/innerkits/crypto_operation/signature.h +++ b/interfaces/innerkits/crypto_operation/signature.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Huawei Device Co., Ltd. + * Copyright (C) 2022-2023 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 @@ -22,6 +22,14 @@ #include "result.h" #include "key_pair.h" +typedef enum { + PSS_MD_NAME_STR = 100, + PSS_MGF_NAME_STR = 101, + PSS_MGF1_MD_STR = 102, + PSS_SALT_LEN_INT = 103, // warning: PSS_SALT_LEN_NUM in JS + PSS_TRAILER_FIELD_INT = 104, // warning: PSS_TRAILER_FIELD_NUM in JS +} SignSpecItem; + typedef struct HcfSign HcfSign; struct HcfSign { @@ -34,6 +42,12 @@ struct HcfSign { HcfResult (*sign)(HcfSign *self, HcfBlob *data, HcfBlob *returnSignatureData); const char *(*getAlgoName)(HcfSign *self); + + HcfResult (*setSignSpecInt)(HcfSign *self, SignSpecItem item, int32_t saltLen); + + HcfResult (*getSignSpecString)(HcfSign *self, SignSpecItem item, char **returnString); + + HcfResult (*getSignSpecInt)(HcfSign *self, SignSpecItem item, int32_t *returnInt); }; typedef struct HcfVerify HcfVerify; @@ -48,6 +62,12 @@ struct HcfVerify { bool (*verify)(HcfVerify *self, HcfBlob *data, HcfBlob *signatureData); const char *(*getAlgoName)(HcfVerify *self); + + HcfResult (*setVerifySpecInt)(HcfVerify *self, SignSpecItem item, int32_t saltLen); + + HcfResult (*getVerifySpecString)(HcfVerify *self, SignSpecItem item, char **returnString); + + HcfResult (*getVerifySpecInt)(HcfVerify *self, SignSpecItem item, int32_t *returnInt); }; #ifdef __cplusplus diff --git a/plugin/openssl_plugin/common/inc/openssl_adapter.h b/plugin/openssl_plugin/common/inc/openssl_adapter.h index cd066e89dd7d549f365249b781375bbaf08708b5..631a5157aaaa42fa07d5ac581b3dc1d9d7c96da4 100644 --- a/plugin/openssl_plugin/common/inc/openssl_adapter.h +++ b/plugin/openssl_plugin/common/inc/openssl_adapter.h @@ -20,6 +20,10 @@ #include #include #include +#include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -28,10 +32,24 @@ extern "C" { BIGNUM *Openssl_BN_dup(const BIGNUM *a); void Openssl_BN_clear(BIGNUM *a); void Openssl_BN_clear_free(BIGNUM *a); +BIGNUM *Openssl_BN_new(void); +void Openssl_BN_free(BIGNUM *a); +BIGNUM *Openssl_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +BIGNUM *Openssl_BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret); +int Openssl_BN_bn2binpad(const BIGNUM *a, unsigned char *to, int toLen); +int Openssl_BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int toLen); +BN_CTX *Openssl_BN_CTX_new(void); +void Openssl_BN_CTX_free(BN_CTX *ctx); +int Openssl_BN_num_bytes(const BIGNUM *a); +int Openssl_BN_set_word(BIGNUM *a, unsigned int w); +unsigned int Openssl_BN_get_word(const BIGNUM *a); +int Openssl_BN_num_bits(const BIGNUM *a); +int Openssl_BN_hex2bn(BIGNUM **a, const char *str); +int Openssl_BN_cmp(const BIGNUM *a, const BIGNUM *b); EC_KEY *Openssl_EC_KEY_new_by_curve_name(int nid); EC_POINT *Openssl_EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); -int Openssl_EC_KEY_generate_key(EC_KEY *eckey); +int Openssl_EC_KEY_generate_key(EC_KEY *ecKey); int Openssl_EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); int Openssl_EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key); int Openssl_EC_KEY_check_key(const EC_KEY *key); @@ -43,9 +61,31 @@ int Openssl_i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); EC_KEY *Openssl_d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length); EC_KEY *Openssl_d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); void Openssl_EC_KEY_set_asn1_flag(EC_KEY *key, int flag); -void Openssl_EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); +void Openssl_EC_KEY_set_enc_flags(EC_KEY *ecKey, unsigned int flags); void Openssl_EC_KEY_free(EC_KEY *key); void Openssl_EC_POINT_free(EC_POINT *point); +EC_GROUP *Openssl_EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +void Openssl_EC_GROUP_free(EC_GROUP *group); +EC_POINT *Openssl_EC_POINT_new(const EC_GROUP *group); +int Openssl_EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx); +int Openssl_EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor); +EC_KEY *Openssl_EC_KEY_new(void); +EC_KEY *Openssl_EC_KEY_dup(const EC_KEY *ecKey); +int Openssl_EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); +int Openssl_EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); +const EC_POINT *Openssl_EC_GROUP_get0_generator(const EC_GROUP *group); +int Openssl_EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, const EC_POINT *point, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx); +int Openssl_EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); +int Openssl_EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); +int Openssl_EC_GROUP_get_degree(const EC_GROUP *group); +EC_GROUP *Openssl_EC_GROUP_dup(const EC_GROUP *a); +void Openssl_EC_GROUP_set_curve_name(EC_GROUP *group, int nid); +int Openssl_EC_GROUP_get_curve_name(const EC_GROUP *group); +int Openssl_EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, const EC_POINT *point, + const BIGNUM *p_scalar, BN_CTX *ctx); EVP_MD_CTX *Openssl_EVP_MD_CTX_new(void); void Openssl_EVP_MD_CTX_free(EVP_MD_CTX *ctx); @@ -55,6 +95,12 @@ int Openssl_EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, size_t * int Openssl_EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); int Openssl_EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t count); int Openssl_EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, size_t siglen); +int Openssl_EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, + size_t tbslen); +int Openssl_EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen, const unsigned char *tbs, + size_t tbslen); EVP_PKEY *Openssl_EVP_PKEY_new(void); int Openssl_EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); @@ -66,8 +112,139 @@ int Openssl_EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); int Openssl_EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); void Openssl_EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); +// new added +int Openssl_EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int Openssl_EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int Openssl_EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); + +EVP_PKEY_CTX *Openssl_EVP_PKEY_CTX_new_id(int id, ENGINE *e); +int Openssl_EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits); +int Openssl_EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int Openssl_EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int Openssl_EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int Openssl_EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key); +DSA *Openssl_EVP_PKEY_get1_DSA(EVP_PKEY *pkey); +DSA *Openssl_DSA_new(void); +void Openssl_DSA_free(DSA *dsa); +int Openssl_DSA_up_ref(DSA *dsa); +int Openssl_DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g); +int Openssl_DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *pri_key); +const BIGNUM *Openssl_DSA_get0_p(const DSA *dsa); +const BIGNUM *Openssl_DSA_get0_q(const DSA *dsa); +const BIGNUM *Openssl_DSA_get0_g(const DSA *dsa); +const BIGNUM *Openssl_DSA_get0_pub_key(const DSA *dsa); +const BIGNUM *Openssl_DSA_get0_priv_key(const DSA *dsa); +int Openssl_DSA_generate_key(DSA *a); +DSA *Openssl_d2i_DSA_PUBKEY(DSA **dsa, const unsigned char **ppin, long length); +DSA *Openssl_d2i_DSAPrivateKey(DSA **dsa, const unsigned char **ppin, long length); +int Openssl_i2d_DSA_PUBKEY(DSA *dsa, unsigned char **ppout); +int Openssl_i2d_DSAPrivateKey(DSA *dsa, unsigned char **ppout); + +RSA *Openssl_RSA_new(void); +void Openssl_RSA_free(RSA *rsa); +int Openssl_RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes, + BIGNUM *e, BN_GENCB *cb); +int Openssl_RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +int Openssl_RSA_bits(const RSA *rsa); +int Openssl_RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); +void Openssl_RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); +const BIGNUM *Openssl_RSA_get0_n(const RSA *d); +const BIGNUM *Openssl_RSA_get0_e(const RSA *d); +const BIGNUM *Openssl_RSA_get0_d(const RSA *d); +void Openssl_RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); +RSA *Openssl_RSAPublicKey_dup(RSA *rsa); +RSA *Openssl_RSAPrivateKey_dup(RSA *rsa); +RSA *Openssl_d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length); +int Openssl_i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); +int Openssl_EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen); +int Openssl_EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen); +int Openssl_EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad); +int Openssl_EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int Openssl_EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md); +int Openssl_EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int len); +int Openssl_EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label); +EVP_PKEY *Openssl_d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, long length); +struct rsa_st *Openssl_EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +int Openssl_EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +int Openssl_EVP_PKEY_assign_RSA(EVP_PKEY *pkey, struct rsa_st *key); +int Openssl_i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u); +// BIO +BIO *Openssl_BIO_new(const BIO_METHOD *type); +const BIO_METHOD *Openssl_BIO_s_mem(void); +int Openssl_BIO_read(BIO *b, void *data, int dlen); +void Openssl_BIO_free_all(BIO *a); + +int Openssl_RAND_priv_bytes(unsigned char *buf, int num); +void Openssl_RAND_seed(const void *buf, int num); + +const EVP_MD *Openssl_EVP_sha1(void); +const EVP_MD *Openssl_EVP_sha224(void); +const EVP_MD *Openssl_EVP_sha256(void); +const EVP_MD *Openssl_EVP_sha384(void); +const EVP_MD *Openssl_EVP_sha512(void); +const EVP_MD *Openssl_EVP_md5(void); +int Openssl_EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size); +int Openssl_EVP_MD_CTX_size(const EVP_MD_CTX *ctx); +int Openssl_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); + +int Openssl_HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md, ENGINE *impl); +int Openssl_HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); +size_t Openssl_HMAC_size(const HMAC_CTX *ctx); +void Openssl_HMAC_CTX_free(HMAC_CTX *ctx); +HMAC_CTX *Openssl_HMAC_CTX_new(void); + +void Openssl_EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); +const EVP_CIPHER *Openssl_EVP_aes_128_ecb(void); +const EVP_CIPHER *Openssl_EVP_aes_192_ecb(void); +const EVP_CIPHER *Openssl_EVP_aes_256_ecb(void); +const EVP_CIPHER *Openssl_EVP_aes_128_cbc(void); +const EVP_CIPHER *Openssl_EVP_aes_192_cbc(void); +const EVP_CIPHER *Openssl_EVP_aes_256_cbc(void); +const EVP_CIPHER *Openssl_EVP_aes_128_ctr(void); +const EVP_CIPHER *Openssl_EVP_aes_192_ctr(void); +const EVP_CIPHER *Openssl_EVP_aes_256_ctr(void); +const EVP_CIPHER *Openssl_EVP_aes_128_ofb(void); +const EVP_CIPHER *Openssl_EVP_aes_192_ofb(void); +const EVP_CIPHER *Openssl_EVP_aes_256_ofb(void); +const EVP_CIPHER *Openssl_EVP_aes_128_cfb(void); +const EVP_CIPHER *Openssl_EVP_aes_192_cfb(void); +const EVP_CIPHER *Openssl_EVP_aes_256_cfb(void); +const EVP_CIPHER *Openssl_EVP_aes_128_cfb1(void); +const EVP_CIPHER *Openssl_EVP_aes_192_cfb1(void); +const EVP_CIPHER *Openssl_EVP_aes_256_cfb1(void); +const EVP_CIPHER *Openssl_EVP_aes_128_cfb128(void); +const EVP_CIPHER *Openssl_EVP_aes_192_cfb128(void); +const EVP_CIPHER *Openssl_EVP_aes_256_cfb128(void); +const EVP_CIPHER *Openssl_EVP_aes_128_cfb8(void); +const EVP_CIPHER *Openssl_EVP_aes_192_cfb8(void); +const EVP_CIPHER *Openssl_EVP_aes_256_cfb8(void); +const EVP_CIPHER *Openssl_EVP_aes_128_ccm(void); +const EVP_CIPHER *Openssl_EVP_aes_192_ccm(void); +const EVP_CIPHER *Openssl_EVP_aes_256_ccm(void); +const EVP_CIPHER *Openssl_EVP_aes_128_gcm(void); +const EVP_CIPHER *Openssl_EVP_aes_192_gcm(void); +const EVP_CIPHER *Openssl_EVP_aes_256_gcm(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_ecb(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_cbc(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_ofb(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_cfb64(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_cfb1(void); +const EVP_CIPHER *Openssl_EVP_des_ede3_cfb8(void); +EVP_CIPHER_CTX *Openssl_EVP_CIPHER_CTX_new(void); +int Openssl_EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc); +int Openssl_EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad); +int Openssl_EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int Openssl_EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +int Openssl_EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl); + #ifdef __cplusplus } #endif -#endif +#endif \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/signature/inc/dsa_openssl.h b/plugin/openssl_plugin/crypto_operation/signature/inc/dsa_openssl.h new file mode 100644 index 0000000000000000000000000000000000000000..a7df21f701029acab509e694ad766aa712c94beb --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/signature/inc/dsa_openssl.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2023 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 HCF_DSA_OPENSSL_H +#define HCF_DSA_OPENSSL_H + +#include "signature_spi.h" +#include "params_parser.h" +#include "result.h" + +#ifdef __cplusplus +extern "C" { +#endif + +HcfResult HcfSignSpiDsaCreate(HcfSignatureParams *params, HcfSignSpi **returnObj); +HcfResult HcfVerifySpiDsaCreate(HcfSignatureParams *params, HcfVerifySpi **returnObj); + +#ifdef __cplusplus +} +#endif +#endif \ No newline at end of file diff --git a/plugin/openssl_plugin/crypto_operation/signature/src/dsa_openssl.c b/plugin/openssl_plugin/crypto_operation/signature/src/dsa_openssl.c new file mode 100644 index 0000000000000000000000000000000000000000..479f26650c40f5b6d39840cd831f39a0ef3fd1c9 --- /dev/null +++ b/plugin/openssl_plugin/crypto_operation/signature/src/dsa_openssl.c @@ -0,0 +1,623 @@ +/* + * Copyright (C) 2023 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 "dsa_openssl.h" + +#include + +#include "log.h" +#include "memory.h" +#include "openssl_adapter.h" +#include "openssl_common.h" +#include "openssl_class.h" +#include "utils.h" + +#define OPENSSL_DSA_SIGN_CLASS "OPENSSL.DSA.SIGN" +#define OPENSSL_DSA_VERIFY_CLASS "OPENSSL.DSA.VERIFY" + +typedef struct { + HcfSignSpi base; + + const EVP_MD *digestAlg; + + EVP_MD_CTX *mdCtx; + + EVP_PKEY_CTX *pkeyCtx; + + CryptoStatus status; +} HcfSignSpiDsaOpensslImpl; + +typedef struct { + HcfVerifySpi base; + + const EVP_MD *digestAlg; + + EVP_MD_CTX *mdCtx; + + EVP_PKEY_CTX *pkeyCtx; + + CryptoStatus status; +} HcfVerifySpiDsaOpensslImpl; + +static const char *GetDsaSignClass(void) +{ + return OPENSSL_DSA_SIGN_CLASS; +} + +static const char *GetDsaVerifyClass(void) +{ + return OPENSSL_DSA_VERIFY_CLASS; +} + +static bool IsSignInitInputValid(HcfSignSpi *self, HcfPriKey *privateKey) +{ + if ((self == NULL) || (privateKey == NULL)) { + LOGE("Invalid input parameter."); + return false; + } + if ((!IsClassMatch((HcfObjectBase *)self, GetDsaSignClass())) || + (!IsClassMatch((HcfObjectBase *)privateKey, OPENSSL_DSA_PRIKEY_CLASS))) { + return false; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (impl->status != UNINITIALIZED) { + LOGE("Repeated initialization is not allowed."); + return false; + } + return true; +} + +static bool IsVerifyInitInputValid(HcfVerifySpi *self, HcfPubKey *publicKey) +{ + if ((self == NULL) || (publicKey == NULL)) { + LOGE("Invalid input parameter."); + return false; + } + if ((!IsClassMatch((HcfObjectBase *)self, GetDsaVerifyClass())) || + (!IsClassMatch((HcfObjectBase *)publicKey, OPENSSL_DSA_PUBKEY_CLASS))) { + return false; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + if (impl->status != UNINITIALIZED) { + LOGE("Repeated initialization is not allowed."); + return false; + } + return true; +} + +static bool IsSignDoFinalInputValid(HcfSignSpi *self, HcfBlob *returnSignatureData) +{ + if ((self == NULL) || (returnSignatureData == NULL)) { + LOGE("Invalid input parameter."); + return false; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaSignClass())) { + return false; + } + return true; +} + +static bool IsVerifyDoFinalInputValid(HcfVerifySpi *self, HcfBlob *signatureData) +{ + if ((self == NULL) || (!IsBlobValid(signatureData))) { + LOGE("Invalid input parameter."); + return false; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaVerifyClass())) { + return false; + } + return true; +} + +static void DestroyDsaSign(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + + if (!IsClassMatch(self, GetDsaSignClass())) { + return; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (impl->mdCtx != NULL) { + Openssl_EVP_MD_CTX_free(impl->mdCtx); + impl->mdCtx = NULL; + } + if (impl->pkeyCtx != NULL) { + Openssl_EVP_PKEY_CTX_free(impl->pkeyCtx); + impl->pkeyCtx = NULL; + } + HcfFree(impl); +} + +static void DestroyDsaVerify(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetDsaVerifyClass())) { + return; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + if (impl->mdCtx != NULL) { + Openssl_EVP_MD_CTX_free(impl->mdCtx); + impl->mdCtx = NULL; + } + if (impl->pkeyCtx != NULL) { + Openssl_EVP_PKEY_CTX_free(impl->pkeyCtx); + impl->pkeyCtx = NULL; + } + HcfFree(impl); +} + +static EVP_PKEY *CreateDsaEvpKeyByDsa(HcfKey *key, bool isSign) +{ + EVP_PKEY *pKey = Openssl_EVP_PKEY_new(); + if (pKey == NULL) { + LOGE("EVP_PKEY_new fail"); + HcfPrintOpensslError(); + return NULL; + } + DSA *dsa = isSign ? ((HcfOpensslDsaPriKey *)key)->sk : ((HcfOpensslDsaPubKey *)key)->pk; + if (Openssl_EVP_PKEY_set1_DSA(pKey, dsa) != HCF_OPENSSL_SUCCESS) { + LOGE("EVP_PKEY_set1_DSA fail"); + HcfPrintOpensslError(); + EVP_PKEY_free(pKey); + return NULL; + } + return pKey; +} + +static HcfResult EngineDsaSignInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey) +{ + (void)params; + if (!IsSignInitInputValid(self, privateKey)) { + return HCF_INVALID_PARAMS; + } + EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)privateKey, true); + if (pKey == NULL) { + LOGE("Create DSA evp key failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (Openssl_EVP_DigestSignInit(impl->mdCtx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + + Openssl_EVP_PKEY_free(pKey); + impl->status = INITIALIZED; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaSignWithoutDigestInit(HcfSignSpi *self, HcfParamsSpec *params, HcfPriKey *privateKey) +{ + (void)params; + if (!IsSignInitInputValid(self, privateKey)) { + return HCF_INVALID_PARAMS; + } + EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)privateKey, true); + if (pKey == NULL) { + LOGE("Create DSA evp key failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + + impl->pkeyCtx = Openssl_EVP_PKEY_CTX_new(pKey, NULL); + if (impl->pkeyCtx == NULL) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_PKEY_sign_init(impl->pkeyCtx) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + Openssl_EVP_PKEY_CTX_free(impl->pkeyCtx); + impl->pkeyCtx = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EVP_PKEY_free(pKey); + impl->status = READY; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaVerifyInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey) +{ + (void)params; + if (!IsVerifyInitInputValid(self, publicKey)) { + return HCF_INVALID_PARAMS; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)publicKey, false); + if (pKey == NULL) { + LOGE("Create DSA evp key failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_DigestVerifyInit(impl->mdCtx, NULL, impl->digestAlg, NULL, pKey) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + + Openssl_EVP_PKEY_free(pKey); + impl->status = INITIALIZED; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaVerifyWithoutDigestInit(HcfVerifySpi *self, HcfParamsSpec *params, HcfPubKey *publicKey) +{ + (void)params; + if (!IsVerifyInitInputValid(self, publicKey)) { + return HCF_INVALID_PARAMS; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + EVP_PKEY *pKey = CreateDsaEvpKeyByDsa((HcfKey *)publicKey, false); + if (pKey == NULL) { + LOGE("Create dsa evp key failed!"); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->pkeyCtx = Openssl_EVP_PKEY_CTX_new(pKey, NULL); + if (impl->pkeyCtx == NULL) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_EVP_PKEY_verify_init(impl->pkeyCtx) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + Openssl_EVP_PKEY_free(pKey); + Openssl_EVP_PKEY_CTX_free(impl->pkeyCtx); + impl->pkeyCtx = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + Openssl_EVP_PKEY_free(pKey); + impl->status = READY; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaSignUpdate(HcfSignSpi *self, HcfBlob *data) +{ + if ((self == NULL) || (!IsBlobValid(data))) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaSignClass())) { + return HCF_INVALID_PARAMS; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (impl->status == UNINITIALIZED) { + LOGE("Sign object has not been initialized."); + return HCF_INVALID_PARAMS; + } + if (Openssl_EVP_DigestSignUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->status = READY; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaSignWithoutDigestUpdate(HcfSignSpi *self, HcfBlob *data) +{ + (void)self; + (void)data; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaVerifyUpdate(HcfVerifySpi *self, HcfBlob *data) +{ + if ((self == NULL) || (!IsBlobValid(data))) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaVerifyClass())) { + return HCF_INVALID_PARAMS; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + if (impl->status == UNINITIALIZED) { + LOGE("Verify object has not been initialized."); + return HCF_INVALID_PARAMS; + } + + if (Openssl_EVP_DigestVerifyUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->status = READY; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaVerifyWithoutDigestUpdate(HcfVerifySpi *self, HcfBlob *data) +{ + (void)self; + (void)data; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaSignDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData) +{ + if (!IsSignDoFinalInputValid(self, returnSignatureData)) { + return HCF_INVALID_PARAMS; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (IsBlobValid(data)) { + if (Openssl_EVP_DigestSignUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + impl->status = READY; + } + if (impl->status != READY) { + LOGE("The message has not been transferred."); + return HCF_INVALID_PARAMS; + } + size_t maxLen; + if (Openssl_EVP_DigestSignFinal(impl->mdCtx, NULL, &maxLen) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + uint8_t *signatureData = (uint8_t *)HcfMalloc(maxLen, 0); + if (signatureData == NULL) { + LOGE("Failed to allocate signatureData memory!"); + return HCF_ERR_MALLOC; + } + size_t actualLen = maxLen; + if (Openssl_EVP_DigestSignFinal(impl->mdCtx, signatureData, &actualLen) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + HcfFree(signatureData); + return HCF_ERR_CRYPTO_OPERATION; + } + if (actualLen > maxLen) { + LOGE("Signature data too long."); + HcfFree(signatureData); + return HCF_ERR_CRYPTO_OPERATION; + } + + returnSignatureData->data = signatureData; + returnSignatureData->len = (uint32_t)actualLen; + return HCF_SUCCESS; +} + +static HcfResult EngineDsaSignWithoutDigestDoFinal(HcfSignSpi *self, HcfBlob *data, HcfBlob *returnSignatureData) +{ + if (!IsSignDoFinalInputValid(self, returnSignatureData)) { + return HCF_INVALID_PARAMS; + } + if (!IsBlobValid(data)) { + LOGE("Src data is invalid."); + return HCF_INVALID_PARAMS; + } + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)self; + if (impl->status != READY) { + LOGE("Not init yet."); + return HCF_INVALID_PARAMS; + } + size_t maxLen; + if (Openssl_EVP_PKEY_sign(impl->pkeyCtx, NULL, &maxLen, + (const unsigned char *)data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + uint8_t *signatureData = (uint8_t *)HcfMalloc(maxLen, 0); + if (signatureData == NULL) { + LOGE("Failed to allocate signatureData memory!"); + return HCF_ERR_MALLOC; + } + size_t actualLen = maxLen; + if (Openssl_EVP_PKEY_sign(impl->pkeyCtx, signatureData, &actualLen, + (const unsigned char *)data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + HcfFree(signatureData); + return HCF_ERR_CRYPTO_OPERATION; + } + if (actualLen > maxLen) { + LOGE("Signature data too long."); + HcfFree(signatureData); + return HCF_ERR_CRYPTO_OPERATION; + } + + returnSignatureData->data = signatureData; + returnSignatureData->len = (uint32_t)actualLen; + return HCF_SUCCESS; +} + +static bool EngineDsaVerifyDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData) +{ + if (!IsVerifyDoFinalInputValid(self, signatureData)) { + return false; + } + + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + if (IsBlobValid(data)) { + if (Openssl_EVP_DigestVerifyUpdate(impl->mdCtx, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl update failed."); + HcfPrintOpensslError(); + return false; + } + impl->status = READY; + } + if (impl->status != READY) { + LOGE("The message has not been transferred."); + return false; + } + + if (Openssl_EVP_DigestVerifyFinal(impl->mdCtx, signatureData->data, signatureData->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return false; + } + return true; +} + +static bool EngineDsaVerifyWithoutDigestDoFinal(HcfVerifySpi *self, HcfBlob *data, HcfBlob *signatureData) +{ + if (!IsVerifyDoFinalInputValid(self, signatureData)) { + return false; + } + if (!IsBlobValid(data)) { + LOGE("Src data is invalid."); + return false; + } + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)self; + if (impl->status != READY) { + LOGE("Not init yet."); + return false; + } + + if (Openssl_EVP_PKEY_verify(impl->pkeyCtx, signatureData->data, + signatureData->len, data->data, data->len) != HCF_OPENSSL_SUCCESS) { + HcfPrintOpensslError(); + return false; + } + return true; +} + +HcfResult EngineSetSignDsaSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t saltLen) +{ + (void)self; + (void)item; + (void)saltLen; + return HCF_NOT_SUPPORT; +} + +HcfResult EngineSetVerifyDsaSpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t saltLen) +{ + (void)self; + (void)item; + (void)saltLen; + return HCF_NOT_SUPPORT; +} + +HcfResult EngineGetSignDsaSpecInt(HcfSignSpi *self, SignSpecItem item, int32_t *returnInt) +{ + (void)self; + (void)item; + (void)returnInt; + return HCF_NOT_SUPPORT; +} + +HcfResult EngineGetVerifyDsaSpecInt(HcfVerifySpi *self, SignSpecItem item, int32_t *returnInt) +{ + (void)self; + (void)item; + (void)returnInt; + return HCF_NOT_SUPPORT; +} + +HcfResult EngineGetSignDsaSpecString(HcfSignSpi *self, SignSpecItem item, char **returnString) +{ + (void)self; + (void)item; + (void)returnString; + return HCF_NOT_SUPPORT; +} + +HcfResult EngineGetVerifyDsaSpecString(HcfVerifySpi *self, SignSpecItem item, char **returnString) +{ + (void)self; + (void)item; + (void)returnString; + return HCF_NOT_SUPPORT; +} + +HcfResult HcfSignSpiDsaCreate(HcfSignatureParams *params, HcfSignSpi **returnObj) +{ + if ((params == NULL) || (returnObj == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + + HcfSignSpiDsaOpensslImpl *impl = (HcfSignSpiDsaOpensslImpl *)HcfMalloc(sizeof(HcfSignSpiDsaOpensslImpl), 0); + if (impl == NULL) { + LOGE("Failed to allocate impl memroy!"); + return HCF_ERR_MALLOC; + } + + EVP_MD *digestAlg = NULL; + + if (params->md == HCF_OPENSSL_DIGEST_NONE) { + impl->base.engineInit = EngineDsaSignWithoutDigestInit; + impl->base.engineUpdate = EngineDsaSignWithoutDigestUpdate; + impl->base.engineSign = EngineDsaSignWithoutDigestDoFinal; + } else { + HcfResult ret = GetOpensslDigestAlg(params->md, &digestAlg); + if (ret != HCF_SUCCESS) { + HcfFree(impl); + return HCF_INVALID_PARAMS; + } + impl->base.engineInit = EngineDsaSignInit; + impl->base.engineUpdate = EngineDsaSignUpdate; + impl->base.engineSign = EngineDsaSignDoFinal; + impl->mdCtx = Openssl_EVP_MD_CTX_new(); + if (impl->mdCtx == NULL) { + LOGE("Failed to allocate ctx memory!"); + HcfFree(impl); + return HCF_ERR_MALLOC; + } + } + impl->base.base.getClass = GetDsaSignClass; + impl->base.base.destroy = DestroyDsaSign; + impl->base.engineSetSignSpecInt = EngineSetSignDsaSpecInt; + impl->base.engineGetSignSpecInt = EngineGetSignDsaSpecInt; + impl->base.engineGetSignSpecString = EngineGetSignDsaSpecString; + impl->status = UNINITIALIZED; + impl->digestAlg = digestAlg; + *returnObj = (HcfSignSpi *)impl; + return HCF_SUCCESS; +} + +HcfResult HcfVerifySpiDsaCreate(HcfSignatureParams *params, HcfVerifySpi **returnObj) +{ + if ((params == NULL) || (returnObj == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + + HcfVerifySpiDsaOpensslImpl *impl = (HcfVerifySpiDsaOpensslImpl *)HcfMalloc(sizeof(HcfVerifySpiDsaOpensslImpl), 0); + if (impl == NULL) { + LOGE("Failed to allocate impl memroy!"); + return HCF_ERR_MALLOC; + } + + EVP_MD *digestAlg = NULL; + if (params->md == HCF_OPENSSL_DIGEST_NONE) { + impl->base.engineInit = EngineDsaVerifyWithoutDigestInit; + impl->base.engineUpdate = EngineDsaVerifyWithoutDigestUpdate; + impl->base.engineVerify = EngineDsaVerifyWithoutDigestDoFinal; + } else { + HcfResult ret = GetOpensslDigestAlg(params->md, &digestAlg); + if (ret != HCF_SUCCESS) { + return HCF_INVALID_PARAMS; + } + impl->base.engineInit = EngineDsaVerifyInit; + impl->base.engineUpdate = EngineDsaVerifyUpdate; + impl->base.engineVerify = EngineDsaVerifyDoFinal; + impl->mdCtx = Openssl_EVP_MD_CTX_new(); + if (impl->mdCtx == NULL) { + LOGE("Failed to allocate ctx memory!"); + HcfFree(impl); + return HCF_ERR_MALLOC; + } + } + impl->base.base.getClass = GetDsaVerifyClass; + impl->base.base.destroy = DestroyDsaVerify; + impl->base.engineSetVerifySpecInt = EngineSetVerifyDsaSpecInt; + impl->base.engineGetVerifySpecInt = EngineGetVerifyDsaSpecInt; + impl->base.engineGetVerifySpecString = EngineGetVerifyDsaSpecString; + impl->digestAlg = digestAlg; + impl->status = UNINITIALIZED; + + *returnObj = (HcfVerifySpi *)impl; + return HCF_SUCCESS; +} \ No newline at end of file diff --git a/plugin/openssl_plugin/key/asy_key_generator/inc/dsa_asy_key_generator_openssl.h b/plugin/openssl_plugin/key/asy_key_generator/inc/dsa_asy_key_generator_openssl.h new file mode 100644 index 0000000000000000000000000000000000000000..f33e3de424e837df6575e1fe96403a0bc35c06a6 --- /dev/null +++ b/plugin/openssl_plugin/key/asy_key_generator/inc/dsa_asy_key_generator_openssl.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2023 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 HCF_DSA_ASY_KEY_GENERATOR_OPENSSL_H +#define HCF_DSA_ASY_KEY_GENERATOR_OPENSSL_H + +#include "asy_key_generator_spi.h" +#include "params_parser.h" +#include "result.h" + +#ifdef __cplusplus +extern "C" { +#endif + +HcfResult HcfAsyKeyGeneratorSpiDsaCreate(HcfAsyKeyGenParams *params, HcfAsyKeyGeneratorSpi **returnObj); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/plugin/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c b/plugin/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c new file mode 100644 index 0000000000000000000000000000000000000000..0adde210a35c5dc4ba4fffbf41e173c7537a66a4 --- /dev/null +++ b/plugin/openssl_plugin/key/asy_key_generator/src/dsa_asy_key_generator_openssl.c @@ -0,0 +1,966 @@ +/* + * Copyright (C) 2023 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 "dsa_asy_key_generator_openssl.h" + +#include +#include +#include + +#include "detailed_dsa_key_params.h" +#include "log.h" +#include "memory.h" +#include "openssl_adapter.h" +#include "openssl_class.h" +#include "openssl_common.h" +#include "utils.h" + +#define OPENSSL_DSA_GENERATOR_CLASS "OPENSSL.DSA.KEYGENERATOR" +#define OPENSSL_DSA_PUBKEY_FORMAT "X.509" +#define OPENSSL_DSA_PRIKEY_FORMAT "PKCS#8" +#define ALGORITHM_NAME_DSA "DSA" + +typedef struct { + HcfAsyKeyGeneratorSpi base; + + int32_t bits; +} HcfAsyKeyGeneratorSpiDsaOpensslImpl; + +static void FreeCtx(EVP_PKEY_CTX *paramsCtx, EVP_PKEY *paramsPkey, EVP_PKEY_CTX *pkeyCtx) +{ + if (paramsCtx != NULL) { + Openssl_EVP_PKEY_CTX_free(paramsCtx); + } + if (paramsPkey != NULL) { + Openssl_EVP_PKEY_free(paramsPkey); + } + if (pkeyCtx != NULL) { + Openssl_EVP_PKEY_CTX_free(pkeyCtx); + } +} + +static void FreeCommSpecBn(BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + if (p != NULL) { + Openssl_BN_free(p); + } + if (q != NULL) { + Openssl_BN_free(q); + } + if (g != NULL) { + Openssl_BN_free(g); + } +} + +static const char *GetDsaKeyGeneratorSpiClass(void) +{ + return OPENSSL_DSA_GENERATOR_CLASS; +} + +static const char *GetDsaKeyPairClass(void) +{ + return OPENSSL_DSA_KEYPAIR_CLASS; +} + +static const char *GetDsaPubKeyClass(void) +{ + return OPENSSL_DSA_PUBKEY_CLASS; +} + +static const char *GetDsaPriKeyClass(void) +{ + return OPENSSL_DSA_PRIKEY_CLASS; +} + +static void DestroyDsaKeyGeneratorSpiImpl(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetDsaKeyGeneratorSpiClass())) { + return; + } + HcfFree(self); +} + +static void DestroyDsaPubKey(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetDsaPubKeyClass())) { + return; + } + HcfOpensslDsaPubKey *impl = (HcfOpensslDsaPubKey *)self; + Openssl_DSA_free(impl->pk); + impl->pk = NULL; + HcfFree(impl); +} + +static void DestroyDsaPriKey(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetDsaPriKeyClass())) { + return; + } + HcfOpensslDsaPriKey *impl = (HcfOpensslDsaPriKey *)self; + Openssl_DSA_free(impl->sk); + impl->sk = NULL; + HcfFree(impl); +} + +static void DestroyDsaKeyPair(HcfObjectBase *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch(self, GetDsaKeyPairClass())) { + return; + } + HcfOpensslDsaKeyPair *impl = (HcfOpensslDsaKeyPair *)self; + DestroyDsaPubKey((HcfObjectBase *)impl->base.pubKey); + impl->base.pubKey = NULL; + DestroyDsaPriKey((HcfObjectBase *)impl->base.priKey); + impl->base.priKey = NULL; + HcfFree(self); +} + +static const char *GetDsaPubKeyAlgorithm(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPubKeyClass())) { + return NULL; + } + return ALGORITHM_NAME_DSA; +} + +static const char *GetDsaPriKeyAlgorithm(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPriKeyClass())) { + return NULL; + } + return ALGORITHM_NAME_DSA; +} + +static HcfResult GetDsaPubKeyEncoded(HcfKey *self, HcfBlob *returnBlob) +{ + if ((self == NULL) || (returnBlob == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPubKeyClass())) { + return HCF_INVALID_PARAMS; + } + HcfOpensslDsaPubKey *impl = (HcfOpensslDsaPubKey *)self; + unsigned char *returnData = NULL; + int len = Openssl_i2d_DSA_PUBKEY(impl->pk, &returnData); + if (len <= 0) { + LOGE("Call i2d_DSA_PUBKEY failed"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + returnBlob->data = returnData; + returnBlob->len = len; + return HCF_SUCCESS; +} + +static HcfResult GetDsaPriKeyEncoded(HcfKey *self, HcfBlob *returnBlob) +{ + if ((self == NULL) || (returnBlob == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPriKeyClass())) { + return HCF_INVALID_PARAMS; + } + HcfOpensslDsaPriKey *impl = (HcfOpensslDsaPriKey *)self; + unsigned char *returnData = NULL; + int len = Openssl_i2d_DSAPrivateKey(impl->sk, &returnData); + if (len <= 0) { + LOGE("Call i2d_DSAPrivateKey failed."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + returnBlob->data = returnData; + returnBlob->len = len; + return HCF_SUCCESS; +} + +static const char *GetDsaPubKeyFormat(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPubKeyClass())) { + return NULL; + } + return OPENSSL_DSA_PUBKEY_FORMAT; +} + +static const char *GetDsaPriKeyFormat(HcfKey *self) +{ + if (self == NULL) { + LOGE("Invalid input parameter."); + return NULL; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPriKeyClass())) { + return NULL; + } + return OPENSSL_DSA_PRIKEY_FORMAT; +} + +static HcfResult GetBigIntegerSpecFromDsaPubKey(const HcfPubKey *self, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger) +{ + if (self == NULL || returnBigInteger == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPubKeyClass())) { + LOGE("Invalid class of self."); + return HCF_INVALID_PARAMS; + } + HcfResult ret = HCF_SUCCESS; + HcfOpensslDsaPubKey *impl = (HcfOpensslDsaPubKey *)self; + DSA *dsaPk = impl->pk; + if (dsaPk == NULL) { + return HCF_INVALID_PARAMS; + } + switch (item) { + case DSA_P_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_p(dsaPk), returnBigInteger); + break; + case DSA_Q_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_q(dsaPk), returnBigInteger); + break; + case DSA_G_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_g(dsaPk), returnBigInteger); + break; + case DSA_PK_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_pub_key(dsaPk), returnBigInteger); + break; + default: + LOGE("Input item is invalid"); + ret = HCF_INVALID_PARAMS; + break; + } + return ret; +} + +static HcfResult GetBigIntegerSpecFromDsaPriKey(const HcfPriKey *self, const AsyKeySpecItem item, + HcfBigInteger *returnBigInteger) +{ + if (self == NULL || returnBigInteger == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPriKeyClass())) { + LOGE("Invalid class of self."); + return HCF_INVALID_PARAMS; + } + HcfResult ret = HCF_SUCCESS; + HcfOpensslDsaPriKey *impl = (HcfOpensslDsaPriKey *)self; + DSA *dsaSk = impl->sk; + if (dsaSk == NULL) { + return HCF_INVALID_PARAMS; + } + switch (item) { + case DSA_P_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_p(dsaSk), returnBigInteger); + break; + case DSA_Q_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_q(dsaSk), returnBigInteger); + break; + case DSA_G_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_g(dsaSk), returnBigInteger); + break; + case DSA_SK_BN: + ret = BigNumToBigInteger(Openssl_DSA_get0_priv_key(dsaSk), returnBigInteger); + break; + default: + LOGE("Input item is invalid"); + ret = HCF_INVALID_PARAMS; + break; + } + return ret; +} + +static HcfResult GetIntSpecFromDsaPubKey(const HcfPubKey *self, const AsyKeySpecItem item, int *returnInt) +{ + (void)self; + (void)returnInt; + return HCF_NOT_SUPPORT; +} + +static HcfResult GetIntSpecFromDsaPriKey(const HcfPriKey *self, const AsyKeySpecItem item, int *returnInt) +{ + (void)self; + (void)returnInt; + return HCF_NOT_SUPPORT; +} + +static HcfResult GetStrSpecFromDsaPubKey(const HcfPubKey *self, const AsyKeySpecItem item, char **returnString) +{ + (void)self; + (void)returnString; + return HCF_NOT_SUPPORT; +} + +static HcfResult GetStrSpecFromDsaPriKey(const HcfPriKey *self, const AsyKeySpecItem item, char **returnString) +{ + (void)self; + (void)returnString; + return HCF_NOT_SUPPORT; +} + +static void ClearDsaPriKeyMem(HcfPriKey *self) +{ + if (self == NULL) { + return; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaPriKeyClass())) { + return; + } + HcfOpensslDsaPriKey *impl = (HcfOpensslDsaPriKey *)self; + Openssl_DSA_free(impl->sk); + impl->sk = NULL; +} + +static HcfResult GenerateDsaEvpKey(int32_t keyLen, EVP_PKEY **ppkey) +{ + EVP_PKEY_CTX *paramsCtx = NULL; + EVP_PKEY *paramsPkey = NULL; + EVP_PKEY_CTX *pkeyCtx = NULL; + HcfResult ret = HCF_SUCCESS; + do { + paramsCtx = Openssl_EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL); + if (paramsCtx == NULL) { + LOGE("Create params ctx failed."); + ret = HCF_ERR_MALLOC; + break; + } + if (Openssl_EVP_PKEY_paramgen_init(paramsCtx) != HCF_OPENSSL_SUCCESS) { + LOGE("Params ctx generate init failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + if (Openssl_EVP_PKEY_CTX_set_dsa_paramgen_bits(paramsCtx, keyLen) <= 0) { + LOGE("Set length of bits to params ctx failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + if (Openssl_EVP_PKEY_paramgen(paramsCtx, ¶msPkey) != HCF_OPENSSL_SUCCESS) { + LOGE("Generate params pkey failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + pkeyCtx = Openssl_EVP_PKEY_CTX_new(paramsPkey, NULL); + if (pkeyCtx == NULL) { + LOGE("Create pkey ctx failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + if (Openssl_EVP_PKEY_keygen_init(pkeyCtx) != HCF_OPENSSL_SUCCESS) { + LOGE("Key ctx generate init failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + if (Openssl_EVP_PKEY_keygen(pkeyCtx, ppkey) != HCF_OPENSSL_SUCCESS) { + LOGE("Generate pkey failed."); + ret = HCF_ERR_CRYPTO_OPERATION; + break; + } + } while (0); + FreeCtx(paramsCtx, paramsPkey, pkeyCtx); + return ret; +} + +static void FillOpensslDsaPubKeyFunc(HcfOpensslDsaPubKey *pk) +{ + pk->base.base.base.destroy = DestroyDsaPubKey; + pk->base.base.base.getClass = GetDsaPubKeyClass; + pk->base.base.getAlgorithm = GetDsaPubKeyAlgorithm; + pk->base.base.getEncoded = GetDsaPubKeyEncoded; + pk->base.base.getFormat = GetDsaPubKeyFormat; + pk->base.getAsyKeySpecBigInteger = GetBigIntegerSpecFromDsaPubKey; + pk->base.getAsyKeySpecInt = GetIntSpecFromDsaPubKey; + pk->base.getAsyKeySpecString = GetStrSpecFromDsaPubKey; +} + +static void FillOpensslDsaPriKeyFunc(HcfOpensslDsaPriKey *sk) +{ + sk->base.base.base.destroy = DestroyDsaPriKey; + sk->base.base.base.getClass = GetDsaPriKeyClass; + sk->base.base.getAlgorithm = GetDsaPriKeyAlgorithm; + sk->base.base.getEncoded = GetDsaPriKeyEncoded; + sk->base.base.getFormat = GetDsaPriKeyFormat; + sk->base.getAsyKeySpecBigInteger = GetBigIntegerSpecFromDsaPriKey; + sk->base.getAsyKeySpecInt = GetIntSpecFromDsaPriKey; + sk->base.getAsyKeySpecString = GetStrSpecFromDsaPriKey; + sk->base.clearMem = ClearDsaPriKeyMem; +} + +static HcfResult CreateDsaPubKey(DSA *pk, HcfOpensslDsaPubKey **returnPubKey) +{ + HcfOpensslDsaPubKey *dsaPubKey = (HcfOpensslDsaPubKey *)HcfMalloc(sizeof(HcfOpensslDsaPubKey), 0); + if (dsaPubKey == NULL) { + LOGE("Failed to allocate DSA public key memory."); + return HCF_ERR_MALLOC; + } + FillOpensslDsaPubKeyFunc(dsaPubKey); + dsaPubKey->pk = pk; + + *returnPubKey = dsaPubKey; + return HCF_SUCCESS; +} + +static HcfResult CreateDsaPriKey(DSA *sk, HcfOpensslDsaPriKey **returnPriKey) +{ + HcfOpensslDsaPriKey *dsaPriKey = (HcfOpensslDsaPriKey *)HcfMalloc(sizeof(HcfOpensslDsaPriKey), 0); + if (dsaPriKey == NULL) { + LOGE("Failed to allocate DSA private key memory."); + return HCF_ERR_MALLOC; + } + FillOpensslDsaPriKeyFunc(dsaPriKey); + dsaPriKey->sk = sk; + + *returnPriKey = dsaPriKey; + return HCF_SUCCESS; +} + +static HcfResult CreateDsaKeyPair(const HcfOpensslDsaPubKey *pubKey, const HcfOpensslDsaPriKey *priKey, + HcfKeyPair **returnKeyPair) +{ + HcfOpensslDsaKeyPair *keyPair = (HcfOpensslDsaKeyPair *)HcfMalloc(sizeof(HcfOpensslDsaKeyPair), 0); + if (keyPair == NULL) { + LOGE("Failed to allocate keyPair memory."); + return HCF_ERR_MALLOC; + } + keyPair->base.base.getClass = GetDsaKeyPairClass; + keyPair->base.base.destroy = DestroyDsaKeyPair; + keyPair->base.pubKey = (HcfPubKey *)pubKey; + keyPair->base.priKey = (HcfPriKey *)priKey; + + *returnKeyPair = (HcfKeyPair *)keyPair; + return HCF_SUCCESS; +} + +static HcfResult GeneratePubKeyByPkey(EVP_PKEY *pkey, HcfOpensslDsaPubKey **returnPubKey) +{ + DSA *pk = Openssl_EVP_PKEY_get1_DSA(pkey); + if (pk == NULL) { + LOGE("Get das public key from pkey failed"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult ret = CreateDsaPubKey(pk, returnPubKey); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA public key failed"); + Openssl_DSA_free(pk); + } + return ret; +} + +static HcfResult GeneratePriKeyByPkey(EVP_PKEY *pkey, HcfOpensslDsaPriKey **returnPriKey) +{ + DSA *sk = Openssl_EVP_PKEY_get1_DSA(pkey); + if (sk == NULL) { + LOGE("Get DSA private key from pkey failed"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult ret = CreateDsaPriKey(sk, returnPriKey); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA private key failed"); + Openssl_DSA_free(sk); + } + return ret; +} + +static HcfResult GenerateDsaPubAndPriKey(int32_t keyLen, HcfOpensslDsaPubKey **returnPubKey, + HcfOpensslDsaPriKey **returnPriKey) +{ + EVP_PKEY *pkey = NULL; + HcfResult ret = GenerateDsaEvpKey(keyLen, &pkey); + if (ret != HCF_SUCCESS) { + LOGE("Generate DSA EVP_PKEY failed."); + return ret; + } + + ret = GeneratePubKeyByPkey(pkey, returnPubKey); + if (ret != HCF_SUCCESS) { + Openssl_EVP_PKEY_free(pkey); + return ret; + } + + ret = GeneratePriKeyByPkey(pkey, returnPriKey); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(*returnPubKey); + *returnPubKey = NULL; + Openssl_EVP_PKEY_free(pkey); + return HCF_ERR_CRYPTO_OPERATION; + } + + Openssl_EVP_PKEY_free(pkey); + return ret; +} + +static HcfResult ConvertCommSpec2Bn(const HcfDsaCommParamsSpec *paramsSpec, BIGNUM **p, BIGNUM **q, BIGNUM **g) +{ + if (BigIntegerToBigNum(&(paramsSpec->p), p) != HCF_SUCCESS) { + LOGE("Get openssl BN p failed"); + return HCF_ERR_CRYPTO_OPERATION; + } + if (BigIntegerToBigNum(&(paramsSpec->q), q) != HCF_SUCCESS) { + LOGE("Get openssl BN q failed"); + Openssl_BN_free(*p); + *p = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + if (BigIntegerToBigNum(&(paramsSpec->g), g) != HCF_SUCCESS) { + LOGE("Get openssl BN g failed"); + Openssl_BN_free(*p); + *p = NULL; + Openssl_BN_free(*q); + *q = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static HcfResult CreateOpensslDsaKey(const HcfDsaCommParamsSpec *paramsSpec, BIGNUM *pk, BIGNUM *sk, DSA **returnDsa) +{ + BIGNUM *p = NULL; + BIGNUM *q = NULL; + BIGNUM *g = NULL; + if (ConvertCommSpec2Bn(paramsSpec, &p, &q, &g)!= HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + DSA *dsa = Openssl_DSA_new(); + if (dsa == NULL) { + FreeCommSpecBn(p, q, g); + LOGE("Openssl DSA new failed"); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + if (Openssl_DSA_set0_pqg(dsa, p, q, g) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl DSA set pqg failed"); + FreeCommSpecBn(p, q, g); + HcfPrintOpensslError(); + Openssl_DSA_free(dsa); + return HCF_ERR_CRYPTO_OPERATION; + } + if ((pk == NULL) && (sk == NULL)) { + *returnDsa = dsa; + return HCF_SUCCESS; + } + if (Openssl_DSA_set0_key(dsa, pk, sk) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl DSA set pqg failed"); + HcfPrintOpensslError(); + Openssl_DSA_free(dsa); + return HCF_ERR_CRYPTO_OPERATION; + } + *returnDsa = dsa; + return HCF_SUCCESS; +} + +static HcfResult GenerateOpensslDsaKeyByCommSpec(const HcfDsaCommParamsSpec *paramsSpec, DSA **returnDsa) +{ + if (CreateOpensslDsaKey(paramsSpec, NULL, NULL, returnDsa) != HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + + if (Openssl_DSA_generate_key(*returnDsa) != HCF_OPENSSL_SUCCESS) { + LOGE("Openssl DSA generate key failed"); + HcfPrintOpensslError(); + Openssl_DSA_free(*returnDsa); + *returnDsa = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static HcfResult GenerateOpensslDsaKeyByPubKeySpec(const HcfDsaPubKeyParamsSpec *paramsSpec, DSA **returnDsa) +{ + BIGNUM *pubKey = NULL; + if (BigIntegerToBigNum(&(paramsSpec->pk), &pubKey) != HCF_SUCCESS) { + LOGE("Get openssl BN pk failed"); + return HCF_ERR_CRYPTO_OPERATION; + } + + if (CreateOpensslDsaKey(&(paramsSpec->base), pubKey, NULL, returnDsa) != HCF_SUCCESS) { + Openssl_BN_free(pubKey); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static HcfResult GenerateOpensslDsaKeyByKeyPairSpec(const HcfDsaKeyPairParamsSpec *paramsSpec, DSA **returnDsa) +{ + BIGNUM *pubKey = NULL; + BIGNUM *priKey = NULL; + if (BigIntegerToBigNum(&(paramsSpec->pk), &pubKey) != HCF_SUCCESS) { + LOGE("Get openssl BN pk failed"); + return HCF_ERR_CRYPTO_OPERATION; + } + if (BigIntegerToBigNum(&(paramsSpec->sk), &priKey) != HCF_SUCCESS) { + LOGE("Get openssl BN sk failed"); + Openssl_BN_free(pubKey); + return HCF_ERR_CRYPTO_OPERATION; + } + if (CreateOpensslDsaKey(&(paramsSpec->base), pubKey, priKey, returnDsa) != HCF_SUCCESS) { + Openssl_BN_free(pubKey); + Openssl_BN_free(priKey); + return HCF_ERR_CRYPTO_OPERATION; + } + return HCF_SUCCESS; +} + +static HcfResult CreateDsaKeyPairByCommSpec(const HcfDsaCommParamsSpec *paramsSpec, HcfKeyPair **returnKeyPair) +{ + DSA *dsa = NULL; + if (GenerateOpensslDsaKeyByCommSpec(paramsSpec, &dsa) != HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + HcfOpensslDsaPubKey *pubKey = NULL; + if (CreateDsaPubKey(dsa, &pubKey) != HCF_SUCCESS) { + Openssl_DSA_free(dsa); + return HCF_ERR_MALLOC; + } + + if (Openssl_DSA_up_ref(dsa) != HCF_OPENSSL_SUCCESS) { + LOGE("Dup DSA failed."); + HcfPrintOpensslError(); + HcfObjDestroy(pubKey); + return HCF_ERR_CRYPTO_OPERATION; + } + + HcfOpensslDsaPriKey *priKey = NULL; + if (CreateDsaPriKey(dsa, &priKey) != HCF_SUCCESS) { + Openssl_DSA_free(dsa); + HcfObjDestroy(pubKey); + return HCF_ERR_MALLOC; + } + + if (CreateDsaKeyPair(pubKey, priKey, returnKeyPair) != HCF_SUCCESS) { + HcfObjDestroy(pubKey); + HcfObjDestroy(priKey); + return HCF_ERR_MALLOC; + } + return HCF_SUCCESS; +} + +static HcfResult CreateDsaPubKeyByKeyPairSpec(const HcfDsaKeyPairParamsSpec *paramsSpec, + HcfOpensslDsaPubKey **returnPubKey) +{ + DSA *dsa = NULL; + if (GenerateOpensslDsaKeyByKeyPairSpec(paramsSpec, &dsa) != HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + if (CreateDsaPubKey(dsa, returnPubKey) != HCF_SUCCESS) { + Openssl_DSA_free(dsa); + return HCF_ERR_MALLOC; + } + return HCF_SUCCESS; +} + +static HcfResult CreateDsaPriKeyByKeyPairSpec(const HcfDsaKeyPairParamsSpec *paramsSpec, + HcfOpensslDsaPriKey **returnPriKey) +{ + DSA *dsa = NULL; + if (GenerateOpensslDsaKeyByKeyPairSpec(paramsSpec, &dsa) != HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + if (CreateDsaPriKey(dsa, returnPriKey) != HCF_SUCCESS) { + Openssl_DSA_free(dsa); + return HCF_ERR_MALLOC; + } + return HCF_SUCCESS; +} + +static HcfResult CreateDsaKeyPairByKeyPairSpec(const HcfDsaKeyPairParamsSpec *paramsSpec, HcfKeyPair **returnKeyPair) +{ + HcfOpensslDsaPubKey *pubKey = NULL; + HcfResult ret = CreateDsaPubKeyByKeyPairSpec(paramsSpec, &pubKey); + if (ret != HCF_SUCCESS) { + return ret; + } + + HcfOpensslDsaPriKey *priKey = NULL; + ret = CreateDsaPriKeyByKeyPairSpec(paramsSpec, &priKey); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(pubKey); + return ret; + } + ret = CreateDsaKeyPair(pubKey, priKey, returnKeyPair); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(pubKey); + HcfObjDestroy(priKey); + return ret; + } + return HCF_SUCCESS; +} + +static HcfResult CreateDsaKeyPairBySpec(const HcfAsyKeyParamsSpec *paramsSpec, HcfKeyPair **returnKeyPair) +{ + if (paramsSpec->specType == HCF_COMMON_PARAMS_SPEC) { + return CreateDsaKeyPairByCommSpec((const HcfDsaCommParamsSpec *)paramsSpec, returnKeyPair); + } else { + return CreateDsaKeyPairByKeyPairSpec((const HcfDsaKeyPairParamsSpec *)paramsSpec, returnKeyPair); + } +} + +static HcfResult CreateDsaPubKeyByPubKeySpec(const HcfDsaPubKeyParamsSpec *paramsSpec, HcfPubKey **returnPubKey) +{ + DSA *dsa = NULL; + if (GenerateOpensslDsaKeyByPubKeySpec(paramsSpec, &dsa) != HCF_SUCCESS) { + return HCF_ERR_CRYPTO_OPERATION; + } + + HcfOpensslDsaPubKey *pubKey = NULL; + if (CreateDsaPubKey(dsa, &pubKey) != HCF_SUCCESS) { + Openssl_DSA_free(dsa); + return HCF_ERR_MALLOC; + } + *returnPubKey = (HcfPubKey *)pubKey; + return HCF_SUCCESS; +} + +static HcfResult ConvertDsaPubKey(const HcfBlob *pubKeyBlob, HcfOpensslDsaPubKey **returnPubKey) +{ + const unsigned char *tmpData = (const unsigned char *)(pubKeyBlob->data); + DSA *dsa = Openssl_d2i_DSA_PUBKEY(NULL, &tmpData, pubKeyBlob->len); + if (dsa == NULL) { + LOGE("D2i_DSA_PUBKEY fail."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult ret = CreateDsaPubKey(dsa, returnPubKey); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA public key failed"); + Openssl_DSA_free(dsa); + } + return ret; +} + +static HcfResult ConvertDsaPriKey(const HcfBlob *priKeyBlob, HcfOpensslDsaPriKey **returnPriKey) +{ + const unsigned char *tmpData = (const unsigned char *)(priKeyBlob->data); + DSA *dsa = Openssl_d2i_DSAPrivateKey(NULL, &tmpData, priKeyBlob->len); + if (dsa == NULL) { + LOGE("D2i_DSADSAPrivateKey fail."); + HcfPrintOpensslError(); + return HCF_ERR_CRYPTO_OPERATION; + } + HcfResult ret = CreateDsaPriKey(dsa, returnPriKey); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA private key failed"); + Openssl_DSA_free(dsa); + } + return ret; +} + +static HcfResult ConvertDsaPubAndPriKey(const HcfBlob *pubKeyBlob, const HcfBlob *priKeyBlob, + HcfOpensslDsaPubKey **returnPubKey, HcfOpensslDsaPriKey **returnPriKey) +{ + if (pubKeyBlob != NULL) { + if (ConvertDsaPubKey(pubKeyBlob, returnPubKey) != HCF_SUCCESS) { + LOGE("Convert DSA public key failed."); + return HCF_ERR_CRYPTO_OPERATION; + } + } + if (priKeyBlob != NULL) { + if (ConvertDsaPriKey(priKeyBlob, returnPriKey) != HCF_SUCCESS) { + LOGE("Convert DSA private key failed."); + HcfObjDestroy(*returnPubKey); + *returnPubKey = NULL; + return HCF_ERR_CRYPTO_OPERATION; + } + } + return HCF_SUCCESS; +} + +static HcfResult EngineGenerateDsaKeyPair(HcfAsyKeyGeneratorSpi *self, HcfKeyPair **returnKeyPair) +{ + if (self == NULL || returnKeyPair == NULL) { + LOGE("Invalid params."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaKeyGeneratorSpiClass())) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + HcfAsyKeyGeneratorSpiDsaOpensslImpl *impl = (HcfAsyKeyGeneratorSpiDsaOpensslImpl *)self; + + HcfOpensslDsaPubKey *pubKey = NULL; + HcfOpensslDsaPriKey *priKey = NULL; + HcfResult ret = GenerateDsaPubAndPriKey(impl->bits, &pubKey, &priKey); + if (ret != HCF_SUCCESS) { + LOGE("Generate DSA pk and sk by openssl failed."); + return ret; + } + + ret = CreateDsaKeyPair(pubKey, priKey, returnKeyPair); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(pubKey); + HcfObjDestroy(priKey); + return ret; + } + return HCF_SUCCESS; +} + +static HcfResult EngineConvertDsaKey(HcfAsyKeyGeneratorSpi *self, HcfParamsSpec *params, HcfBlob *pubKeyBlob, + HcfBlob *priKeyBlob, HcfKeyPair **returnKeyPair) +{ + (void)params; + if ((self == NULL) || (returnKeyPair == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaKeyGeneratorSpiClass())) { + LOGE("Class not match."); + return HCF_INVALID_PARAMS; + } + bool pubKeyValid = IsBlobValid(pubKeyBlob); + bool priKeyValid = IsBlobValid(priKeyBlob); + if ((!pubKeyValid) && (!priKeyValid)) { + LOGE("The private key and public key cannot both be NULL."); + return HCF_INVALID_PARAMS; + } + + HcfOpensslDsaPubKey *pubKey = NULL; + HcfOpensslDsaPriKey *priKey = NULL; + HcfBlob *inputPk = pubKeyValid ? pubKeyBlob : NULL; + HcfBlob *inputSk = priKeyValid ? priKeyBlob : NULL; + HcfResult ret = ConvertDsaPubAndPriKey(inputPk, inputSk, &pubKey, &priKey); + if (ret != HCF_SUCCESS) { + return ret; + } + ret = CreateDsaKeyPair(pubKey, priKey, returnKeyPair); + if (ret != HCF_SUCCESS) { + HcfObjDestroy(pubKey); + HcfObjDestroy(priKey); + } + return ret; +} + +static HcfResult EngineGenerateDsaKeyPairBySpec(const HcfAsyKeyGeneratorSpi *self, + const HcfAsyKeyParamsSpec *paramsSpec, HcfKeyPair **returnKeyPair) +{ + if ((self == NULL) || (paramsSpec == NULL) || (returnKeyPair == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + + if (!IsClassMatch((HcfObjectBase *)self, GetDsaKeyGeneratorSpiClass())) { + return HCF_INVALID_PARAMS; + } + + if ((strcmp(paramsSpec->algName, ALGORITHM_NAME_DSA) != 0) || + ((paramsSpec->specType != HCF_COMMON_PARAMS_SPEC) && (paramsSpec->specType != HCF_KEY_PAIR_SPEC))) { + LOGE("Invalid params spec."); + return HCF_INVALID_PARAMS; + } + HcfResult ret = CreateDsaKeyPairBySpec(paramsSpec, returnKeyPair); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA key pair by spec falied."); + } + return ret; +} + +static HcfResult EngineGenerateDsaPubKeyBySpec(const HcfAsyKeyGeneratorSpi *self, + const HcfAsyKeyParamsSpec *paramsSpec, HcfPubKey **returnPubKey) +{ + if ((self == NULL) || (paramsSpec == NULL) || (returnPubKey == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + + if (!IsClassMatch((HcfObjectBase *)self, GetDsaKeyGeneratorSpiClass())) { + return HCF_INVALID_PARAMS; + } + + if ((strcmp(paramsSpec->algName, ALGORITHM_NAME_DSA) != 0) || + ((paramsSpec->specType != HCF_PUBLIC_KEY_SPEC) && (paramsSpec->specType != HCF_KEY_PAIR_SPEC))) { + LOGE("Invalid params spec."); + return HCF_INVALID_PARAMS; + } + + HcfResult ret = CreateDsaPubKeyByPubKeySpec((const HcfDsaPubKeyParamsSpec *)paramsSpec, returnPubKey); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA public key by spec falied."); + } + return ret; +} + +static HcfResult EngineGenerateDsaPriKeyBySpec(const HcfAsyKeyGeneratorSpi *self, + const HcfAsyKeyParamsSpec *paramsSpec, HcfPriKey **returnPriKey) +{ + if ((self == NULL) || (paramsSpec == NULL) || (returnPriKey == NULL)) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + if (!IsClassMatch((HcfObjectBase *)self, GetDsaKeyGeneratorSpiClass())) { + return HCF_INVALID_PARAMS; + } + if ((strcmp(paramsSpec->algName, ALGORITHM_NAME_DSA) != 0) || (paramsSpec->specType != HCF_KEY_PAIR_SPEC)) { + LOGE("Invalid params spec."); + return HCF_INVALID_PARAMS; + } + + HcfOpensslDsaPriKey *dsaSk = NULL; + HcfResult ret = CreateDsaPriKeyByKeyPairSpec((const HcfDsaKeyPairParamsSpec *)paramsSpec, &dsaSk); + if (ret != HCF_SUCCESS) { + LOGE("Create DSA private key by spec falied."); + } else { + *returnPriKey = (HcfPriKey *)dsaSk; + } + return ret; +} + +HcfResult HcfAsyKeyGeneratorSpiDsaCreate(HcfAsyKeyGenParams *params, HcfAsyKeyGeneratorSpi **returnSpi) +{ + if (params == NULL || returnSpi == NULL) { + LOGE("Invalid input parameter."); + return HCF_INVALID_PARAMS; + } + HcfAsyKeyGeneratorSpiDsaOpensslImpl *impl = (HcfAsyKeyGeneratorSpiDsaOpensslImpl *)HcfMalloc( + sizeof(HcfAsyKeyGeneratorSpiDsaOpensslImpl), 0); + if (impl == NULL) { + LOGE("Failed to allocate generator impl memroy."); + return HCF_ERR_MALLOC; + } + impl->bits = params->bits; + impl->base.base.getClass = GetDsaKeyGeneratorSpiClass; + impl->base.base.destroy = DestroyDsaKeyGeneratorSpiImpl; + impl->base.engineGenerateKeyPair = EngineGenerateDsaKeyPair; + impl->base.engineConvertKey = EngineConvertDsaKey; + impl->base.engineGenerateKeyPairBySpec = EngineGenerateDsaKeyPairBySpec; + impl->base.engineGeneratePubKeyBySpec = EngineGenerateDsaPubKeyBySpec; + impl->base.engineGeneratePriKeyBySpec = EngineGenerateDsaPriKeyBySpec; + + *returnSpi = (HcfAsyKeyGeneratorSpi *)impl; + return HCF_SUCCESS; +} \ No newline at end of file