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_asy_key_spec_generator.h"
17
18 #include "asy_key_params.h"
19 #include "securec.h"
20 #include "log.h"
21 #include "memory.h"
22
23 #include "napi_crypto_framework_defines.h"
24 #include "napi_utils.h"
25 #include "napi_key_pair.h"
26 #include "napi_pri_key.h"
27 #include "napi_pub_key.h"
28
29 namespace OHOS {
30 namespace CryptoFramework {
31 struct AsyKeyCtx {
32 napi_env env = nullptr;
33
34 AsyncType asyncType = ASYNC_CALLBACK;
35 napi_ref callback = nullptr;
36 napi_deferred deferred = nullptr;
37 napi_value promise = nullptr;
38 napi_async_work asyncWork = nullptr;
39 napi_ref generatorRef = nullptr;
40
41 HcfAsyKeyGeneratorBySpec *generator;
42 HcfResult errCode = HCF_SUCCESS;
43 const char *errMsg = nullptr;
44 HcfKeyPair *returnKeyPair = nullptr;
45 HcfPubKey *returnPubKey = nullptr;
46 HcfPriKey *returnPriKey = nullptr;
47 };
48
49 thread_local napi_ref NapiAsyKeyGeneratorBySpec::classRef_ = nullptr;
50
FreeAsyKeyCtx(napi_env env,AsyKeyCtx * ctx)51 static void FreeAsyKeyCtx(napi_env env, AsyKeyCtx *ctx)
52 {
53 if (ctx == nullptr) {
54 return;
55 }
56
57 if (ctx->asyncWork != nullptr) {
58 napi_delete_async_work(env, ctx->asyncWork);
59 ctx->asyncWork = nullptr;
60 }
61
62 if (ctx->callback != nullptr) {
63 napi_delete_reference(env, ctx->callback);
64 ctx->callback = nullptr;
65 }
66
67 if (ctx->generatorRef != nullptr) {
68 napi_delete_reference(env, ctx->generatorRef);
69 ctx->generatorRef = nullptr;
70 }
71
72 HcfFree(ctx);
73 }
74
BuildAsyKeyCtx(napi_env env,napi_callback_info info,AsyKeyCtx * ctx)75 static bool BuildAsyKeyCtx(napi_env env, napi_callback_info info, AsyKeyCtx *ctx)
76 {
77 napi_value thisVar = nullptr;
78 size_t expectedArgc = PARAMS_NUM_ONE;
79 size_t argc = expectedArgc;
80 napi_value argv[PARAMS_NUM_ONE] = { nullptr };
81 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
82 if (argc != expectedArgc && argc != expectedArgc - 1) {
83 LOGE("wrong argument num. require %{public}zu or %{public}zu arguments. [Argc]: %{public}zu!",
84 expectedArgc - 1, expectedArgc, argc);
85 return false;
86 }
87 ctx->asyncType = isCallback(env, argv[0], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
88
89 NapiAsyKeyGeneratorBySpec *napiGenerator = nullptr;
90 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiGenerator));
91 if (status != napi_ok || napiGenerator == nullptr) {
92 LOGE("failed to unwrap napi asyKeyGenerator obj.");
93 return false;
94 }
95 ctx->generator = napiGenerator->GetAsyKeyGeneratorBySpec();
96
97 if (napi_create_reference(env, thisVar, 1, &ctx->generatorRef) != napi_ok) {
98 LOGE("create generator ref failed when generator asym key by spec!");
99 return false;
100 }
101
102 if (ctx->asyncType == ASYNC_PROMISE) {
103 napi_create_promise(env, &ctx->deferred, &ctx->promise);
104 return true;
105 } else {
106 return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback);
107 }
108 }
109
GetAsyKeyGenerator(napi_env env,napi_callback_info info,HcfAsyKeyGeneratorBySpec ** generator)110 static bool GetAsyKeyGenerator(napi_env env, napi_callback_info info, HcfAsyKeyGeneratorBySpec **generator)
111 {
112 napi_value thisVar = nullptr;
113 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
114
115 NapiAsyKeyGeneratorBySpec *napiGenerator = nullptr;
116 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiGenerator));
117 if (status != napi_ok || napiGenerator == nullptr) {
118 LOGE("failed to unwrap napi asyKeyGenerator obj.");
119 return false;
120 }
121 *generator = napiGenerator->GetAsyKeyGeneratorBySpec();
122 return true;
123 }
124
ReturnAsyKeyCallbackResult(napi_env env,AsyKeyCtx * ctx,napi_value result)125 static void ReturnAsyKeyCallbackResult(napi_env env, AsyKeyCtx *ctx, napi_value result)
126 {
127 napi_value businessError = nullptr;
128 if (ctx->errCode != HCF_SUCCESS) {
129 businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg);
130 }
131
132 napi_value params[ARGS_SIZE_TWO] = { businessError, result };
133
134 napi_value func = nullptr;
135 napi_get_reference_value(env, ctx->callback, &func);
136
137 napi_value recv = nullptr;
138 napi_value callFuncRet = nullptr;
139 napi_get_undefined(env, &recv);
140 napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
141 }
142
ReturnAsyKeyPromiseResult(napi_env env,AsyKeyCtx * ctx,napi_value result)143 static void ReturnAsyKeyPromiseResult(napi_env env, AsyKeyCtx *ctx, napi_value result)
144 {
145 if (ctx->errCode == HCF_SUCCESS) {
146 napi_resolve_deferred(env, ctx->deferred, result);
147 } else {
148 napi_reject_deferred(env, ctx->deferred,
149 GenerateBusinessError(env, ctx->errCode, ctx->errMsg));
150 }
151 }
152
GenKeyPairAsyncWorkProcess(napi_env env,void * data)153 static void GenKeyPairAsyncWorkProcess(napi_env env, void *data)
154 {
155 AsyKeyCtx *ctx = static_cast<AsyKeyCtx *>(data);
156
157 ctx->errCode = ctx->generator->generateKeyPair(ctx->generator, &(ctx->returnKeyPair));
158 if (ctx->errCode != HCF_SUCCESS) {
159 LOGD("[error] generate key pair fail.");
160 ctx->errMsg = "generate key pair fail.";
161 }
162 }
163
GenKeyPairAsyncWorkReturn(napi_env env,napi_status status,void * data)164 static void GenKeyPairAsyncWorkReturn(napi_env env, napi_status status, void *data)
165 {
166 AsyKeyCtx *ctx = static_cast<AsyKeyCtx *>(data);
167
168 napi_value instance = nullptr;
169 if (ctx->errCode == HCF_SUCCESS) {
170 NapiKeyPair *napiKeyPair = new (std::nothrow) NapiKeyPair(ctx->returnKeyPair);
171 if (napiKeyPair == nullptr) {
172 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi key pair failed!"));
173 LOGE("new napi key pair failed");
174 HcfObjDestroy(ctx->returnKeyPair);
175 ctx->returnKeyPair = nullptr;
176 FreeAsyKeyCtx(env, ctx);
177 return;
178 }
179 instance = napiKeyPair->ConvertToJsKeyPair(env);
180
181 napi_status ret = napi_wrap(
182 env, instance, napiKeyPair,
183 [](napi_env env, void *data, void *hint) {
184 NapiKeyPair *keyPair = static_cast<NapiKeyPair *>(data);
185 delete keyPair;
186 return;
187 }, nullptr, nullptr);
188 if (ret != napi_ok) {
189 LOGE("failed to wrap napiKeyPair obj!");
190 ctx->errCode = HCF_INVALID_PARAMS;
191 ctx->errMsg = "failed to wrap napiKeyPair obj!";
192 delete napiKeyPair;
193 }
194 }
195
196 if (ctx->asyncType == ASYNC_CALLBACK) {
197 ReturnAsyKeyCallbackResult(env, ctx, instance);
198 } else {
199 ReturnAsyKeyPromiseResult(env, ctx, instance);
200 }
201 FreeAsyKeyCtx(env, ctx);
202 }
203
PubKeyAsyncWorkProcess(napi_env env,void * data)204 static void PubKeyAsyncWorkProcess(napi_env env, void *data)
205 {
206 AsyKeyCtx *ctx = static_cast<AsyKeyCtx *>(data);
207
208 ctx->errCode = ctx->generator->generatePubKey(ctx->generator, &(ctx->returnPubKey));
209 if (ctx->errCode != HCF_SUCCESS) {
210 LOGD("[error] generate PubKey fail.");
211 ctx->errMsg = "generate PubKey fail.";
212 }
213 }
214
PubKeyAsyncWorkReturn(napi_env env,napi_status status,void * data)215 static void PubKeyAsyncWorkReturn(napi_env env, napi_status status, void *data)
216 {
217 AsyKeyCtx *ctx = static_cast<AsyKeyCtx *>(data);
218
219 napi_value instance = nullptr;
220 if (ctx->errCode == HCF_SUCCESS) {
221 NapiPubKey *napiPubKey = new (std::nothrow) NapiPubKey(ctx->returnPubKey);
222 if (napiPubKey == nullptr) {
223 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi pub key failed!"));
224 LOGE("new napi pub key failed");
225 HcfObjDestroy(ctx->returnPubKey);
226 ctx->returnPubKey = nullptr;
227 FreeAsyKeyCtx(env, ctx);
228 return;
229 }
230 instance = napiPubKey->ConvertToJsPubKey(env);
231
232 napi_status ret = napi_wrap(
233 env, instance, napiPubKey,
234 [](napi_env env, void *data, void *hint) {
235 NapiPubKey *napiPubKey = static_cast<NapiPubKey *>(data);
236 HcfObjDestroy(napiPubKey->GetPubKey());
237 delete napiPubKey;
238 return;
239 }, nullptr, nullptr);
240 if (ret != napi_ok) {
241 LOGE("failed to wrap napiPubKey obj!");
242 ctx->errCode = HCF_INVALID_PARAMS;
243 ctx->errMsg = "failed to wrap napiPubKey obj!";
244 HcfObjDestroy(napiPubKey->GetPubKey());
245 delete napiPubKey;
246 }
247 }
248
249 if (ctx->asyncType == ASYNC_CALLBACK) {
250 ReturnAsyKeyCallbackResult(env, ctx, instance);
251 } else {
252 ReturnAsyKeyPromiseResult(env, ctx, instance);
253 }
254 FreeAsyKeyCtx(env, ctx);
255 }
256
PriKeyAsyncWorkProcess(napi_env env,void * data)257 static void PriKeyAsyncWorkProcess(napi_env env, void *data)
258 {
259 AsyKeyCtx *ctx = static_cast<AsyKeyCtx *>(data);
260
261 ctx->errCode = ctx->generator->generatePriKey(ctx->generator, &(ctx->returnPriKey));
262 if (ctx->errCode != HCF_SUCCESS) {
263 LOGD("[error] generate PriKey fail.");
264 ctx->errMsg = "generate PriKey fail.";
265 }
266 }
267
PriKeyAsyncWorkReturn(napi_env env,napi_status status,void * data)268 static void PriKeyAsyncWorkReturn(napi_env env, napi_status status, void *data)
269 {
270 AsyKeyCtx *ctx = static_cast<AsyKeyCtx *>(data);
271
272 napi_value instance = nullptr;
273 if (ctx->errCode == HCF_SUCCESS) {
274 NapiPriKey *napiPriKey = new (std::nothrow) NapiPriKey(ctx->returnPriKey);
275 if (napiPriKey == nullptr) {
276 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi pri key failed!"));
277 LOGE("new napi pri key failed");
278 HcfObjDestroy(ctx->returnPriKey);
279 ctx->returnPriKey = nullptr;
280 FreeAsyKeyCtx(env, ctx);
281 return;
282 }
283 instance = napiPriKey->ConvertToJsPriKey(env);
284
285 napi_status ret = napi_wrap(
286 env, instance, napiPriKey,
287 [](napi_env env, void *data, void *hint) {
288 NapiPriKey *napiPriKey = static_cast<NapiPriKey *>(data);
289 HcfObjDestroy(napiPriKey->GetPriKey());
290 delete napiPriKey;
291 return;
292 }, nullptr, nullptr);
293 if (ret != napi_ok) {
294 LOGE("failed to wrap napiPriKey obj!");
295 ctx->errCode = HCF_INVALID_PARAMS;
296 ctx->errMsg = "failed to wrap napiPriKey obj!";
297 HcfObjDestroy(napiPriKey->GetPriKey());
298 delete napiPriKey;
299 }
300 }
301
302 if (ctx->asyncType == ASYNC_CALLBACK) {
303 ReturnAsyKeyCallbackResult(env, ctx, instance);
304 } else {
305 ReturnAsyKeyPromiseResult(env, ctx, instance);
306 }
307 FreeAsyKeyCtx(env, ctx);
308 }
309
NewGenKeyPairAsyncWork(napi_env env,AsyKeyCtx * ctx)310 static napi_value NewGenKeyPairAsyncWork(napi_env env, AsyKeyCtx *ctx)
311 {
312 napi_value resourceName = nullptr;
313 napi_create_string_utf8(env, "generateKeyPair", NAPI_AUTO_LENGTH, &resourceName);
314
315 napi_create_async_work(
316 env, nullptr, resourceName,
317 [](napi_env env, void *data) {
318 GenKeyPairAsyncWorkProcess(env, data);
319 return;
320 },
321 [](napi_env env, napi_status status, void *data) {
322 GenKeyPairAsyncWorkReturn(env, status, data);
323 return;
324 },
325 static_cast<void *>(ctx),
326 &ctx->asyncWork);
327
328 napi_queue_async_work(env, ctx->asyncWork);
329 if (ctx->asyncType == ASYNC_PROMISE) {
330 return ctx->promise;
331 } else {
332 return NapiGetNull(env);
333 }
334 }
335
NewPubKeyAsyncWork(napi_env env,AsyKeyCtx * ctx)336 static napi_value NewPubKeyAsyncWork(napi_env env, AsyKeyCtx *ctx)
337 {
338 napi_value resourceName = nullptr;
339 napi_create_string_utf8(env, "generatePubKey", NAPI_AUTO_LENGTH, &resourceName);
340
341 napi_create_async_work(
342 env, nullptr, resourceName,
343 [](napi_env env, void *data) {
344 PubKeyAsyncWorkProcess(env, data);
345 return;
346 },
347 [](napi_env env, napi_status status, void *data) {
348 PubKeyAsyncWorkReturn(env, status, data);
349 return;
350 },
351 static_cast<void *>(ctx),
352 &ctx->asyncWork);
353
354 napi_queue_async_work(env, ctx->asyncWork);
355 if (ctx->asyncType == ASYNC_PROMISE) {
356 return ctx->promise;
357 } else {
358 return NapiGetNull(env);
359 }
360 }
361
NewPriKeyAsyncWork(napi_env env,AsyKeyCtx * ctx)362 static napi_value NewPriKeyAsyncWork(napi_env env, AsyKeyCtx *ctx)
363 {
364 napi_value resourceName = nullptr;
365 napi_create_string_utf8(env, "generatePriKey", NAPI_AUTO_LENGTH, &resourceName);
366
367 napi_create_async_work(
368 env, nullptr, resourceName,
369 [](napi_env env, void *data) {
370 PriKeyAsyncWorkProcess(env, data);
371 return;
372 },
373 [](napi_env env, napi_status status, void *data) {
374 PriKeyAsyncWorkReturn(env, status, data);
375 return;
376 },
377 static_cast<void *>(ctx),
378 &ctx->asyncWork);
379
380 napi_queue_async_work(env, ctx->asyncWork);
381 if (ctx->asyncType == ASYNC_PROMISE) {
382 return ctx->promise;
383 } else {
384 return NapiGetNull(env);
385 }
386 }
387
NapiAsyKeyGeneratorBySpec(HcfAsyKeyGeneratorBySpec * generator)388 NapiAsyKeyGeneratorBySpec::NapiAsyKeyGeneratorBySpec(HcfAsyKeyGeneratorBySpec *generator)
389 {
390 this->generator_ = generator;
391 }
392
~NapiAsyKeyGeneratorBySpec()393 NapiAsyKeyGeneratorBySpec::~NapiAsyKeyGeneratorBySpec()
394 {
395 HcfObjDestroy(this->generator_);
396 this->generator_ = nullptr;
397 }
398
GetAsyKeyGeneratorBySpec()399 HcfAsyKeyGeneratorBySpec *NapiAsyKeyGeneratorBySpec::GetAsyKeyGeneratorBySpec()
400 {
401 return this->generator_;
402 }
403
JsGenerateKeyPair(napi_env env,napi_callback_info info)404 napi_value NapiAsyKeyGeneratorBySpec::JsGenerateKeyPair(napi_env env, napi_callback_info info)
405 {
406 AsyKeyCtx *ctx = static_cast<AsyKeyCtx *>(HcfMalloc(sizeof(AsyKeyCtx), 0));
407 if (ctx == nullptr) {
408 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail!"));
409 LOGE("create context fail.");
410 return nullptr;
411 }
412
413 if (!BuildAsyKeyCtx(env, info, ctx)) {
414 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail!"));
415 LOGE("build context fail.");
416 FreeAsyKeyCtx(env, ctx);
417 return nullptr;
418 }
419
420 return NewGenKeyPairAsyncWork(env, ctx);
421 }
422
JsGenerateKeyPairSync(napi_env env,napi_callback_info info)423 napi_value NapiAsyKeyGeneratorBySpec::JsGenerateKeyPairSync(napi_env env, napi_callback_info info)
424 {
425 HcfAsyKeyGeneratorBySpec *generator = nullptr;
426 if (!GetAsyKeyGenerator(env, info, &generator) || generator == nullptr) {
427 LOGE("build generator fail.");
428 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build generator fail!"));
429 return nullptr;
430 }
431
432 HcfKeyPair *returnKeyPair = nullptr;
433 HcfResult errCode = generator->generateKeyPair(generator, &(returnKeyPair));
434 if (errCode != HCF_SUCCESS) {
435 LOGE("generate key pair fail.");
436 napi_throw(env, GenerateBusinessError(env, errCode, "generate key pair fail."));
437 return nullptr;
438 }
439
440 napi_value instance = nullptr;
441 NapiKeyPair *napiKeyPair = new (std::nothrow) NapiKeyPair(returnKeyPair);
442 if (napiKeyPair == nullptr) {
443 HcfObjDestroy(returnKeyPair);
444 returnKeyPair = nullptr;
445 LOGE("new napi key pair failed");
446 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi key pair failed!"));
447 return nullptr;
448 }
449
450 instance = napiKeyPair->ConvertToJsKeyPair(env);
451 napi_status ret = napi_wrap(
452 env, instance, napiKeyPair,
453 [](napi_env env, void *data, void *hint) {
454 NapiKeyPair *keyPair = static_cast<NapiKeyPair *>(data);
455 delete keyPair;
456 return;
457 }, nullptr, nullptr);
458 if (ret != napi_ok) {
459 LOGE("failed to wrap napiKeyPair obj!");
460 delete napiKeyPair;
461 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to wrap napiKeyPair obj!"));
462 return nullptr;
463 }
464 return instance;
465 }
466
JsGeneratePubKey(napi_env env,napi_callback_info info)467 napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePubKey(napi_env env, napi_callback_info info)
468 {
469 AsyKeyCtx *ctx = static_cast<AsyKeyCtx *>(HcfMalloc(sizeof(AsyKeyCtx), 0));
470 if (ctx == nullptr) {
471 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail!"));
472 LOGE("create context fail.");
473 return nullptr;
474 }
475
476 if (!BuildAsyKeyCtx(env, info, ctx)) {
477 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail!"));
478 LOGE("build context fail.");
479 FreeAsyKeyCtx(env, ctx);
480 return nullptr;
481 }
482
483 return NewPubKeyAsyncWork(env, ctx);
484 }
485
JsGeneratePubKeySync(napi_env env,napi_callback_info info)486 napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePubKeySync(napi_env env, napi_callback_info info)
487 {
488 HcfAsyKeyGeneratorBySpec *generator = nullptr;
489 if (!GetAsyKeyGenerator(env, info, &generator) || generator == nullptr) {
490 LOGE("build generator fail.");
491 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build generator fail!"));
492 return nullptr;
493 }
494
495 HcfPubKey *returnPubKey = nullptr;
496 HcfResult errCode = generator->generatePubKey(generator, &(returnPubKey));
497 if (errCode != HCF_SUCCESS) {
498 LOGE("generate PubKey fail.");
499 napi_throw(env, GenerateBusinessError(env, errCode, "generate PubKey fail."));
500 return nullptr;
501 }
502
503 napi_value instance = nullptr;
504 NapiPubKey *napiPubKey = new (std::nothrow) NapiPubKey(returnPubKey);
505 if (napiPubKey == nullptr) {
506 HcfObjDestroy(returnPubKey);
507 returnPubKey = nullptr;
508 LOGE("new napi pub key failed");
509 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi pub key failed!"));
510 return nullptr;
511 }
512
513 instance = napiPubKey->ConvertToJsPubKey(env);
514 napi_status ret = napi_wrap(
515 env, instance, napiPubKey,
516 [](napi_env env, void *data, void *hint) {
517 NapiPubKey *napiPubKey = static_cast<NapiPubKey *>(data);
518 HcfObjDestroy(napiPubKey->GetPubKey());
519 delete napiPubKey;
520 return;
521 }, nullptr, nullptr);
522 if (ret != napi_ok) {
523 LOGE("failed to wrap napiPubKey obj!");
524 HcfObjDestroy(napiPubKey->GetPubKey());
525 delete napiPubKey;
526 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "failed to wrap napiPubKey obj!"));
527 return nullptr;
528 }
529
530 return instance;
531 }
532
JsGeneratePriKey(napi_env env,napi_callback_info info)533 napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePriKey(napi_env env, napi_callback_info info)
534 {
535 AsyKeyCtx *ctx = static_cast<AsyKeyCtx *>(HcfMalloc(sizeof(AsyKeyCtx), 0));
536 if (ctx == nullptr) {
537 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail!"));
538 LOGE("create context fail.");
539 return nullptr;
540 }
541
542 if (!BuildAsyKeyCtx(env, info, ctx)) {
543 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail!"));
544 LOGE("build context fail.");
545 FreeAsyKeyCtx(env, ctx);
546 return nullptr;
547 }
548
549 return NewPriKeyAsyncWork(env, ctx);
550 }
551
JsGeneratePriKeySync(napi_env env,napi_callback_info info)552 napi_value NapiAsyKeyGeneratorBySpec::JsGeneratePriKeySync(napi_env env, napi_callback_info info)
553 {
554 HcfAsyKeyGeneratorBySpec *generator = nullptr;
555 if (!GetAsyKeyGenerator(env, info, &generator) || generator == nullptr) {
556 LOGE("build generator fail.");
557 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build generator fail!"));
558 return nullptr;
559 }
560
561 HcfPriKey *returnPriKey = nullptr;
562 HcfResult errCode = generator->generatePriKey(generator, &(returnPriKey));
563 if (errCode != HCF_SUCCESS) {
564 LOGE("generate PriKey fail.");
565 napi_throw(env, GenerateBusinessError(env, errCode, "generate PriKey fail."));
566 return nullptr;
567 }
568
569 napi_value instance = nullptr;
570 NapiPriKey *napiPriKey = new (std::nothrow) NapiPriKey(returnPriKey);
571 if (napiPriKey == nullptr) {
572 HcfObjDestroy(returnPriKey);
573 returnPriKey = nullptr;
574 LOGE("new napi pri key failed");
575 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi pri key failed!"));
576 return nullptr;
577 }
578
579 instance = napiPriKey->ConvertToJsPriKey(env);
580 napi_status ret = napi_wrap(
581 env, instance, napiPriKey,
582 [](napi_env env, void *data, void *hint) {
583 NapiPriKey *napiPriKey = static_cast<NapiPriKey *>(data);
584 HcfObjDestroy(napiPriKey->GetPriKey());
585 delete napiPriKey;
586 return;
587 }, nullptr, nullptr);
588 if (ret != napi_ok) {
589 LOGE("failed to wrap napiPriKey obj!");
590 HcfObjDestroy(napiPriKey->GetPriKey());
591 delete napiPriKey;
592 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "failed to wrap napiPriKey obj!"));
593 return nullptr;
594 }
595
596 return instance;
597 }
598
AsyKeyGeneratorBySpecConstructor(napi_env env,napi_callback_info info)599 napi_value NapiAsyKeyGeneratorBySpec::AsyKeyGeneratorBySpecConstructor(napi_env env, napi_callback_info info)
600 {
601 napi_value thisVar = nullptr;
602 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
603 return thisVar;
604 }
605
CreateJsAsyKeyGeneratorBySpec(napi_env env,napi_callback_info info)606 napi_value NapiAsyKeyGeneratorBySpec::CreateJsAsyKeyGeneratorBySpec(napi_env env, napi_callback_info info)
607 {
608 size_t argc = PARAMS_NUM_ONE;
609 napi_value argv[PARAMS_NUM_ONE] = { nullptr };
610 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
611
612 if (argc != PARAMS_NUM_ONE) {
613 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
614 LOGE("The input args num is invalid.");
615 return nullptr;
616 }
617
618 napi_value instance;
619 napi_value constructor = nullptr;
620 napi_get_reference_value(env, classRef_, &constructor);
621 napi_new_instance(env, constructor, argc, argv, &instance);
622
623 HcfAsyKeyParamsSpec *asyKeySpec = nullptr;
624 if (!GetAsyKeySpecFromNapiValue(env, argv[0], &asyKeySpec)) {
625 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get valid asyKeySpec!"));
626 LOGE("GetAsyKeySpecFromNapiValue failed!");
627 return nullptr;
628 }
629 HcfAsyKeyGeneratorBySpec *generator = nullptr;
630 HcfResult res = HcfAsyKeyGeneratorBySpecCreate(asyKeySpec, &generator);
631 FreeAsyKeySpec(asyKeySpec);
632 asyKeySpec = nullptr;
633 if (res != HCF_SUCCESS) {
634 napi_throw(env, GenerateBusinessError(env, res, "create C generator by sepc fail."));
635 LOGE("create C generator by spec fail.");
636 return nullptr;
637 }
638
639 NapiAsyKeyGeneratorBySpec *napiAsyKeyGeneratorBySpec = new (std::nothrow) NapiAsyKeyGeneratorBySpec(generator);
640 if (napiAsyKeyGeneratorBySpec == nullptr) {
641 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi asy key generator by spec failed!"));
642 LOGE("new napi asy key generator by spec failed!");
643 HcfObjDestroy(generator);
644 generator = nullptr;
645 return nullptr;
646 }
647
648 napi_status status = napi_wrap(env, instance, napiAsyKeyGeneratorBySpec,
649 [](napi_env env, void *data, void *hint) {
650 NapiAsyKeyGeneratorBySpec *napiAsyKeyGeneratorBySpec = static_cast<NapiAsyKeyGeneratorBySpec *>(data);
651 delete napiAsyKeyGeneratorBySpec;
652 return;
653 }, nullptr, nullptr);
654 if (status != napi_ok) {
655 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "wrap napiAsyKeyGeneratorBySpec failed!"));
656 LOGE("failed to wrap napiAsyKeyGeneratorBySpec obj!");
657 delete napiAsyKeyGeneratorBySpec;
658 return nullptr;
659 }
660 return instance;
661 }
662
JsGetAlgorithm(napi_env env,napi_callback_info info)663 napi_value NapiAsyKeyGeneratorBySpec::JsGetAlgorithm(napi_env env, napi_callback_info info)
664 {
665 napi_value thisVar = nullptr;
666 NapiAsyKeyGeneratorBySpec *napiAsyKeyGeneratorBySpec = nullptr;
667 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
668 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiAsyKeyGeneratorBySpec));
669 if (status != napi_ok || napiAsyKeyGeneratorBySpec == nullptr) {
670 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napi asyKeyGenerator obj."));
671 LOGE("failed to unwrap napi asyKeyGenerator obj.");
672 return nullptr;
673 }
674 HcfAsyKeyGeneratorBySpec *generator = napiAsyKeyGeneratorBySpec->GetAsyKeyGeneratorBySpec();
675 if (generator == nullptr) {
676 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get generator by spec obj!"));
677 LOGE("fail to get generator by spec obj!");
678 return nullptr;
679 }
680
681 const char *algo = generator->getAlgName(generator);
682 napi_value instance = nullptr;
683 napi_create_string_utf8(env, algo, NAPI_AUTO_LENGTH, &instance);
684 return instance;
685 }
686
DefineAsyKeyGeneratorBySpecJSClass(napi_env env,napi_value exports)687 void NapiAsyKeyGeneratorBySpec::DefineAsyKeyGeneratorBySpecJSClass(napi_env env, napi_value exports)
688 {
689 napi_property_descriptor desc[] = {
690 DECLARE_NAPI_FUNCTION("createAsyKeyGeneratorBySpec", NapiAsyKeyGeneratorBySpec::CreateJsAsyKeyGeneratorBySpec),
691 };
692 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
693
694 napi_property_descriptor classDesc[] = {
695 DECLARE_NAPI_FUNCTION("generateKeyPair", NapiAsyKeyGeneratorBySpec::JsGenerateKeyPair),
696 DECLARE_NAPI_FUNCTION("generateKeyPairSync", NapiAsyKeyGeneratorBySpec::JsGenerateKeyPairSync),
697 DECLARE_NAPI_FUNCTION("generatePriKey", NapiAsyKeyGeneratorBySpec::JsGeneratePriKey),
698 DECLARE_NAPI_FUNCTION("generatePriKeySync", NapiAsyKeyGeneratorBySpec::JsGeneratePriKeySync),
699 DECLARE_NAPI_FUNCTION("generatePubKey", NapiAsyKeyGeneratorBySpec::JsGeneratePubKey),
700 DECLARE_NAPI_FUNCTION("generatePubKeySync", NapiAsyKeyGeneratorBySpec::JsGeneratePubKeySync),
701 { .utf8name = "algName", .getter = NapiAsyKeyGeneratorBySpec::JsGetAlgorithm },
702 };
703 napi_value constructor = nullptr;
704 napi_define_class(env, "AsyKeyGeneratorBySpec", NAPI_AUTO_LENGTH,
705 NapiAsyKeyGeneratorBySpec::AsyKeyGeneratorBySpecConstructor,
706 nullptr, sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor);
707 napi_create_reference(env, constructor, 1, &classRef_);
708 }
709 } // CryptoFramework
710 } // OHOS
711