• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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