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