1 /*
2 * Copyright (C) 2022 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_sign.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_pri_key.h"
24 #include "napi_pub_key.h"
25 #include "napi_utils.h"
26
27 namespace OHOS {
28 namespace CryptoFramework {
29 struct SignInitCtx {
30 napi_env env = nullptr;
31
32 AsyncType asyncType = ASYNC_CALLBACK;
33 napi_ref callback = nullptr;
34 napi_deferred deferred = nullptr;
35 napi_value promise = nullptr;
36 napi_async_work asyncWork = nullptr;
37
38 HcfSign *sign;
39 HcfParamsSpec *params;
40 HcfPriKey *priKey;
41
42 HcfResult result;
43 };
44
45 struct SignUpdateCtx {
46 napi_env env = nullptr;
47
48 AsyncType asyncType = ASYNC_CALLBACK;
49 napi_ref callback = nullptr;
50 napi_deferred deferred = nullptr;
51 napi_value promise = nullptr;
52 napi_async_work asyncWork = nullptr;
53
54 HcfSign *sign;
55 HcfBlob *data;
56
57 HcfResult result;
58 };
59
60 struct SignDoFinalCtx {
61 napi_env env = nullptr;
62
63 AsyncType asyncType = ASYNC_CALLBACK;
64 napi_ref callback = nullptr;
65 napi_deferred deferred = nullptr;
66 napi_value promise = nullptr;
67 napi_async_work asyncWork = nullptr;
68
69 HcfSign *sign;
70 HcfBlob *data;
71
72 HcfResult result;
73 HcfBlob returnSignatureData;
74 };
75
76 thread_local napi_ref NapiSign::classRef_ = nullptr;
77
FreeSignInitCtx(napi_env env,SignInitCtx * ctx)78 static void FreeSignInitCtx(napi_env env, SignInitCtx *ctx)
79 {
80 if (ctx == nullptr) {
81 return;
82 }
83
84 if (ctx->asyncWork != nullptr) {
85 napi_delete_async_work(env, ctx->asyncWork);
86 }
87
88 if (ctx->callback != nullptr) {
89 napi_delete_reference(env, ctx->callback);
90 }
91
92 HcfFree(ctx);
93 }
94
FreeSignUpdateCtx(napi_env env,SignUpdateCtx * ctx)95 static void FreeSignUpdateCtx(napi_env env, SignUpdateCtx *ctx)
96 {
97 if (ctx == nullptr) {
98 return;
99 }
100
101 if (ctx->asyncWork != nullptr) {
102 napi_delete_async_work(env, ctx->asyncWork);
103 }
104
105 if (ctx->callback != nullptr) {
106 napi_delete_reference(env, ctx->callback);
107 }
108
109 HcfBlobDataFree(ctx->data);
110 HcfFree(ctx->data);
111 HcfFree(ctx);
112 }
113
FreeSignDoFinalCtx(napi_env env,SignDoFinalCtx * ctx)114 static void FreeSignDoFinalCtx(napi_env env, SignDoFinalCtx *ctx)
115 {
116 if (ctx == nullptr) {
117 return;
118 }
119
120 if (ctx->asyncWork != nullptr) {
121 napi_delete_async_work(env, ctx->asyncWork);
122 ctx->asyncWork = nullptr;
123 }
124
125 if (ctx->callback != nullptr) {
126 napi_delete_reference(env, ctx->callback);
127 ctx->callback = nullptr;
128 }
129
130 if (ctx->returnSignatureData.data != nullptr) {
131 HcfFree(ctx->returnSignatureData.data);
132 ctx->returnSignatureData.data = nullptr;
133 ctx->returnSignatureData.len = 0;
134 }
135
136 HcfBlobDataFree(ctx->data);
137 HcfFree(ctx->data);
138 HcfFree(ctx);
139 }
140
BuildSignJsInitCtx(napi_env env,napi_callback_info info,SignInitCtx * ctx)141 static bool BuildSignJsInitCtx(napi_env env, napi_callback_info info, SignInitCtx *ctx)
142 {
143 napi_value thisVar = nullptr;
144 size_t expectedArgc = PARAMS_NUM_TWO;
145 size_t argc = expectedArgc;
146 napi_value argv[PARAMS_NUM_TWO] = { nullptr, nullptr };
147 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
148 if (argc != expectedArgc && argc != expectedArgc - 1) {
149 LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc);
150 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.", false));
151 return false;
152 }
153 ctx->asyncType = (argc == expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
154
155 NapiSign *napiSign = nullptr;
156 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiSign));
157 if (status != napi_ok) {
158 LOGE("failed to unwrap napi sign obj.");
159 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.", false));
160 return false;
161 }
162
163 size_t index = 0;
164 NapiPriKey *napiPriKey = nullptr;
165 status = napi_unwrap(env, argv[index], reinterpret_cast<void **>(&napiPriKey));
166 if (status != napi_ok) {
167 LOGE("failed to unwrap napi priKey obj.");
168 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[PriKey]: param unwarp error.", false));
169 return false;
170 }
171
172 ctx->sign = napiSign->GetSign();
173 ctx->params = nullptr;
174 ctx->priKey = napiPriKey->GetPriKey();
175
176 if (ctx->asyncType == ASYNC_PROMISE) {
177 napi_create_promise(env, &ctx->deferred, &ctx->promise);
178 return true;
179 } else {
180 return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback, false);
181 }
182 }
183
BuildSignJsUpdateCtx(napi_env env,napi_callback_info info,SignUpdateCtx * ctx)184 static bool BuildSignJsUpdateCtx(napi_env env, napi_callback_info info, SignUpdateCtx *ctx)
185 {
186 napi_value thisVar = nullptr;
187 size_t expectedArgc = PARAMS_NUM_TWO;
188 size_t argc = expectedArgc;
189 napi_value argv[PARAMS_NUM_TWO] = { nullptr, nullptr };
190 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
191 if ((argc != expectedArgc) && (argc != expectedArgc - 1)) {
192 LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc);
193 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.", false));
194 return false;
195 }
196 ctx->asyncType = (argc == PARAMS_NUM_TWO) ? ASYNC_CALLBACK : ASYNC_PROMISE;
197
198 NapiSign *napiSign = nullptr;
199 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiSign));
200 if (status != napi_ok) {
201 LOGE("failed to unwrap napi sign obj.");
202 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.", false));
203 return false;
204 }
205
206 size_t index = 0;
207 HcfBlob *blob = GetBlobFromNapiValue(env, argv[index]);
208 if (blob == nullptr) {
209 LOGE("failed to get data.");
210 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS,
211 "[Data]: must be of the DataBlob type.", false));
212 return false;
213 }
214
215 ctx->sign = napiSign->GetSign();
216 ctx->data = blob;
217
218 if (ctx->asyncType == ASYNC_PROMISE) {
219 napi_create_promise(env, &ctx->deferred, &ctx->promise);
220 return true;
221 } else {
222 return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback, false);
223 }
224 }
225
BuildSignJsDoFinalCtx(napi_env env,napi_callback_info info,SignDoFinalCtx * ctx)226 static bool BuildSignJsDoFinalCtx(napi_env env, napi_callback_info info, SignDoFinalCtx *ctx)
227 {
228 napi_value thisVar = nullptr;
229 size_t expectedArgc = PARAMS_NUM_TWO;
230 size_t argc = expectedArgc;
231 napi_value argv[PARAMS_NUM_TWO] = { nullptr, nullptr };
232 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
233 if ((argc != expectedArgc) && (argc != expectedArgc - 1)) {
234 LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc);
235 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "params num error.", false));
236 return false;
237 }
238 ctx->asyncType = (argc == PARAMS_NUM_TWO) ? ASYNC_CALLBACK : ASYNC_PROMISE;
239
240 NapiSign *napiSign = nullptr;
241 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiSign));
242 if (status != napi_ok) {
243 LOGE("failed to unwrap napi sign obj.");
244 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "[Self]: param unwarp error.", false));
245 return false;
246 }
247
248 size_t index = 0;
249 napi_valuetype valueType;
250 napi_typeof(env, argv[index], &valueType);
251 HcfBlob *data = nullptr;
252 if (valueType != napi_null) {
253 data = GetBlobFromNapiValue(env, argv[index]);
254 if (data == nullptr) {
255 LOGE("failed to get data.");
256 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS,
257 "[Data]: must be of the DataBlob type.", false));
258 return false;
259 }
260 }
261
262 ctx->sign = napiSign->GetSign();
263 ctx->data = data;
264
265 if (ctx->asyncType == ASYNC_PROMISE) {
266 napi_create_promise(env, &ctx->deferred, &ctx->promise);
267 return true;
268 } else {
269 return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback, false);
270 }
271 }
272
ReturnInitCallbackResult(napi_env env,SignInitCtx * ctx,napi_value result)273 static void ReturnInitCallbackResult(napi_env env, SignInitCtx *ctx, napi_value result)
274 {
275 napi_value businessError = nullptr;
276 if (ctx->result != HCF_SUCCESS) {
277 businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str(), false);
278 }
279
280 napi_value params[ARGS_SIZE_ONE] = { businessError };
281
282 napi_value func = nullptr;
283 napi_get_reference_value(env, ctx->callback, &func);
284
285 napi_value recv = nullptr;
286 napi_value callFuncRet = nullptr;
287 napi_get_undefined(env, &recv);
288 napi_call_function(env, recv, func, ARGS_SIZE_ONE, params, &callFuncRet);
289 }
290
ReturnInitPromiseResult(napi_env env,SignInitCtx * ctx,napi_value result)291 static void ReturnInitPromiseResult(napi_env env, SignInitCtx *ctx, napi_value result)
292 {
293 if (ctx->result == HCF_SUCCESS) {
294 napi_resolve_deferred(env, ctx->deferred, result);
295 } else {
296 napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->result,
297 COMMON_ERR_MSG.c_str(), false));
298 }
299 }
300
ReturnUpdateCallbackResult(napi_env env,SignUpdateCtx * ctx,napi_value result)301 static void ReturnUpdateCallbackResult(napi_env env, SignUpdateCtx *ctx, napi_value result)
302 {
303 napi_value businessError = nullptr;
304 if (ctx->result != HCF_SUCCESS) {
305 businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str(), false);
306 }
307
308 napi_value params[ARGS_SIZE_ONE] = { businessError };
309
310 napi_value func = nullptr;
311 napi_get_reference_value(env, ctx->callback, &func);
312
313 napi_value recv = nullptr;
314 napi_value callFuncRet = nullptr;
315 napi_get_undefined(env, &recv);
316 napi_call_function(env, recv, func, ARGS_SIZE_ONE, params, &callFuncRet);
317 }
318
ReturnUpdatePromiseResult(napi_env env,SignUpdateCtx * ctx,napi_value result)319 static void ReturnUpdatePromiseResult(napi_env env, SignUpdateCtx *ctx, napi_value result)
320 {
321 if (ctx->result == HCF_SUCCESS) {
322 napi_resolve_deferred(env, ctx->deferred, result);
323 } else {
324 napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->result,
325 COMMON_ERR_MSG.c_str(), false));
326 }
327 }
328
ReturnDoFinalCallbackResult(napi_env env,SignDoFinalCtx * ctx,napi_value result)329 static void ReturnDoFinalCallbackResult(napi_env env, SignDoFinalCtx *ctx, napi_value result)
330 {
331 napi_value businessError = nullptr;
332 if (ctx->result != HCF_SUCCESS) {
333 businessError = GenerateBusinessError(env, ctx->result, COMMON_ERR_MSG.c_str(), false);
334 }
335
336 napi_value params[ARGS_SIZE_TWO] = { businessError, result };
337
338 napi_value func = nullptr;
339 napi_get_reference_value(env, ctx->callback, &func);
340
341 napi_value recv = nullptr;
342 napi_value callFuncRet = nullptr;
343 napi_get_undefined(env, &recv);
344 napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
345 }
346
ReturnDoFinalPromiseResult(napi_env env,SignDoFinalCtx * ctx,napi_value result)347 static void ReturnDoFinalPromiseResult(napi_env env, SignDoFinalCtx *ctx, napi_value result)
348 {
349 if (ctx->result == HCF_SUCCESS) {
350 napi_resolve_deferred(env, ctx->deferred, result);
351 } else {
352 napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->result,
353 COMMON_ERR_MSG.c_str(), false));
354 }
355 }
356
SignJsInitAsyncWorkProcess(napi_env env,void * data)357 void SignJsInitAsyncWorkProcess(napi_env env, void *data)
358 {
359 SignInitCtx *ctx = static_cast<SignInitCtx *>(data);
360
361 HcfResult res = ctx->sign->init(ctx->sign, ctx->params, ctx->priKey);
362
363 ctx->result = res;
364 if (res != HCF_SUCCESS) {
365 LOGE("sign init fail.");
366 }
367 }
368
SignJsInitAsyncWorkReturn(napi_env env,napi_status status,void * data)369 void SignJsInitAsyncWorkReturn(napi_env env, napi_status status, void *data)
370 {
371 SignInitCtx *ctx = static_cast<SignInitCtx *>(data);
372
373 if (ctx->asyncType == ASYNC_CALLBACK) {
374 ReturnInitCallbackResult(env, ctx, NapiGetNull(env));
375 } else {
376 ReturnInitPromiseResult(env, ctx, NapiGetNull(env));
377 }
378 FreeSignInitCtx(env, ctx);
379 }
380
SignJsUpdateAsyncWorkProcess(napi_env env,void * data)381 void SignJsUpdateAsyncWorkProcess(napi_env env, void *data)
382 {
383 SignUpdateCtx *ctx = static_cast<SignUpdateCtx *>(data);
384
385 HcfResult res = ctx->sign->update(ctx->sign, ctx->data);
386
387 ctx->result = res;
388 if (res != HCF_SUCCESS) {
389 LOGE("sign update fail.");
390 }
391 }
392
SignJsUpdateAsyncWorkReturn(napi_env env,napi_status status,void * data)393 void SignJsUpdateAsyncWorkReturn(napi_env env, napi_status status, void *data)
394 {
395 SignUpdateCtx *ctx = static_cast<SignUpdateCtx *>(data);
396
397 if (ctx->asyncType == ASYNC_CALLBACK) {
398 ReturnUpdateCallbackResult(env, ctx, NapiGetNull(env));
399 } else {
400 ReturnUpdatePromiseResult(env, ctx, NapiGetNull(env));
401 }
402 FreeSignUpdateCtx(env, ctx);
403 }
404
SignJsDoFinalAsyncWorkProcess(napi_env env,void * data)405 void SignJsDoFinalAsyncWorkProcess(napi_env env, void *data)
406 {
407 SignDoFinalCtx *ctx = static_cast<SignDoFinalCtx *>(data);
408
409 HcfResult res = ctx->sign->sign(ctx->sign, ctx->data, &ctx->returnSignatureData);
410
411 ctx->result = res;
412 if (res != HCF_SUCCESS) {
413 LOGE("sign doFinal fail.");
414 }
415 }
416
SignJsDoFinalAsyncWorkReturn(napi_env env,napi_status status,void * data)417 void SignJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, void *data)
418 {
419 SignDoFinalCtx *ctx = static_cast<SignDoFinalCtx *>(data);
420
421 napi_value dataBlob = nullptr;
422 if (ctx->result == HCF_SUCCESS) {
423 dataBlob = ConvertBlobToNapiValue(env, &ctx->returnSignatureData);
424 }
425
426 if (ctx->asyncType == ASYNC_CALLBACK) {
427 ReturnDoFinalCallbackResult(env, ctx, dataBlob);
428 } else {
429 ReturnDoFinalPromiseResult(env, ctx, dataBlob);
430 }
431 FreeSignDoFinalCtx(env, ctx);
432 }
433
NewSignJsInitAsyncWork(napi_env env,SignInitCtx * ctx)434 static napi_value NewSignJsInitAsyncWork(napi_env env, SignInitCtx *ctx)
435 {
436 napi_value resourceName = nullptr;
437 napi_create_string_utf8(env, "init", NAPI_AUTO_LENGTH, &resourceName);
438
439 napi_create_async_work(
440 env, nullptr, resourceName,
441 [](napi_env env, void *data) {
442 SignJsInitAsyncWorkProcess(env, data);
443 return;
444 },
445 [](napi_env env, napi_status status, void *data) {
446 SignJsInitAsyncWorkReturn(env, status, data);
447 return;
448 },
449 static_cast<void *>(ctx),
450 &ctx->asyncWork);
451
452 napi_queue_async_work(env, ctx->asyncWork);
453 if (ctx->asyncType == ASYNC_PROMISE) {
454 return ctx->promise;
455 } else {
456 napi_value result = nullptr;
457 napi_get_null(env, &result);
458 return result;
459 }
460 }
461
NewSignJsUpdateAsyncWork(napi_env env,SignUpdateCtx * ctx)462 static napi_value NewSignJsUpdateAsyncWork(napi_env env, SignUpdateCtx *ctx)
463 {
464 napi_value resourceName = nullptr;
465 napi_create_string_utf8(env, "update", NAPI_AUTO_LENGTH, &resourceName);
466
467 napi_create_async_work(
468 env, nullptr, resourceName,
469 [](napi_env env, void *data) {
470 SignJsUpdateAsyncWorkProcess(env, data);
471 return;
472 },
473 [](napi_env env, napi_status status, void *data) {
474 SignJsUpdateAsyncWorkReturn(env, status, data);
475 return;
476 },
477 static_cast<void *>(ctx),
478 &ctx->asyncWork);
479
480 napi_queue_async_work(env, ctx->asyncWork);
481 if (ctx->asyncType == ASYNC_PROMISE) {
482 return ctx->promise;
483 } else {
484 napi_value result = nullptr;
485 napi_get_null(env, &result);
486 return result;
487 }
488 }
489
NewSignJsDoFinalAsyncWork(napi_env env,SignDoFinalCtx * ctx)490 static napi_value NewSignJsDoFinalAsyncWork(napi_env env, SignDoFinalCtx *ctx)
491 {
492 napi_value resourceName = nullptr;
493 napi_create_string_utf8(env, "sign", NAPI_AUTO_LENGTH, &resourceName);
494
495 napi_create_async_work(
496 env, nullptr, resourceName,
497 [](napi_env env, void *data) {
498 SignJsDoFinalAsyncWorkProcess(env, data);
499 return;
500 },
501 [](napi_env env, napi_status status, void *data) {
502 SignJsDoFinalAsyncWorkReturn(env, status, data);
503 return;
504 },
505 static_cast<void *>(ctx),
506 &ctx->asyncWork);
507
508 napi_queue_async_work(env, ctx->asyncWork);
509 if (ctx->asyncType == ASYNC_PROMISE) {
510 return ctx->promise;
511 } else {
512 napi_value result = nullptr;
513 napi_get_null(env, &result);
514 return result;
515 }
516 }
517
NapiSign(HcfSign * sign)518 NapiSign::NapiSign(HcfSign *sign)
519 {
520 this->sign_ = sign;
521 }
522
~NapiSign()523 NapiSign::~NapiSign()
524 {
525 HcfObjDestroy(this->sign_);
526 }
527
GetSign()528 HcfSign *NapiSign::GetSign()
529 {
530 return this->sign_;
531 }
532
JsInit(napi_env env,napi_callback_info info)533 napi_value NapiSign::JsInit(napi_env env, napi_callback_info info)
534 {
535 LOGI("enter ...");
536 SignInitCtx *ctx = static_cast<SignInitCtx *>(HcfMalloc(sizeof(SignInitCtx), 0));
537 if (ctx == nullptr) {
538 LOGE("create context fail.");
539 return nullptr;
540 }
541
542 if (!BuildSignJsInitCtx(env, info, ctx)) {
543 LOGE("build context fail.");
544 FreeSignInitCtx(env, ctx);
545 return nullptr;
546 }
547
548 return NewSignJsInitAsyncWork(env, ctx);
549 }
550
JsUpdate(napi_env env,napi_callback_info info)551 napi_value NapiSign::JsUpdate(napi_env env, napi_callback_info info)
552 {
553 LOGI("enter ...");
554 SignUpdateCtx *ctx = static_cast<SignUpdateCtx *>(HcfMalloc(sizeof(SignUpdateCtx), 0));
555 if (ctx == nullptr) {
556 LOGE("create context fail.");
557 return nullptr;
558 }
559
560 if (!BuildSignJsUpdateCtx(env, info, ctx)) {
561 LOGE("build context fail.");
562 FreeSignUpdateCtx(env, ctx);
563 return nullptr;
564 }
565
566 return NewSignJsUpdateAsyncWork(env, ctx);
567 }
568
JsSign(napi_env env,napi_callback_info info)569 napi_value NapiSign::JsSign(napi_env env, napi_callback_info info)
570 {
571 LOGI("enter ...");
572 SignDoFinalCtx *ctx = static_cast<SignDoFinalCtx *>(HcfMalloc(sizeof(SignDoFinalCtx), 0));
573 if (ctx == nullptr) {
574 LOGE("create context fail.");
575 return nullptr;
576 }
577
578 if (!BuildSignJsDoFinalCtx(env, info, ctx)) {
579 LOGE("build context fail.");
580 FreeSignDoFinalCtx(env, ctx);
581 return nullptr;
582 }
583
584 return NewSignJsDoFinalAsyncWork(env, ctx);
585 }
586
SignConstructor(napi_env env,napi_callback_info info)587 napi_value NapiSign::SignConstructor(napi_env env, napi_callback_info info)
588 {
589 LOGI("enter ...");
590
591 napi_value thisVar = nullptr;
592 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
593
594 LOGI("out ...");
595 return thisVar;
596 }
597
CreateJsSign(napi_env env,napi_callback_info info)598 napi_value NapiSign::CreateJsSign(napi_env env, napi_callback_info info)
599 {
600 LOGI("enter ...");
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 LOGE("The input args num is invalid.");
608 return nullptr;
609 }
610
611 napi_value instance;
612 napi_value constructor = nullptr;
613 napi_get_reference_value(env, classRef_, &constructor);
614 napi_new_instance(env, constructor, argc, argv, &instance);
615
616 std::string algName;
617 if (!GetStringFromJSParams(env, argv[0], algName, false)) {
618 return nullptr;
619 }
620
621 HcfSign *sign = nullptr;
622 int32_t res = HcfSignCreate(algName.c_str(), &sign);
623 if (res != HCF_SUCCESS) {
624 LOGE("create c sign fail.");
625 return nullptr;
626 }
627
628 NapiSign *napiSign = new NapiSign(sign);
629
630 napi_wrap(
631 env, instance, napiSign,
632 [](napi_env env, void *data, void *hint) {
633 NapiSign *napiSign = static_cast<NapiSign *>(data);
634 delete napiSign;
635 return;
636 },
637 nullptr,
638 nullptr);
639
640 napi_value napiAlgName = nullptr;
641 napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName);
642 napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName);
643
644 LOGI("out ...");
645 return instance;
646 }
647
DefineSignJSClass(napi_env env,napi_value exports)648 void NapiSign::DefineSignJSClass(napi_env env, napi_value exports)
649 {
650 napi_property_descriptor desc[] = {
651 DECLARE_NAPI_FUNCTION("createSign", NapiSign::CreateJsSign),
652 };
653 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
654
655 napi_property_descriptor classDesc[] = {
656 DECLARE_NAPI_FUNCTION("init", NapiSign::JsInit),
657 DECLARE_NAPI_FUNCTION("update", NapiSign::JsUpdate),
658 DECLARE_NAPI_FUNCTION("sign", NapiSign::JsSign),
659 };
660 napi_value constructor = nullptr;
661 napi_define_class(env, "Sign", NAPI_AUTO_LENGTH, NapiSign::SignConstructor, nullptr,
662 sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor);
663 napi_create_reference(env, constructor, 1, &classRef_);
664 }
665 } // CryptoFramework
666 } // OHOS
667