1 /*
2 * Copyright (C) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi_pri_key.h"
17
18 #include "log.h"
19 #include "memory.h"
20 #include "napi_crypto_framework_defines.h"
21 #include "napi_utils.h"
22 #include "securec.h"
23 #include "key.h"
24
25 namespace OHOS {
26 namespace CryptoFramework {
27 thread_local napi_ref NapiPriKey::classRef_ = nullptr;
28
NapiPriKey(HcfPriKey * priKey)29 NapiPriKey::NapiPriKey(HcfPriKey *priKey) : NapiKey(reinterpret_cast<HcfKey *>(priKey)) {}
30
~NapiPriKey()31 NapiPriKey::~NapiPriKey() {}
32
GetPriKey()33 HcfPriKey *NapiPriKey::GetPriKey()
34 {
35 return reinterpret_cast<HcfPriKey *>(NapiKey::GetHcfKey());
36 }
37
PriKeyConstructor(napi_env env,napi_callback_info info)38 napi_value NapiPriKey::PriKeyConstructor(napi_env env, napi_callback_info info)
39 {
40 napi_value thisVar = nullptr;
41 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
42 return thisVar;
43 }
44
ConvertToJsPriKey(napi_env env)45 napi_value NapiPriKey::ConvertToJsPriKey(napi_env env)
46 {
47 napi_value instance;
48 napi_value constructor = nullptr;
49 napi_get_reference_value(env, classRef_, &constructor);
50 napi_new_instance(env, constructor, 0, nullptr, &instance);
51
52 const char *algName = this->GetPriKey()->base.getAlgorithm(&(this->GetPriKey()->base));
53 const char *format = this->GetPriKey()->base.getFormat(&(this->GetPriKey()->base));
54
55 napi_value napiAlgName = nullptr;
56 napi_create_string_utf8(env, algName, NAPI_AUTO_LENGTH, &napiAlgName);
57 napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName);
58
59 napi_value napiFormat = nullptr;
60 napi_create_string_utf8(env, format, NAPI_AUTO_LENGTH, &napiFormat);
61 napi_set_named_property(env, instance, CRYPTO_TAG_FORMAT.c_str(), napiFormat);
62 return instance;
63 }
64
JsGetEncoded(napi_env env,napi_callback_info info)65 napi_value NapiPriKey::JsGetEncoded(napi_env env, napi_callback_info info)
66 {
67 napi_value thisVar = nullptr;
68 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
69 NapiPriKey *napiPriKey = nullptr;
70 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiPriKey));
71 if (status != napi_ok || napiPriKey == nullptr) {
72 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiPriKey obj!"));
73 LOGE("failed to unwrap napiPriKey obj!");
74 return nullptr;
75 }
76
77 HcfPriKey *priKey = napiPriKey->GetPriKey();
78 if (priKey == nullptr) {
79 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get priKey obj!"));
80 LOGE("failed to get priKey obj!");
81 return nullptr;
82 }
83
84 HcfBlob returnBlob;
85 HcfResult res = priKey->base.getEncoded(&priKey->base, &returnBlob);
86 if (res != HCF_SUCCESS) {
87 napi_throw(env, GenerateBusinessError(env, res, "c getEncoded fail."));
88 LOGD("[error] c getEncoded fail.");
89 return nullptr;
90 }
91
92 napi_value instance = ConvertBlobToNapiValue(env, &returnBlob);
93 HcfBlobDataFree(&returnBlob);
94 return instance;
95 }
96
JsClearMem(napi_env env,napi_callback_info info)97 napi_value NapiPriKey::JsClearMem(napi_env env, napi_callback_info info)
98 {
99 napi_value thisVar = nullptr;
100 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
101 NapiPriKey *napiPriKey = nullptr;
102 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiPriKey));
103 if (status != napi_ok || napiPriKey == nullptr) {
104 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiPriKey obj!"));
105 LOGE("failed to unwrap napiPriKey obj!");
106 return nullptr;
107 }
108
109 HcfPriKey *priKey = napiPriKey->GetPriKey();
110 if (priKey == nullptr) {
111 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get priKey obj!"));
112 LOGE("failed to get priKey obj!");
113 return nullptr;
114 }
115
116 priKey->clearMem(priKey);
117 return nullptr;
118 }
119
GetAsyKeySpecBigInt(napi_env env,AsyKeySpecItem item,HcfPriKey * priKey)120 static napi_value GetAsyKeySpecBigInt(napi_env env, AsyKeySpecItem item, HcfPriKey *priKey)
121 {
122 HcfBigInteger returnBigInteger = { 0 };
123 HcfResult res = priKey->getAsyKeySpecBigInteger(priKey, item, &returnBigInteger);
124 if (res != HCF_SUCCESS) {
125 napi_throw(env, GenerateBusinessError(env, res, "C getAsyKeySpecBigInteger failed."));
126 LOGE("C getAsyKeySpecBigInteger failed.");
127 return nullptr;
128 }
129
130 napi_value instance = ConvertBigIntToNapiValue(env, &returnBigInteger);
131 HcfFree(returnBigInteger.data);
132 return instance;
133 }
134
GetAsyKeySpecNumber(napi_env env,AsyKeySpecItem item,HcfPriKey * priKey)135 static napi_value GetAsyKeySpecNumber(napi_env env, AsyKeySpecItem item, HcfPriKey *priKey)
136 {
137 int returnInt = 0;
138 HcfResult res = priKey->getAsyKeySpecInt(priKey, item, &returnInt);
139 if (res != HCF_SUCCESS) {
140 napi_throw(env, GenerateBusinessError(env, res, "C getAsyKeySpecInt failed."));
141 LOGE("C getAsyKeySpecInt fail.");
142 return nullptr;
143 }
144
145 napi_value instance = nullptr;
146 napi_create_int32(env, returnInt, &instance);
147 return instance;
148 }
149
GetAsyKeySpecString(napi_env env,AsyKeySpecItem item,HcfPriKey * priKey)150 static napi_value GetAsyKeySpecString(napi_env env, AsyKeySpecItem item, HcfPriKey *priKey)
151 {
152 char *returnString = nullptr;
153 HcfResult res = priKey->getAsyKeySpecString(priKey, item, &returnString);
154 if (res != HCF_SUCCESS) {
155 napi_throw(env, GenerateBusinessError(env, res, "C getAsyKeySpecString failed."));
156 LOGE("c getAsyKeySpecString fail.");
157 return nullptr;
158 }
159
160 napi_value instance = nullptr;
161 napi_create_string_utf8(env, returnString, NAPI_AUTO_LENGTH, &instance);
162 HcfFree(returnString);
163 return instance;
164 }
165
JsGetAsyKeySpec(napi_env env,napi_callback_info info)166 napi_value NapiPriKey::JsGetAsyKeySpec(napi_env env, napi_callback_info info)
167 {
168 napi_value thisVar = nullptr;
169 NapiPriKey *napiPriKey = nullptr;
170 size_t expectedArgc = ARGS_SIZE_ONE;
171 size_t argc = ARGS_SIZE_ONE;
172 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
173 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
174 if (argc != expectedArgc) {
175 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "JsGetAsyKeySpec fail, wrong argument num."));
176 LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc);
177 return nullptr;
178 }
179
180 AsyKeySpecItem item;
181 if (napi_get_value_uint32(env, argv[0], reinterpret_cast<uint32_t *>(&item)) != napi_ok) {
182 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "JsGetAsyKeySpec failed!"));
183 LOGE("JsGetAsyKeySpec failed!");
184 return nullptr;
185 }
186
187 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiPriKey));
188 if (status != napi_ok || napiPriKey == nullptr) {
189 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiPriKey obj!"));
190 LOGE("failed to unwrap napiPriKey obj!");
191 return nullptr;
192 }
193 HcfPriKey *priKey = napiPriKey->GetPriKey();
194 if (priKey == nullptr) {
195 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get priKey obj!"));
196 LOGE("failed to get priKey obj!");
197 return nullptr;
198 }
199 LOGD("prepare priKey ok.");
200
201 int32_t type = GetAsyKeySpecType(item);
202 if (type == SPEC_ITEM_TYPE_BIG_INT) {
203 return GetAsyKeySpecBigInt(env, item, priKey);
204 } else if (type == SPEC_ITEM_TYPE_NUM) {
205 return GetAsyKeySpecNumber(env, item, priKey);
206 } else if (type == SPEC_ITEM_TYPE_STR) {
207 return GetAsyKeySpecString(env, item, priKey);
208 } else {
209 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "AsyKeySpecItem not support!"));
210 return nullptr;
211 }
212 }
213
DefinePriKeyJSClass(napi_env env)214 void NapiPriKey::DefinePriKeyJSClass(napi_env env)
215 {
216 napi_property_descriptor classDesc[] = {
217 DECLARE_NAPI_FUNCTION("getEncoded", NapiPriKey::JsGetEncoded),
218 DECLARE_NAPI_FUNCTION("clearMem", NapiPriKey::JsClearMem),
219 DECLARE_NAPI_FUNCTION("getAsyKeySpec", NapiPriKey::JsGetAsyKeySpec),
220 };
221 napi_value constructor = nullptr;
222 napi_define_class(env, "PriKey", NAPI_AUTO_LENGTH, NapiPriKey::PriKeyConstructor, nullptr,
223 sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor);
224 napi_create_reference(env, constructor, 1, &classRef_);
225 }
226 } // CryptoFramework
227 } // OHOS
228