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