1 /*
2  * Copyright (C) 2022-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_sym_key_generator.h"
17 
18 #include "securec.h"
19 #include "log.h"
20 #include "memory.h"
21 #include "napi_sym_key.h"
22 #include "napi_utils.h"
23 #include "napi_crypto_framework_defines.h"
24 
25 namespace OHOS {
26 namespace CryptoFramework {
27 thread_local napi_ref NapiSymKeyGenerator::classRef_ = nullptr;
28 
29 struct SymKeyGeneratorFwkCtxT {
30     napi_env env = nullptr;
31     AsyncType asyncType = ASYNC_CALLBACK;
32     napi_ref callback = nullptr;
33     napi_deferred deferred = nullptr;
34     napi_value promise = nullptr;
35     napi_async_work asyncWork = nullptr;
36     napi_ref symKeyGeneratorRef = nullptr;
37 
38     HcfResult errCode = HCF_SUCCESS;
39     HcfSymKey *returnSymKey = nullptr;
40     const char *errMsg = nullptr;
41 
42     HcfSymKeyGenerator *generator = nullptr;
43     HcfBlob keyMaterial = { .data = nullptr, .len = 0 };
44 };
45 
46 using SymKeyGeneratorFwkCtx = SymKeyGeneratorFwkCtxT *;
47 
FreeSymKeyGeneratorFwkCtx(napi_env env,SymKeyGeneratorFwkCtx & context)48 static void FreeSymKeyGeneratorFwkCtx(napi_env env, SymKeyGeneratorFwkCtx &context)
49 {
50     if (context == nullptr) {
51         return;
52     }
53 
54     if (context->asyncWork != nullptr) {
55         napi_delete_async_work(env, context->asyncWork);
56         context->asyncWork = nullptr;
57     }
58 
59     if (context->callback != nullptr) {
60         napi_delete_reference(env, context->callback);
61         context->callback = nullptr;
62     }
63 
64     if (context->symKeyGeneratorRef != nullptr) {
65         napi_delete_reference(env, context->symKeyGeneratorRef);
66         context->symKeyGeneratorRef = nullptr;
67     }
68 
69     if (context->keyMaterial.data != nullptr) {
70         (void)memset_s(context->keyMaterial.data, context->keyMaterial.len, 0, context->keyMaterial.len);
71         HcfFree(context->keyMaterial.data);
72         context->keyMaterial.data = nullptr;
73         context->keyMaterial.len = 0;
74     }
75     context->errMsg = nullptr;
76 
77     HcfFree(context);
78     context = nullptr;
79 }
80 
BuildContextForGenerateKey(napi_env env,napi_callback_info info,SymKeyGeneratorFwkCtx context)81 static bool BuildContextForGenerateKey(napi_env env, napi_callback_info info, SymKeyGeneratorFwkCtx context)
82 {
83     napi_value thisVar = nullptr;
84     size_t expectedArgc = ARGS_SIZE_ONE;
85     size_t argc = ARGS_SIZE_ONE;
86     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
87     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
88     if (argc != expectedArgc && argc != expectedArgc - 1) {
89         LOGE("wrong argument num. require 0 or 1 arguments. [Argc]: %zu!", argc);
90         return false;
91     }
92     context->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
93     NapiSymKeyGenerator *napiGenerator = nullptr;
94     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiGenerator));
95     if (status != napi_ok || napiGenerator == nullptr) {
96         LOGE("failed to unwrap NapiSymKeyGenerator obj!");
97         return false;
98     }
99 
100     context->generator = napiGenerator->GetSymKeyGenerator();
101     if (context->generator == nullptr) {
102         LOGE("failed to get generator obj!");
103         return false;
104     }
105 
106     if (napi_create_reference(env, thisVar, 1, &context->symKeyGeneratorRef) != napi_ok) {
107         LOGE("create sym key generator ref failed when generate sym key!");
108         return false;
109     }
110 
111     if (context->asyncType == ASYNC_PROMISE) {
112         napi_create_promise(env, &context->deferred, &context->promise);
113         return true;
114     } else {
115         return GetCallbackFromJSParams(env, argv[0], &context->callback);
116     }
117 }
118 
BuildContextForConvertKey(napi_env env,napi_callback_info info,SymKeyGeneratorFwkCtx context)119 static bool BuildContextForConvertKey(napi_env env, napi_callback_info info, SymKeyGeneratorFwkCtx context)
120 {
121     napi_value thisVar = nullptr;
122     size_t expectedArgc = ARGS_SIZE_TWO;
123     size_t argc = ARGS_SIZE_TWO;
124     napi_value argv[ARGS_SIZE_TWO] = { nullptr };
125     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
126     if (argc != expectedArgc && argc != expectedArgc - 1) {
127         LOGE("wrong argument num. require 1 or 2 arguments. [Argc]: %zu!", argc);
128         return false;
129     }
130     context->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
131 
132     NapiSymKeyGenerator *napiGenerator = nullptr;
133     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiGenerator));
134     if (status != napi_ok || napiGenerator == nullptr) {
135         LOGE("failed to unwrap NapiSymKeyGenerator obj!");
136         return false;
137     }
138 
139     context->generator = napiGenerator->GetSymKeyGenerator();
140     if (context->generator == nullptr) {
141         LOGE("failed to get generator obj!");
142         return false;
143     }
144 
145     size_t index = 0;
146     HcfBlob *blob = GetBlobFromNapiDataBlob(env, argv[index++]);
147     if (blob == nullptr) {
148         LOGE("get keyMaterial failed!");
149         return false;
150     }
151     context->keyMaterial = *blob;
152     HcfFree(blob);
153 
154     if (napi_create_reference(env, thisVar, 1, &context->symKeyGeneratorRef) != napi_ok) {
155         LOGE("create sym key generator ref failed when covert sym key!");
156         return false;
157     }
158 
159     if (context->asyncType == ASYNC_PROMISE) {
160         napi_create_promise(env, &context->deferred, &context->promise);
161         return true;
162     } else {
163         return GetCallbackFromJSParams(env, argv[index], &context->callback);
164     }
165 }
166 
ReturnPromiseResult(napi_env env,SymKeyGeneratorFwkCtx context,napi_value result)167 static void ReturnPromiseResult(napi_env env, SymKeyGeneratorFwkCtx context, napi_value result)
168 {
169     if (context->errCode == HCF_SUCCESS) {
170         napi_resolve_deferred(env, context->deferred, result);
171     } else {
172         napi_reject_deferred(env, context->deferred,
173             GenerateBusinessError(env, context->errCode, context->errMsg));
174     }
175 }
176 
ReturnCallbackResult(napi_env env,SymKeyGeneratorFwkCtx context,napi_value result)177 static void ReturnCallbackResult(napi_env env, SymKeyGeneratorFwkCtx context, napi_value result)
178 {
179     napi_value businessError = nullptr;
180     if (context->errCode != HCF_SUCCESS) {
181         businessError = GenerateBusinessError(env, context->errCode, context->errMsg);
182     }
183     napi_value params[ARGS_SIZE_TWO] = { businessError, result };
184 
185     napi_value func = nullptr;
186     napi_get_reference_value(env, context->callback, &func);
187 
188     napi_value recv = nullptr;
189     napi_value callFuncRet = nullptr;
190     napi_get_undefined(env, &recv);
191     napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
192 }
193 
AsyncGenKeyProcess(napi_env env,void * data)194 static void AsyncGenKeyProcess(napi_env env, void *data)
195 {
196     SymKeyGeneratorFwkCtx context = static_cast<SymKeyGeneratorFwkCtx>(data);
197     HcfSymKeyGenerator *generator = context->generator;
198 
199     HcfSymKey *key = nullptr;
200     context->errCode = generator->generateSymKey(generator, &key);
201     if (context->errCode != HCF_SUCCESS) {
202         LOGE("generate sym key failed.");
203         context->errMsg = "generate sym key failed.";
204         return;
205     }
206 
207     context->errCode = HCF_SUCCESS;
208     context->returnSymKey = key;
209 }
210 
AsyncKeyReturn(napi_env env,napi_status status,void * data)211 static void AsyncKeyReturn(napi_env env, napi_status status, void *data)
212 {
213     napi_value instance = NapiSymKey::CreateSymKey(env);
214     SymKeyGeneratorFwkCtx context = static_cast<SymKeyGeneratorFwkCtx>(data);
215     NapiSymKey *napiSymKey = new (std::nothrow) NapiSymKey(context->returnSymKey);
216     if (napiSymKey == nullptr) {
217         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi sym key failed."));
218         FreeSymKeyGeneratorFwkCtx(env, context);
219         LOGE("new napi sym key failed.");
220         return;
221     }
222 
223     napi_status ret = napi_wrap(env, instance, napiSymKey,
224         [](napi_env env, void *data, void *hint) {
225             NapiSymKey *napiSymKey = static_cast<NapiSymKey *>(data);
226             delete napiSymKey;
227             return;
228         }, nullptr, nullptr);
229     if (ret != napi_ok) {
230         LOGE("failed to wrap napiSymKey obj!");
231         context->errCode = HCF_INVALID_PARAMS;
232         context->errMsg = "failed to wrap napiSymKey obj!";
233         delete napiSymKey;
234     }
235 
236     if (context->asyncType == ASYNC_CALLBACK) {
237         ReturnCallbackResult(env, context, instance);
238     } else {
239         ReturnPromiseResult(env, context, instance);
240     }
241     FreeSymKeyGeneratorFwkCtx(env, context);
242 }
243 
AsyncConvertKeyProcess(napi_env env,void * data)244 static void AsyncConvertKeyProcess(napi_env env, void *data)
245 {
246     SymKeyGeneratorFwkCtx context = static_cast<SymKeyGeneratorFwkCtx>(data);
247     HcfSymKeyGenerator *generator = context->generator;
248 
249     HcfSymKey *key = nullptr;
250     context->errCode = generator->convertSymKey(generator, &context->keyMaterial, &key);
251     if (context->errCode != HCF_SUCCESS) {
252         LOGE("convertSymKey key failed!");
253         context->errMsg = "convert sym key failed.";
254         return;
255     }
256 
257     context->returnSymKey = key;
258 }
259 
NewConvertKeyAsyncWork(napi_env env,SymKeyGeneratorFwkCtx context)260 static napi_value NewConvertKeyAsyncWork(napi_env env, SymKeyGeneratorFwkCtx context)
261 {
262     napi_value resourceName = nullptr;
263     napi_create_string_utf8(env, "convertSymKey", NAPI_AUTO_LENGTH, &resourceName);
264 
265     napi_create_async_work(
266         env,
267         nullptr,
268         resourceName,
269         [](napi_env env, void *data) {
270             AsyncConvertKeyProcess(env, data);
271             return;
272         },
273         [](napi_env env, napi_status status, void *data) {
274             AsyncKeyReturn(env, status, data);
275             return;
276         },
277         static_cast<void *>(context),
278         &context->asyncWork);
279 
280     napi_queue_async_work(env, context->asyncWork);
281     if (context->asyncType == ASYNC_PROMISE) {
282         return context->promise;
283     } else {
284         return NapiGetNull(env);
285     }
286 }
287 
NewGenKeyAsyncWork(napi_env env,SymKeyGeneratorFwkCtx context)288 static napi_value NewGenKeyAsyncWork(napi_env env, SymKeyGeneratorFwkCtx context)
289 {
290     napi_value resourceName = nullptr;
291     napi_create_string_utf8(env, "generatorSymKey", NAPI_AUTO_LENGTH, &resourceName);
292 
293     napi_create_async_work(
294         env,
295         nullptr,
296         resourceName,
297         [](napi_env env, void *data) {
298             AsyncGenKeyProcess(env, data);
299             return;
300         },
301         [](napi_env env, napi_status status, void *data) {
302             AsyncKeyReturn(env, status, data);
303             return;
304         },
305         static_cast<void *>(context),
306         &context->asyncWork);
307 
308     napi_queue_async_work(env, context->asyncWork);
309     if (context->asyncType == ASYNC_PROMISE) {
310         return context->promise;
311     } else {
312         return NapiGetNull(env);
313     }
314 }
315 
NapiSymKeyGenerator(HcfSymKeyGenerator * generator)316 NapiSymKeyGenerator::NapiSymKeyGenerator(HcfSymKeyGenerator *generator)
317 {
318     this->generator_ = generator;
319 }
320 
~NapiSymKeyGenerator()321 NapiSymKeyGenerator::~NapiSymKeyGenerator()
322 {
323     HcfObjDestroy(this->generator_);
324 }
325 
GetSymKeyGenerator() const326 HcfSymKeyGenerator *NapiSymKeyGenerator::GetSymKeyGenerator() const
327 {
328     return this->generator_;
329 }
330 
napiGetInstance(napi_env env,HcfSymKey * key,napi_value instance)331 static bool napiGetInstance(napi_env env, HcfSymKey *key, napi_value instance)
332 {
333     NapiSymKey *napiSymKey = new (std::nothrow) NapiSymKey(key);
334     if (napiSymKey == nullptr) {
335         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi sym key failed."));
336         LOGE("new napi sym key failed.");
337         HcfObjDestroy(key);
338         return false;
339     }
340 
341     napi_status wrapStatus = napi_wrap(
342         env, instance, napiSymKey,
343         [](napi_env env, void *data, void *hint) {
344             NapiSymKey *napiSymKey = static_cast<NapiSymKey *>(data);
345             delete napiSymKey;
346             return;
347         }, nullptr, nullptr);
348     if (wrapStatus != napi_ok) {
349         LOGE("failed to wrap napiSymKey obj!");
350         delete napiSymKey;
351         return false;
352     }
353 
354     return true;
355 }
356 
JsGenerateSymKey(napi_env env,napi_callback_info info)357 napi_value NapiSymKeyGenerator::JsGenerateSymKey(napi_env env, napi_callback_info info)
358 {
359     SymKeyGeneratorFwkCtx context = static_cast<SymKeyGeneratorFwkCtx>(HcfMalloc(sizeof(SymKeyGeneratorFwkCtxT), 0));
360     if (context == nullptr) {
361         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "Create context failed!"));
362         LOGE("Create context failed!");
363         return nullptr;
364     }
365 
366     if (!BuildContextForGenerateKey(env, info, context)) {
367         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "Build context fail."));
368         LOGE("Build context fail.");
369         FreeSymKeyGeneratorFwkCtx(env, context);
370         return nullptr;
371     }
372 
373     napi_value result = NewGenKeyAsyncWork(env, context);
374     if (result == nullptr) {
375         LOGE("NewGenKeyAsyncWork failed!");
376         FreeSymKeyGeneratorFwkCtx(env, context);
377         return nullptr;
378     }
379     return result;
380 }
381 
JsGenerateSymKeySync(napi_env env,napi_callback_info info)382 napi_value NapiSymKeyGenerator::JsGenerateSymKeySync(napi_env env, napi_callback_info info)
383 {
384     napi_value thisVar = nullptr;
385     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
386     NapiSymKeyGenerator *napiGenerator = nullptr;
387     napi_status unwrapStatus = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiGenerator));
388     if (unwrapStatus != napi_ok || napiGenerator == nullptr) {
389         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "failed to unwrap NapiSymKeyGenerator obj."));
390         LOGE("failed to unwrap NapiSymKeyGenerator obj!");
391         return nullptr;
392     }
393 
394     HcfSymKeyGenerator *generator = napiGenerator->GetSymKeyGenerator();
395     if (generator == nullptr) {
396         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "failed to get generator obj."));
397         LOGE("failed to get generator obj!");
398         return nullptr;
399     }
400 
401     HcfSymKey *key = nullptr;
402     HcfResult ret = generator->generateSymKey(generator, &key);
403     if (ret != HCF_SUCCESS) {
404         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "generate sym key failed."));
405         LOGE("generate sym key failed.");
406         return nullptr;
407     }
408 
409     napi_value instance = NapiSymKey::CreateSymKey(env);
410     if (!napiGetInstance(env, key, instance)) {
411         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "get instance failed!"));
412         LOGE("get instance failed!");
413         return nullptr;
414     }
415 
416     return instance;
417 }
418 
JsConvertKey(napi_env env,napi_callback_info info)419 napi_value NapiSymKeyGenerator::JsConvertKey(napi_env env, napi_callback_info info)
420 {
421     SymKeyGeneratorFwkCtx context = static_cast<SymKeyGeneratorFwkCtx>(HcfMalloc(sizeof(SymKeyGeneratorFwkCtxT), 0));
422     if (context == nullptr) {
423         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc SymKeyGeneratorFwkCtx failed!"));
424         LOGE("malloc SymKeyGeneratorFwkCtx failed!");
425         return nullptr;
426     }
427 
428     if (!BuildContextForConvertKey(env, info, context)) {
429         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "BuildContextForConvertKey failed!"));
430         LOGE("BuildContextForConvertKey failed!");
431         FreeSymKeyGeneratorFwkCtx(env, context);
432         return nullptr;
433     }
434 
435     napi_value result = NewConvertKeyAsyncWork(env, context);
436     if (result == nullptr) {
437         LOGE("Get deviceauth async work failed!");
438         FreeSymKeyGeneratorFwkCtx(env, context);
439         return nullptr;
440     }
441     return result;
442 }
443 
JsConvertKeySync(napi_env env,napi_callback_info info)444 napi_value NapiSymKeyGenerator::JsConvertKeySync(napi_env env, napi_callback_info info)
445 {
446     napi_value thisVar = nullptr;
447     size_t argc = ARGS_SIZE_ONE;
448     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
449     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
450     if (argc != ARGS_SIZE_ONE) {
451         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "the input args num is invalid!"));
452         LOGE("wrong argument num. require 1 argument. [Argc]: %zu!", argc);
453         return nullptr;
454     }
455 
456     NapiSymKeyGenerator *napiGenerator = nullptr;
457     napi_status unwrapStatus = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiGenerator));
458     if (unwrapStatus != napi_ok || napiGenerator == nullptr) {
459         LOGE("failed to unwrap NapiSymKeyGenerator obj!");
460         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap NapiSymKeyGenerator obj!"));
461         return nullptr;
462     }
463 
464     HcfSymKeyGenerator *generator = napiGenerator->GetSymKeyGenerator();
465     if (generator == nullptr) {
466         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "failed to get generator obj!"));
467         LOGE("failed to get generator obj!");
468         return nullptr;
469     }
470 
471     HcfBlob *keyMaterial = GetBlobFromNapiDataBlob(env, argv[PARAM0]);
472     if (keyMaterial == nullptr) {
473         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get keyMaterial failed!"));
474         LOGE("get keyMaterial failed!");
475         return nullptr;
476     }
477 
478     HcfSymKey *key = nullptr;
479     HcfResult ret = generator->convertSymKey(generator, keyMaterial, &key);
480     HcfBlobDataClearAndFree(keyMaterial);
481     HcfFree(keyMaterial);
482     if (ret != HCF_SUCCESS) {
483         napi_throw(env, GenerateBusinessError(env, ret, "convertSymKey key failed!"));
484         LOGE("convertSymKey key failed!");
485         return nullptr;
486     }
487 
488     napi_value instance = NapiSymKey::CreateSymKey(env);
489     if (!napiGetInstance(env, key, instance)) {
490         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "get instance failed!"));
491         LOGE("get instance failed!");
492         return nullptr;
493     }
494 
495     return instance;
496 }
497 
SymKeyGeneratorConstructor(napi_env env,napi_callback_info info)498 napi_value NapiSymKeyGenerator::SymKeyGeneratorConstructor(napi_env env, napi_callback_info info)
499 {
500     napi_value thisVar = nullptr;
501     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
502     return thisVar;
503 }
504 
CreateSymKeyGenerator(napi_env env,napi_callback_info info)505 napi_value NapiSymKeyGenerator::CreateSymKeyGenerator(napi_env env, napi_callback_info info)
506 {
507     LOGD("Enter CreateSymKeyGenerator...");
508     size_t expectedArgc = ARGS_SIZE_ONE;
509     size_t argc = ARGS_SIZE_ONE;
510     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
511     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
512 
513     if (argc != expectedArgc) {
514         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
515         LOGE("The input args num is invalid.");
516         return nullptr;
517     }
518 
519     napi_value instance;
520     napi_value constructor = nullptr;
521     napi_get_reference_value(env, classRef_, &constructor);
522     napi_new_instance(env, constructor, argc, argv, &instance);
523 
524     std::string algoName;
525     if (!GetStringFromJSParams(env, argv[0], algoName)) {
526         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get algoName."));
527         LOGE("failed to get algoName.");
528         return nullptr;
529     }
530 
531     HcfSymKeyGenerator *generator = nullptr;
532     HcfResult res = HcfSymKeyGeneratorCreate(algoName.c_str(), &generator);
533     if (res != HCF_SUCCESS) {
534         napi_throw(env, GenerateBusinessError(env, res, "create C generator fail."));
535         LOGE("create C generator fail.");
536         return nullptr;
537     }
538     NapiSymKeyGenerator *napiSymKeyGenerator = new (std::nothrow) NapiSymKeyGenerator(generator);
539     if (napiSymKeyGenerator == nullptr) {
540         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi sym key generator failed."));
541         LOGE("new napi sym key generator failed!");
542         HcfObjDestroy(generator);
543         return nullptr;
544     }
545 
546     napi_status status = napi_wrap(env, instance, napiSymKeyGenerator,
547         [](napi_env env, void *data, void *hint) {
548             NapiSymKeyGenerator *napiSymKeyGenerator = static_cast<NapiSymKeyGenerator *>(data);
549             delete napiSymKeyGenerator;
550             return;
551         }, nullptr, nullptr);
552     if (status != napi_ok) {
553         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap napiSymKeyGenerator obj!"));
554         LOGE("failed to wrap napiSymKeyGenerator obj!");
555         delete napiSymKeyGenerator;
556         return nullptr;
557     }
558     return instance;
559 }
560 
JsGetAlgorithm(napi_env env,napi_callback_info info)561 napi_value NapiSymKeyGenerator::JsGetAlgorithm(napi_env env, napi_callback_info info)
562 {
563     napi_value thisVar = nullptr;
564     NapiSymKeyGenerator *napiSymKeyGenerator = nullptr;
565     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
566     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiSymKeyGenerator));
567     if (status != napi_ok || napiSymKeyGenerator == nullptr) {
568         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiSymKeyGenerator obj!"));
569         LOGE("failed to unwrap napiSymKeyGenerator obj!");
570         return nullptr;
571     }
572     HcfSymKeyGenerator *generator = napiSymKeyGenerator->GetSymKeyGenerator();
573 
574     const char *algo = generator->getAlgoName(generator);
575     napi_value instance = nullptr;
576     napi_create_string_utf8(env, algo, NAPI_AUTO_LENGTH, &instance);
577     return instance;
578 }
579 
DefineSymKeyGeneratorJSClass(napi_env env,napi_value exports)580 void NapiSymKeyGenerator::DefineSymKeyGeneratorJSClass(napi_env env, napi_value exports)
581 {
582     napi_property_descriptor desc[] = {
583         DECLARE_NAPI_FUNCTION("createSymKeyGenerator", NapiSymKeyGenerator::CreateSymKeyGenerator),
584     };
585     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
586 
587     napi_property_descriptor classDesc[] = {
588         DECLARE_NAPI_FUNCTION("generateSymKey", NapiSymKeyGenerator::JsGenerateSymKey),
589         DECLARE_NAPI_FUNCTION("generateSymKeySync", NapiSymKeyGenerator::JsGenerateSymKeySync),
590         DECLARE_NAPI_FUNCTION("convertKey", NapiSymKeyGenerator::JsConvertKey),
591         DECLARE_NAPI_FUNCTION("convertKeySync", NapiSymKeyGenerator::JsConvertKeySync),
592         { .utf8name = "algName", .getter = NapiSymKeyGenerator::JsGetAlgorithm },
593     };
594     napi_value constructor = nullptr;
595     napi_define_class(env, "SymKeyGenerator", NAPI_AUTO_LENGTH,
596         NapiSymKeyGenerator::SymKeyGeneratorConstructor, nullptr,
597         sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor);
598     napi_create_reference(env, constructor, 1, &classRef_);
599 }
600 } // CryptoFramework
601 } // OHOS