1 /*
2  * Copyright (C) 2023-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_ecc_key_util.h"
17 #include "securec.h"
18 #include "detailed_ecc_key_params.h"
19 #include "log.h"
20 
21 #include "memory.h"
22 #include "napi_crypto_framework_defines.h"
23 #include "napi_utils.h"
24 #include "napi_key_pair.h"
25 #include "napi_pri_key.h"
26 #include "napi_pub_key.h"
27 
28 namespace OHOS {
29 namespace CryptoFramework {
NapiECCKeyUtil()30 NapiECCKeyUtil::NapiECCKeyUtil() {}
31 
~NapiECCKeyUtil()32 NapiECCKeyUtil::~NapiECCKeyUtil() {}
33 
JsGenECCCommonParamsSpec(napi_env env,napi_callback_info info)34 napi_value NapiECCKeyUtil::JsGenECCCommonParamsSpec(napi_env env, napi_callback_info info)
35 {
36     size_t expectedArgc = ARGS_SIZE_ONE;
37     size_t argc = ARGS_SIZE_ONE;
38     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
39     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
40 
41     if (argc != expectedArgc) {
42         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
43         LOGE("The input args num is invalid.");
44         return nullptr;
45     }
46 
47     std::string algName;
48     if (!GetStringFromJSParams(env, argv[0], algName)) {
49         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get algoName."));
50         LOGE("failed to get algoName.");
51         return NapiGetNull(env);
52     }
53 
54     HcfEccCommParamsSpec *eccCommParamsSpec = nullptr;
55     if (HcfEccKeyUtilCreate(algName.c_str(), &eccCommParamsSpec) != HCF_SUCCESS) {
56         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create c generator fail."));
57         LOGE("create c generator fail.");
58         return NapiGetNull(env);
59     }
60     napi_value instance = ConvertEccCommParamsSpecToNapiValue(env, eccCommParamsSpec);
61     FreeEccCommParamsSpec(eccCommParamsSpec);
62     HcfFree(eccCommParamsSpec);
63     return instance;
64 }
65 
JsConvertPoint(napi_env env,napi_callback_info info)66 napi_value NapiECCKeyUtil::JsConvertPoint(napi_env env, napi_callback_info info)
67 {
68     size_t expectedArgc = ARGS_SIZE_TWO;
69     size_t argc = ARGS_SIZE_TWO;
70     napi_value argv[ARGS_SIZE_TWO] = { nullptr };
71     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
72 
73     if (argc != expectedArgc) {
74         LOGE("The input args num is invalid.");
75         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
76         return nullptr;
77     }
78 
79     std::string curveName;
80     if (!GetStringFromJSParams(env, argv[PARAM0], curveName)) {
81         LOGE("failed to get curveName.");
82         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get curveName."));
83         return nullptr;
84     }
85 
86     HcfBlob *pointBlob = GetBlobFromNapiUint8Arr(env, argv[PARAM1]);
87     if (pointBlob == nullptr) {
88         LOGE("failed to get point blob.");
89         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get point blob."));
90         return nullptr;
91     }
92 
93     HcfPoint point;
94     HcfResult ret = HcfConvertPoint(curveName.c_str(), pointBlob, &point);
95     if (ret != HCF_SUCCESS) {
96         LOGE("failed to convert point.");
97         HcfBlobDataFree(pointBlob);
98         HcfFree(pointBlob);
99         napi_throw(env, GenerateBusinessError(env, ret, "failed to convert point."));
100         return nullptr;
101     }
102     napi_value instance = ConvertEccPointToNapiValue(env, &point);
103     FreeEcPointMem(&point);
104     HcfBlobDataFree(pointBlob);
105     HcfFree(pointBlob);
106     return instance;
107 }
108 
JsGetEncodedPoint(napi_env env,napi_callback_info info)109 napi_value NapiECCKeyUtil::JsGetEncodedPoint(napi_env env, napi_callback_info info)
110 {
111     size_t expectedArgc = ARGS_SIZE_THREE;
112     size_t argc = ARGS_SIZE_THREE;
113     napi_value argv[ARGS_SIZE_THREE] = { nullptr };
114     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
115 
116     if (argc != expectedArgc) {
117         LOGE("The input args num is invalid.");
118         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
119         return nullptr;
120     }
121 
122     std::string curveName;
123     if (!GetStringFromJSParams(env, argv[PARAM0], curveName)) {
124         LOGE("failed to get curveName.");
125         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get curveName."));
126         return nullptr;
127     }
128 
129     HcfPoint point;
130     if (!GetPointFromNapiValue(env, argv[PARAM1], &point)) {
131         LOGE("failed to get point.");
132         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get point."));
133         return nullptr;
134     }
135 
136     std::string format;
137     if (!GetStringFromJSParams(env, argv[PARAM2], format)) {
138         LOGE("failed to get format.");
139         FreeEcPointMem(&point);
140         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get format."));
141         return nullptr;
142     }
143 
144     HcfBlob returnBlob;
145     HcfResult ret = HcfGetEncodedPoint(curveName.c_str(), &point, format.c_str(), &returnBlob);
146     if (ret != HCF_SUCCESS) {
147         LOGE("fail to get point data.");
148         FreeEcPointMem(&point);
149         napi_throw(env, GenerateBusinessError(env, ret, "failed to get point data."));
150         return nullptr;
151     }
152     napi_value instance = ConvertObjectBlobToNapiValue(env, &returnBlob);
153     FreeEcPointMem(&point);
154     HcfBlobDataFree(&returnBlob);
155     return instance;
156 }
157 
ECCKeyUtilConstructor(napi_env env,napi_callback_info info)158 napi_value NapiECCKeyUtil::ECCKeyUtilConstructor(napi_env env, napi_callback_info info)
159 {
160     napi_value thisVar = nullptr;
161     size_t argc = ARGS_SIZE_ONE;
162     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
163     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
164     return thisVar;
165 }
166 
GenECCCommonParamSpec(napi_env env)167 napi_value NapiECCKeyUtil::GenECCCommonParamSpec(napi_env env)
168 {
169     napi_value cons = nullptr;
170     napi_property_descriptor clzDes[] = {
171         DECLARE_NAPI_STATIC_FUNCTION("genECCCommonParamsSpec", NapiECCKeyUtil::JsGenECCCommonParamsSpec),
172         DECLARE_NAPI_STATIC_FUNCTION("convertPoint", NapiECCKeyUtil::JsConvertPoint),
173         DECLARE_NAPI_STATIC_FUNCTION("getEncodedPoint", NapiECCKeyUtil::JsGetEncodedPoint),
174     };
175     NAPI_CALL(env, napi_define_class(env, "ECCKeyUtil", NAPI_AUTO_LENGTH, NapiECCKeyUtil::ECCKeyUtilConstructor,
176         nullptr, sizeof(clzDes) / sizeof(clzDes[0]), clzDes, &cons));
177     return cons;
178 }
179 
DefineNapiECCKeyUtilJSClass(napi_env env,napi_value exports)180 void NapiECCKeyUtil::DefineNapiECCKeyUtilJSClass(napi_env env, napi_value exports)
181 {
182     napi_set_named_property(env, exports, "ECCKeyUtil", NapiECCKeyUtil::GenECCCommonParamSpec(env));
183 }
184 } // CryptoFramework
185 } // OHOS
186