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_asy_key_generator.h"
17
18 #include "securec.h"
19 #include "log.h"
20 #include "memory.h"
21
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 {
30 struct GenKeyPairCtx {
31 napi_env env = nullptr;
32
33 AsyncType asyncType = ASYNC_CALLBACK;
34 napi_ref callback = nullptr;
35 napi_deferred deferred = nullptr;
36 napi_value promise = nullptr;
37 napi_async_work asyncWork = nullptr;
38
39 HcfAsyKeyGenerator *generator = nullptr;
40 HcfParamsSpec *params = nullptr;
41
42 HcfResult errCode = HCF_SUCCESS;
43 const char *errMsg = nullptr;
44 HcfKeyPair *returnKeyPair = nullptr;
45 };
46
47 struct ConvertKeyCtx {
48 napi_env env = nullptr;
49
50 AsyncType asyncType = ASYNC_CALLBACK;
51 napi_ref callback = nullptr;
52 napi_deferred deferred = nullptr;
53 napi_value promise = nullptr;
54 napi_async_work asyncWork = nullptr;
55
56 HcfAsyKeyGenerator *generator = nullptr;
57 HcfParamsSpec *params = nullptr;
58 HcfBlob *pubKey = nullptr;
59 HcfBlob *priKey = nullptr;
60
61 HcfResult errCode = HCF_SUCCESS;
62 const char *errMsg = nullptr;
63 HcfKeyPair *returnKeyPair = nullptr;
64 };
65
66 thread_local napi_ref NapiAsyKeyGenerator::classRef_ = nullptr;
67
FreeGenKeyPairCtx(napi_env env,GenKeyPairCtx * ctx)68 static void FreeGenKeyPairCtx(napi_env env, GenKeyPairCtx *ctx)
69 {
70 if (ctx == nullptr) {
71 return;
72 }
73
74 if (ctx->asyncWork != nullptr) {
75 napi_delete_async_work(env, ctx->asyncWork);
76 ctx->asyncWork = nullptr;
77 }
78
79 if (ctx->callback != nullptr) {
80 napi_delete_reference(env, ctx->callback);
81 ctx->callback = nullptr;
82 }
83
84 HcfFree(ctx);
85 }
86
FreeConvertKeyCtx(napi_env env,ConvertKeyCtx * ctx)87 static void FreeConvertKeyCtx(napi_env env, ConvertKeyCtx *ctx)
88 {
89 if (ctx == nullptr) {
90 return;
91 }
92
93 if (ctx->asyncWork != nullptr) {
94 napi_delete_async_work(env, ctx->asyncWork);
95 ctx->asyncWork = nullptr;
96 }
97
98 if (ctx->callback != nullptr) {
99 napi_delete_reference(env, ctx->callback);
100 ctx->callback = nullptr;
101 }
102
103 HcfBlobDataFree(ctx->pubKey);
104 HcfFree(ctx->pubKey);
105 HcfBlobDataFree(ctx->priKey);
106 HcfFree(ctx->priKey);
107 HcfFree(ctx);
108 }
109
BuildGenKeyPairCtx(napi_env env,napi_callback_info info,GenKeyPairCtx * ctx)110 static bool BuildGenKeyPairCtx(napi_env env, napi_callback_info info, GenKeyPairCtx *ctx)
111 {
112 napi_value thisVar = nullptr;
113 size_t expectedArgc = PARAMS_NUM_ONE;
114 size_t argc = expectedArgc;
115 napi_value argv[PARAMS_NUM_ONE] = { nullptr };
116 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
117 if (argc != expectedArgc && argc != expectedArgc - 1) {
118 LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc);
119 return false;
120 }
121 ctx->asyncType = isCallback(env, argv[0], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
122
123 NapiAsyKeyGenerator *napiGenerator;
124 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiGenerator));
125 if (status != napi_ok || napiGenerator == nullptr) {
126 LOGE("failed to unwrap napi asyKeyGenerator obj.");
127 return false;
128 }
129
130 ctx->generator = napiGenerator->GetAsyKeyGenerator();
131 ctx->params = nullptr;
132
133 if (ctx->asyncType == ASYNC_PROMISE) {
134 napi_create_promise(env, &ctx->deferred, &ctx->promise);
135 return true;
136 } else {
137 return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback);
138 }
139 }
140
GetPkAndSkBlobFromNapiValueIfInput(napi_env env,napi_value pkValue,napi_value skValue,HcfBlob ** returnPubKey,HcfBlob ** returnPriKey)141 static bool GetPkAndSkBlobFromNapiValueIfInput(napi_env env, napi_value pkValue, napi_value skValue,
142 HcfBlob **returnPubKey, HcfBlob **returnPriKey)
143 {
144 napi_valuetype valueType;
145 napi_typeof(env, pkValue, &valueType);
146 HcfBlob *pubKey = nullptr;
147 if (valueType != napi_null) {
148 pubKey = GetBlobFromNapiValue(env, pkValue);
149 if (pubKey == nullptr) {
150 LOGE("failed to get pubKey.");
151 return false;
152 }
153 }
154
155 napi_typeof(env, skValue, &valueType);
156 HcfBlob *priKey = nullptr;
157 if (valueType != napi_null) {
158 priKey = GetBlobFromNapiValue(env, skValue);
159 if (priKey == nullptr) {
160 LOGE("failed to get priKey.");
161 return false;
162 }
163 }
164
165 *returnPubKey = pubKey;
166 *returnPriKey = priKey;
167 return true;
168 }
169
BuildConvertKeyCtx(napi_env env,napi_callback_info info,ConvertKeyCtx * ctx)170 static bool BuildConvertKeyCtx(napi_env env, napi_callback_info info, ConvertKeyCtx *ctx)
171 {
172 napi_value thisVar = nullptr;
173 size_t expectedArgc = PARAMS_NUM_THREE;
174 size_t argc = expectedArgc;
175 napi_value argv[PARAMS_NUM_THREE] = { nullptr };
176 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
177 if (argc != expectedArgc && argc != expectedArgc - 1) {
178 LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc);
179 return false;
180 }
181 ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
182
183 NapiAsyKeyGenerator *napiGenerator;
184 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiGenerator));
185 if (status != napi_ok || napiGenerator == nullptr) {
186 LOGE("failed to unwrap napi asyKeyGenerator obj.");
187 return false;
188 }
189
190 HcfBlob *pubKey = nullptr;
191 HcfBlob *priKey = nullptr;
192 if (!GetPkAndSkBlobFromNapiValueIfInput(env, argv[PARAM0], argv[PARAM1], &pubKey, &priKey)) {
193 return false;
194 }
195
196 ctx->generator = napiGenerator->GetAsyKeyGenerator();
197 ctx->params = nullptr;
198 ctx->pubKey = pubKey;
199 ctx->priKey = priKey;
200
201 if (ctx->asyncType == ASYNC_PROMISE) {
202 napi_create_promise(env, &ctx->deferred, &ctx->promise);
203 return true;
204 } else {
205 return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback);
206 }
207 }
208
ReturnGenKeyPairCallbackResult(napi_env env,GenKeyPairCtx * ctx,napi_value result)209 static void ReturnGenKeyPairCallbackResult(napi_env env, GenKeyPairCtx *ctx, napi_value result)
210 {
211 napi_value businessError = nullptr;
212 if (ctx->errCode != HCF_SUCCESS) {
213 businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg);
214 }
215
216 napi_value params[ARGS_SIZE_TWO] = { businessError, result };
217
218 napi_value func = nullptr;
219 napi_get_reference_value(env, ctx->callback, &func);
220
221 napi_value recv = nullptr;
222 napi_value callFuncRet = nullptr;
223 napi_get_undefined(env, &recv);
224 napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
225 }
226
ReturnGenKeyPairPromiseResult(napi_env env,GenKeyPairCtx * ctx,napi_value result)227 static void ReturnGenKeyPairPromiseResult(napi_env env, GenKeyPairCtx *ctx, napi_value result)
228 {
229 if (ctx->errCode == HCF_SUCCESS) {
230 napi_resolve_deferred(env, ctx->deferred, result);
231 } else {
232 napi_reject_deferred(env, ctx->deferred,
233 GenerateBusinessError(env, ctx->errCode, ctx->errMsg));
234 }
235 }
236
ReturnConvertKeyCallbackResult(napi_env env,ConvertKeyCtx * ctx,napi_value result)237 static void ReturnConvertKeyCallbackResult(napi_env env, ConvertKeyCtx *ctx, napi_value result)
238 {
239 napi_value businessError = nullptr;
240 if (ctx->errCode != HCF_SUCCESS) {
241 businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg);
242 }
243
244 napi_value params[ARGS_SIZE_TWO] = { businessError, result };
245
246 napi_value func = nullptr;
247 napi_get_reference_value(env, ctx->callback, &func);
248
249 napi_value recv = nullptr;
250 napi_value callFuncRet = nullptr;
251 napi_get_undefined(env, &recv);
252 napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
253 }
254
ReturnConvertKeyPromiseResult(napi_env env,ConvertKeyCtx * ctx,napi_value result)255 static void ReturnConvertKeyPromiseResult(napi_env env, ConvertKeyCtx *ctx, napi_value result)
256 {
257 if (ctx->errCode == HCF_SUCCESS) {
258 napi_resolve_deferred(env, ctx->deferred, result);
259 } else {
260 napi_reject_deferred(env, ctx->deferred,
261 GenerateBusinessError(env, ctx->errCode, ctx->errMsg));
262 }
263 }
264
GenKeyPairAsyncWorkProcess(napi_env env,void * data)265 static void GenKeyPairAsyncWorkProcess(napi_env env, void *data)
266 {
267 GenKeyPairCtx *ctx = static_cast<GenKeyPairCtx *>(data);
268
269 ctx->errCode = ctx->generator->generateKeyPair(ctx->generator, ctx->params, &(ctx->returnKeyPair));
270 if (ctx->errCode != HCF_SUCCESS) {
271 LOGE("generate key pair fail.");
272 ctx->errMsg = "generate key pair fail.";
273 }
274 }
275
GenKeyPairAsyncWorkReturn(napi_env env,napi_status status,void * data)276 static void GenKeyPairAsyncWorkReturn(napi_env env, napi_status status, void *data)
277 {
278 GenKeyPairCtx *ctx = static_cast<GenKeyPairCtx *>(data);
279
280 napi_value instance = nullptr;
281 if (ctx->errCode == HCF_SUCCESS) {
282 NapiKeyPair *napiKeyPair = new (std::nothrow) NapiKeyPair(ctx->returnKeyPair);
283 if (napiKeyPair == nullptr) {
284 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi key pair failed!"));
285 LOGE("new napi key pair failed");
286 FreeGenKeyPairCtx(env, ctx);
287 return;
288 }
289 instance = napiKeyPair->ConvertToJsKeyPair(env);
290
291 napi_status ret = napi_wrap(
292 env, instance, napiKeyPair,
293 [](napi_env env, void *data, void *hint) {
294 NapiKeyPair *keyPair = static_cast<NapiKeyPair *>(data);
295 delete keyPair;
296 return;
297 }, nullptr, nullptr);
298 if (ret != napi_ok) {
299 LOGE("failed to wrap napiKeyPair obj!");
300 ctx->errCode = HCF_INVALID_PARAMS;
301 ctx->errMsg = "failed to wrap napiKeyPair obj!";
302 delete napiKeyPair;
303 }
304 }
305
306 if (ctx->asyncType == ASYNC_CALLBACK) {
307 ReturnGenKeyPairCallbackResult(env, ctx, instance);
308 } else {
309 ReturnGenKeyPairPromiseResult(env, ctx, instance);
310 }
311 FreeGenKeyPairCtx(env, ctx);
312 }
313
ConvertKeyAsyncWorkProcess(napi_env env,void * data)314 static void ConvertKeyAsyncWorkProcess(napi_env env, void *data)
315 {
316 ConvertKeyCtx *ctx = static_cast<ConvertKeyCtx *>(data);
317
318 ctx->errCode = ctx->generator->convertKey(ctx->generator, ctx->params,
319 ctx->pubKey, ctx->priKey, &(ctx->returnKeyPair));
320 if (ctx->errCode != HCF_SUCCESS) {
321 LOGE("convert key fail.");
322 ctx->errMsg = "convert key fail.";
323 }
324 }
325
ConvertKeyAsyncWorkReturn(napi_env env,napi_status status,void * data)326 static void ConvertKeyAsyncWorkReturn(napi_env env, napi_status status, void *data)
327 {
328 ConvertKeyCtx *ctx = static_cast<ConvertKeyCtx *>(data);
329
330 napi_value instance = nullptr;
331 if (ctx->errCode == HCF_SUCCESS) {
332 NapiKeyPair *napiKeyPair = new (std::nothrow) NapiKeyPair(ctx->returnKeyPair);
333 if (napiKeyPair == nullptr) {
334 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi key pair failed!"));
335 LOGE("new napi key pair failed");
336 FreeConvertKeyCtx(env, ctx);
337 return;
338 }
339 instance = napiKeyPair->ConvertToJsKeyPair(env);
340
341 napi_status ret = napi_wrap(
342 env, instance, napiKeyPair,
343 [](napi_env env, void *data, void *hint) {
344 NapiKeyPair *keyPair = static_cast<NapiKeyPair *>(data);
345 delete keyPair;
346 return;
347 }, nullptr, nullptr);
348 if (ret != napi_ok) {
349 LOGE("failed to wrap napiKeyPair obj!");
350 ctx->errCode = HCF_INVALID_PARAMS;
351 ctx->errMsg = "failed to wrap napiKeyPair obj!";
352 delete napiKeyPair;
353 }
354 }
355
356 if (ctx->asyncType == ASYNC_CALLBACK) {
357 ReturnConvertKeyCallbackResult(env, ctx, instance);
358 } else {
359 ReturnConvertKeyPromiseResult(env, ctx, instance);
360 }
361 FreeConvertKeyCtx(env, ctx);
362 }
363
NewGenKeyPairAsyncWork(napi_env env,GenKeyPairCtx * ctx)364 static napi_value NewGenKeyPairAsyncWork(napi_env env, GenKeyPairCtx *ctx)
365 {
366 napi_value resourceName = nullptr;
367 napi_create_string_utf8(env, "generatorKeyPair", NAPI_AUTO_LENGTH, &resourceName);
368
369 napi_create_async_work(
370 env, nullptr, resourceName,
371 [](napi_env env, void *data) {
372 GenKeyPairAsyncWorkProcess(env, data);
373 return;
374 },
375 [](napi_env env, napi_status status, void *data) {
376 GenKeyPairAsyncWorkReturn(env, status, data);
377 return;
378 },
379 static_cast<void *>(ctx),
380 &ctx->asyncWork);
381
382 napi_queue_async_work(env, ctx->asyncWork);
383 if (ctx->asyncType == ASYNC_PROMISE) {
384 return ctx->promise;
385 } else {
386 return NapiGetNull(env);
387 }
388 }
389
NewConvertKeyAsyncWork(napi_env env,ConvertKeyCtx * ctx)390 static napi_value NewConvertKeyAsyncWork(napi_env env, ConvertKeyCtx *ctx)
391 {
392 napi_value resourceName = nullptr;
393 napi_create_string_utf8(env, "convertKey", NAPI_AUTO_LENGTH, &resourceName);
394
395 napi_create_async_work(
396 env, nullptr, resourceName,
397 [](napi_env env, void *data) {
398 ConvertKeyAsyncWorkProcess(env, data);
399 return;
400 },
401 [](napi_env env, napi_status status, void *data) {
402 ConvertKeyAsyncWorkReturn(env, status, data);
403 return;
404 },
405 static_cast<void *>(ctx),
406 &ctx->asyncWork);
407
408 napi_queue_async_work(env, ctx->asyncWork);
409 if (ctx->asyncType == ASYNC_PROMISE) {
410 return ctx->promise;
411 } else {
412 return NapiGetNull(env);
413 }
414 }
415
NapiAsyKeyGenerator(HcfAsyKeyGenerator * generator)416 NapiAsyKeyGenerator::NapiAsyKeyGenerator(HcfAsyKeyGenerator *generator)
417 {
418 this->generator_ = generator;
419 }
420
~NapiAsyKeyGenerator()421 NapiAsyKeyGenerator::~NapiAsyKeyGenerator()
422 {
423 HcfObjDestroy(this->generator_);
424 }
425
GetAsyKeyGenerator()426 HcfAsyKeyGenerator *NapiAsyKeyGenerator::GetAsyKeyGenerator()
427 {
428 return this->generator_;
429 }
430
JsGenerateKeyPair(napi_env env,napi_callback_info info)431 napi_value NapiAsyKeyGenerator::JsGenerateKeyPair(napi_env env, napi_callback_info info)
432 {
433 GenKeyPairCtx *ctx = static_cast<GenKeyPairCtx *>(HcfMalloc(sizeof(GenKeyPairCtx), 0));
434 if (ctx == nullptr) {
435 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "malloc ctx fail."));
436 LOGE("create context fail.");
437 return nullptr;
438 }
439
440 if (!BuildGenKeyPairCtx(env, info, ctx)) {
441 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail."));
442 LOGE("build context fail.");
443 FreeGenKeyPairCtx(env, ctx);
444 return nullptr;
445 }
446
447 return NewGenKeyPairAsyncWork(env, ctx);
448 }
449
JsConvertKey(napi_env env,napi_callback_info info)450 napi_value NapiAsyKeyGenerator::JsConvertKey(napi_env env, napi_callback_info info)
451 {
452 ConvertKeyCtx *ctx = static_cast<ConvertKeyCtx *>(HcfMalloc(sizeof(ConvertKeyCtx), 0));
453 if (ctx == nullptr) {
454 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail!"));
455 LOGE("create context fail.");
456 return nullptr;
457 }
458
459 if (!BuildConvertKeyCtx(env, info, ctx)) {
460 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail."));
461 LOGE("build context fail.");
462 FreeConvertKeyCtx(env, ctx);
463 return nullptr;
464 }
465
466 return NewConvertKeyAsyncWork(env, ctx);
467 }
468
AsyKeyGeneratorConstructor(napi_env env,napi_callback_info info)469 napi_value NapiAsyKeyGenerator::AsyKeyGeneratorConstructor(napi_env env, napi_callback_info info)
470 {
471 napi_value thisVar = nullptr;
472 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
473 return thisVar;
474 }
475
NapiWrapAsyKeyGen(napi_env env,napi_value instance,NapiAsyKeyGenerator * napiAsyKeyGenerator)476 static napi_value NapiWrapAsyKeyGen(napi_env env, napi_value instance, NapiAsyKeyGenerator *napiAsyKeyGenerator)
477 {
478 napi_status status = napi_wrap(
479 env, instance, napiAsyKeyGenerator,
480 [](napi_env env, void *data, void *hint) {
481 NapiAsyKeyGenerator *napiAsyKeyGenerator = static_cast<NapiAsyKeyGenerator *>(data);
482 delete napiAsyKeyGenerator;
483 return;
484 }, nullptr, nullptr);
485 if (status != napi_ok) {
486 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap napiAsyKeyGenerator obj!"));
487 delete napiAsyKeyGenerator;
488 napiAsyKeyGenerator = nullptr;
489 LOGE("failed to wrap napiAsyKeyGenerator obj!");
490 return nullptr;
491 }
492 return instance;
493 }
494
CreateJsAsyKeyGenerator(napi_env env,napi_callback_info info)495 napi_value NapiAsyKeyGenerator::CreateJsAsyKeyGenerator(napi_env env, napi_callback_info info)
496 {
497 size_t expectedArgc = PARAMS_NUM_ONE;
498 size_t argc = expectedArgc;
499 napi_value argv[PARAMS_NUM_ONE] = { nullptr };
500 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
501 if (argc != expectedArgc) {
502 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
503 LOGE("The input args num is invalid.");
504 return NapiGetNull(env);
505 }
506
507 napi_value instance;
508 napi_value constructor = nullptr;
509 napi_get_reference_value(env, classRef_, &constructor);
510 napi_new_instance(env, constructor, argc, argv, &instance);
511
512 std::string algName;
513 if (!GetStringFromJSParams(env, argv[0], algName)) {
514 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get algoName."));
515 LOGE("failed to get algoName.");
516 return NapiGetNull(env);
517 }
518
519 HcfAsyKeyGenerator *generator = nullptr;
520 HcfResult res = HcfAsyKeyGeneratorCreate(algName.c_str(), &generator);
521 if (res != HCF_SUCCESS) {
522 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "create c generator fail."));
523 LOGE("create c generator fail.");
524 return NapiGetNull(env);
525 }
526
527 NapiAsyKeyGenerator *napiAsyKeyGenerator = new (std::nothrow) NapiAsyKeyGenerator(generator);
528 if (napiAsyKeyGenerator == nullptr) {
529 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi asy key napi generator failed!"));
530 LOGE("new napi asy key napi generator failed");
531 HcfObjDestroy(generator);
532 return NapiGetNull(env);
533 }
534
535 napi_value napiAlgName = nullptr;
536 napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName);
537 napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName);
538
539 return NapiWrapAsyKeyGen(env, instance, napiAsyKeyGenerator);
540 }
541
DefineAsyKeyGeneratorJSClass(napi_env env,napi_value exports)542 void NapiAsyKeyGenerator::DefineAsyKeyGeneratorJSClass(napi_env env, napi_value exports)
543 {
544 napi_property_descriptor desc[] = {
545 DECLARE_NAPI_FUNCTION("createAsyKeyGenerator", NapiAsyKeyGenerator::CreateJsAsyKeyGenerator),
546 };
547 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
548
549 napi_property_descriptor classDesc[] = {
550 DECLARE_NAPI_FUNCTION("generateKeyPair", NapiAsyKeyGenerator::JsGenerateKeyPair),
551 DECLARE_NAPI_FUNCTION("convertKey", NapiAsyKeyGenerator::JsConvertKey),
552 };
553 napi_value constructor = nullptr;
554 napi_define_class(env, "AsyKeyGenerator", NAPI_AUTO_LENGTH, NapiAsyKeyGenerator::AsyKeyGeneratorConstructor,
555 nullptr, sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor);
556 napi_create_reference(env, constructor, 1, &classRef_);
557 }
558 } // CryptoFramework
559 } // OHOS
560