• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_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     napi_ref verifyRef = nullptr;
38     napi_ref pubKeyRef = nullptr;
39 
40     HcfVerify *verify = nullptr;
41     HcfParamsSpec *params = nullptr;
42     HcfPubKey *pubKey = nullptr;
43 
44     HcfResult errCode = HCF_SUCCESS;
45     const char *errMsg = nullptr;
46 };
47 
48 struct VerifyUpdateCtx {
49     napi_env env = nullptr;
50 
51     AsyncType asyncType = ASYNC_CALLBACK;
52     napi_ref callback = nullptr;
53     napi_deferred deferred = nullptr;
54     napi_value promise = nullptr;
55     napi_async_work asyncWork = nullptr;
56     napi_ref verifyRef = nullptr;
57 
58     HcfVerify *verify = nullptr;
59     HcfBlob *data = nullptr;
60 
61     HcfResult errCode = HCF_SUCCESS;
62     const char *errMsg = nullptr;
63 };
64 
65 struct VerifyDoFinalCtx {
66     napi_env env = nullptr;
67 
68     AsyncType asyncType = ASYNC_CALLBACK;
69     napi_ref callback = nullptr;
70     napi_deferred deferred = nullptr;
71     napi_value promise = nullptr;
72     napi_async_work asyncWork = nullptr;
73     napi_ref verifyRef = nullptr;
74 
75     HcfVerify *verify = nullptr;
76     HcfBlob *data = nullptr;
77     HcfBlob *signatureData = nullptr;
78 
79     HcfResult errCode = HCF_SUCCESS;
80     const char *errMsg = nullptr;
81     bool isVerifySucc;
82 };
83 
84 struct VerifyRecoverCtx {
85     napi_env env = nullptr;
86 
87     napi_deferred deferred = nullptr;
88     napi_value promise = nullptr;
89     napi_async_work asyncWork = nullptr;
90     napi_ref verifyRef = nullptr;
91 
92     HcfVerify *verify = nullptr;
93     HcfBlob *signatureData = nullptr;
94 
95     HcfResult errCode = HCF_SUCCESS;
96     const char *errMsg = nullptr;
97     HcfBlob rawSignatureData;
98 };
99 
100 thread_local napi_ref NapiVerify::classRef_ = nullptr;
101 
FreeVerifyInitCtx(napi_env env,VerifyInitCtx * ctx)102 static void FreeVerifyInitCtx(napi_env env, VerifyInitCtx *ctx)
103 {
104     if (ctx == nullptr) {
105         return;
106     }
107 
108     if (ctx->asyncWork != nullptr) {
109         napi_delete_async_work(env, ctx->asyncWork);
110         ctx->asyncWork = nullptr;
111     }
112 
113     if (ctx->callback != nullptr) {
114         napi_delete_reference(env, ctx->callback);
115         ctx->callback = nullptr;
116     }
117 
118     if (ctx->verifyRef != nullptr) {
119         napi_delete_reference(env, ctx->verifyRef);
120         ctx->verifyRef = nullptr;
121     }
122 
123     if (ctx->pubKeyRef != nullptr) {
124         napi_delete_reference(env, ctx->pubKeyRef);
125         ctx->pubKeyRef = nullptr;
126     }
127 
128     HcfFree(ctx);
129 }
130 
FreeVerifyUpdateCtx(napi_env env,VerifyUpdateCtx * ctx)131 static void FreeVerifyUpdateCtx(napi_env env, VerifyUpdateCtx *ctx)
132 {
133     if (ctx == nullptr) {
134         return;
135     }
136 
137     if (ctx->asyncWork != nullptr) {
138         napi_delete_async_work(env, ctx->asyncWork);
139         ctx->asyncWork = nullptr;
140     }
141 
142     if (ctx->callback != nullptr) {
143         napi_delete_reference(env, ctx->callback);
144         ctx->callback = nullptr;
145     }
146 
147     if (ctx->verifyRef != nullptr) {
148         napi_delete_reference(env, ctx->verifyRef);
149         ctx->verifyRef = nullptr;
150     }
151 
152     HcfBlobDataFree(ctx->data);
153     HcfFree(ctx->data);
154     ctx->data = nullptr;
155     HcfFree(ctx);
156 }
157 
FreeVerifyDoFinalCtx(napi_env env,VerifyDoFinalCtx * ctx)158 static void FreeVerifyDoFinalCtx(napi_env env, VerifyDoFinalCtx *ctx)
159 {
160     if (ctx == nullptr) {
161         return;
162     }
163 
164     if (ctx->asyncWork != nullptr) {
165         napi_delete_async_work(env, ctx->asyncWork);
166         ctx->asyncWork = nullptr;
167     }
168 
169     if (ctx->callback != nullptr) {
170         napi_delete_reference(env, ctx->callback);
171         ctx->callback = nullptr;
172     }
173 
174     if (ctx->verifyRef != nullptr) {
175         napi_delete_reference(env, ctx->verifyRef);
176         ctx->verifyRef = nullptr;
177     }
178 
179     HcfBlobDataFree(ctx->data);
180     HcfFree(ctx->data);
181     ctx->data = nullptr;
182     HcfBlobDataFree(ctx->signatureData);
183     HcfFree(ctx->signatureData);
184     ctx->signatureData = nullptr;
185     HcfFree(ctx);
186 }
187 
FreeVerifyRecoverCtx(napi_env env,VerifyRecoverCtx * ctx)188 static void FreeVerifyRecoverCtx(napi_env env, VerifyRecoverCtx *ctx)
189 {
190     if (ctx == nullptr) {
191         return;
192     }
193 
194     if (ctx->asyncWork != nullptr) {
195         napi_delete_async_work(env, ctx->asyncWork);
196         ctx->asyncWork = nullptr;
197     }
198 
199     if (ctx->verifyRef != nullptr) {
200         napi_delete_reference(env, ctx->verifyRef);
201         ctx->verifyRef = nullptr;
202     }
203 
204     if (ctx->rawSignatureData.data != nullptr) {
205         HcfFree(ctx->rawSignatureData.data);
206         ctx->rawSignatureData.data = nullptr;
207         ctx->rawSignatureData.len = 0;
208     }
209 
210     HcfBlobDataFree(ctx->signatureData);
211     HcfFree(ctx->signatureData);
212     ctx->signatureData = nullptr;
213     HcfFree(ctx);
214 }
215 
BuildVerifyJsInitCtx(napi_env env,napi_callback_info info,VerifyInitCtx * ctx)216 static bool BuildVerifyJsInitCtx(napi_env env, napi_callback_info info, VerifyInitCtx *ctx)
217 {
218     napi_value thisVar = nullptr;
219     size_t expectedArgc = PARAMS_NUM_TWO;
220     size_t argc = expectedArgc;
221     napi_value argv[PARAMS_NUM_TWO] = { nullptr };
222     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
223     if ((argc != expectedArgc) && (argc != expectedArgc - 1)) {
224         LOGE("wrong argument num. require %{public}zu or %{public}zu arguments. [Argc]: %{public}zu!",
225             expectedArgc - 1, expectedArgc, argc);
226         return false;
227     }
228     ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
229 
230     NapiVerify *napiVerify = nullptr;
231     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
232     if (status != napi_ok || napiVerify == nullptr) {
233         LOGE("failed to unwrap napi verify obj.");
234         return false;
235     }
236 
237     size_t index = 0;
238     NapiPubKey *napiPubKey = nullptr;
239     status = napi_unwrap(env, argv[index], reinterpret_cast<void **>(&napiPubKey));
240     if (status != napi_ok || napiPubKey == nullptr) {
241         LOGE("failed to unwrap napi pubKey obj.");
242         return false;
243     }
244 
245     ctx->verify = napiVerify->GetVerify();
246     ctx->params = nullptr;
247     ctx->pubKey = napiPubKey->GetPubKey();
248 
249     if (napi_create_reference(env, thisVar, 1, &ctx->verifyRef) != napi_ok) {
250         LOGE("create verify ref failed when do verify init!");
251         return false;
252     }
253 
254     if (napi_create_reference(env, argv[PARAM0], 1, &ctx->pubKeyRef) != napi_ok) {
255         LOGE("create verify ref failed when do verify init!");
256         return false;
257     }
258 
259     if (ctx->asyncType == ASYNC_PROMISE) {
260         napi_create_promise(env, &ctx->deferred, &ctx->promise);
261         return true;
262     } else {
263         return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback);
264     }
265 }
266 
BuildVerifyJsUpdateCtx(napi_env env,napi_callback_info info,VerifyUpdateCtx * ctx)267 static bool BuildVerifyJsUpdateCtx(napi_env env, napi_callback_info info, VerifyUpdateCtx *ctx)
268 {
269     napi_value thisVar = nullptr;
270     size_t expectedArgc = PARAMS_NUM_TWO;
271     size_t argc = expectedArgc;
272     napi_value argv[PARAMS_NUM_TWO] = { nullptr };
273     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
274     if ((argc != expectedArgc) && (argc != expectedArgc - 1)) {
275         LOGE("wrong argument num. require %{public}zu or %{public}zu arguments. [Argc]: %{public}zu!",
276             expectedArgc - 1, expectedArgc, argc);
277         return false;
278     }
279     ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
280 
281     NapiVerify *napiVerify = nullptr;
282     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
283     if (status != napi_ok || napiVerify == nullptr) {
284         LOGE("failed to unwrap napi verify obj.");
285         return false;
286     }
287 
288     size_t index = 0;
289     HcfBlob *blob = GetBlobFromNapiDataBlob(env, argv[index]);
290     if (blob == nullptr) {
291         LOGE("failed to get blob data from napi.");
292         return false;
293     }
294 
295     ctx->verify = napiVerify->GetVerify();
296     ctx->data = blob;
297 
298     if (napi_create_reference(env, thisVar, 1, &ctx->verifyRef) != napi_ok) {
299         LOGE("create verify ref failed when do verify update!");
300         return false;
301     }
302 
303     if (ctx->asyncType == ASYNC_PROMISE) {
304         napi_create_promise(env, &ctx->deferred, &ctx->promise);
305         return true;
306     } else {
307         return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback);
308     }
309 }
310 
GetDataBlobAndSignatureFromInput(napi_env env,napi_value dataValue,napi_value signatureDataValue,HcfBlob ** returnData,HcfBlob ** returnSignatureData)311 static bool GetDataBlobAndSignatureFromInput(napi_env env, napi_value dataValue, napi_value signatureDataValue,
312     HcfBlob **returnData, HcfBlob **returnSignatureData)
313 {
314     napi_valuetype valueType;
315     napi_typeof(env, dataValue, &valueType);
316     HcfBlob *data = nullptr;
317     if (valueType != napi_null) {
318         data = GetBlobFromNapiDataBlob(env, dataValue);
319         if (data == nullptr) {
320             LOGE("failed to get data.");
321             return false;
322         }
323     }
324 
325     HcfBlob *signatureData = GetBlobFromNapiDataBlob(env, signatureDataValue);
326     if (signatureData == nullptr) {
327         LOGE("failed to get signature.");
328         HcfBlobDataFree(data);
329         HcfFree(data);
330         data = nullptr;
331         return false;
332     }
333 
334     *returnData = data;
335     *returnSignatureData = signatureData;
336     return true;
337 }
338 
GetDataAndSignatureFromInput(napi_env env,napi_value dataValue,napi_value signatureDataValue,HcfBlob * returnData,HcfBlob * returnSignatureData)339 static HcfResult GetDataAndSignatureFromInput(napi_env env, napi_value dataValue, napi_value signatureDataValue,
340     HcfBlob *returnData, HcfBlob *returnSignatureData)
341 {
342     HcfResult ret = GetBlobFromNapiValue(env, signatureDataValue, returnSignatureData);
343     if (ret != HCF_SUCCESS) {
344         LOGE("failed to get signature.");
345         return ret;
346     }
347 
348     napi_valuetype valueType;
349     napi_typeof(env, dataValue, &valueType);
350     if (valueType == napi_null) {  // allow dataValue is empty
351         returnData->data = nullptr;
352         returnData->len = 0;
353         return HCF_SUCCESS;
354     }
355 
356     ret = GetBlobFromNapiValue(env, dataValue, returnData);
357     if (ret != HCF_SUCCESS) {
358         LOGE("failed to get data.");
359         HcfBlobDataFree(returnSignatureData);
360         returnSignatureData->data = nullptr;
361         returnSignatureData->len = 0;
362     }
363 
364     return ret;
365 }
366 
BuildVerifyJsDoFinalCtx(napi_env env,napi_callback_info info,VerifyDoFinalCtx * ctx)367 static bool BuildVerifyJsDoFinalCtx(napi_env env, napi_callback_info info, VerifyDoFinalCtx *ctx)
368 {
369     napi_value thisVar = nullptr;
370     size_t expectedArgc = PARAMS_NUM_THREE;
371     size_t argc = expectedArgc;
372     napi_value argv[PARAMS_NUM_THREE] = { nullptr };
373     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
374     if ((argc != expectedArgc) && (argc != expectedArgc - 1)) {
375         LOGE("wrong argument num. require %{public}zu or %{public}zu arguments. [Argc]: %{public}zu!",
376             expectedArgc - 1, expectedArgc, argc);
377         return false;
378     }
379     ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
380 
381     NapiVerify *napiVerify = nullptr;
382     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
383     if (status != napi_ok || napiVerify == nullptr) {
384         LOGE("failed to unwrap napi verify obj.");
385         return false;
386     }
387 
388     HcfBlob *data = nullptr;
389     HcfBlob *signatureData = nullptr;
390     if (!GetDataBlobAndSignatureFromInput(env, argv[PARAM0], argv[PARAM1], &data, &signatureData)) {
391         return false;
392     }
393 
394     ctx->verify = napiVerify->GetVerify();
395     ctx->data = data;
396     ctx->signatureData = signatureData;
397 
398     if (napi_create_reference(env, thisVar, 1, &ctx->verifyRef) != napi_ok) {
399         LOGE("create verify ref failed when do verify final!");
400         return false;
401     }
402 
403     if (ctx->asyncType == ASYNC_PROMISE) {
404         napi_create_promise(env, &ctx->deferred, &ctx->promise);
405         return true;
406     } else {
407         return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback);
408     }
409 }
410 
ReturnInitCallbackResult(napi_env env,VerifyInitCtx * ctx,napi_value result)411 static void ReturnInitCallbackResult(napi_env env, VerifyInitCtx *ctx, napi_value result)
412 {
413     napi_value businessError = nullptr;
414     if (ctx->errCode != HCF_SUCCESS) {
415         businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg);
416     }
417 
418     napi_value params[ARGS_SIZE_ONE] = { businessError };
419 
420     napi_value func = nullptr;
421     napi_get_reference_value(env, ctx->callback, &func);
422 
423     napi_value recv = nullptr;
424     napi_value callFuncRet = nullptr;
425     napi_get_undefined(env, &recv);
426     napi_call_function(env, recv, func, ARGS_SIZE_ONE, params, &callFuncRet);
427 }
428 
ReturnInitPromiseResult(napi_env env,VerifyInitCtx * ctx,napi_value result)429 static void ReturnInitPromiseResult(napi_env env, VerifyInitCtx *ctx, napi_value result)
430 {
431     if (ctx->errCode == HCF_SUCCESS) {
432         napi_resolve_deferred(env, ctx->deferred, result);
433     } else {
434         napi_reject_deferred(env, ctx->deferred,
435             GenerateBusinessError(env, ctx->errCode, ctx->errMsg));
436     }
437 }
438 
ReturnUpdateCallbackResult(napi_env env,VerifyUpdateCtx * ctx,napi_value result)439 static void ReturnUpdateCallbackResult(napi_env env, VerifyUpdateCtx *ctx, napi_value result)
440 {
441     napi_value businessError = nullptr;
442     if (ctx->errCode != HCF_SUCCESS) {
443         businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg);
444     }
445 
446     napi_value params[ARGS_SIZE_ONE] = { businessError };
447 
448     napi_value func = nullptr;
449     napi_get_reference_value(env, ctx->callback, &func);
450 
451     napi_value recv = nullptr;
452     napi_value callFuncRet = nullptr;
453     napi_get_undefined(env, &recv);
454     napi_call_function(env, recv, func, ARGS_SIZE_ONE, params, &callFuncRet);
455 }
456 
ReturnUpdatePromiseResult(napi_env env,VerifyUpdateCtx * ctx,napi_value result)457 static void ReturnUpdatePromiseResult(napi_env env, VerifyUpdateCtx *ctx, napi_value result)
458 {
459     if (ctx->errCode == HCF_SUCCESS) {
460         napi_resolve_deferred(env, ctx->deferred, result);
461     } else {
462         napi_reject_deferred(env, ctx->deferred,
463             GenerateBusinessError(env, ctx->errCode, ctx->errMsg));
464     }
465 }
466 
ReturnDoFinalCallbackResult(napi_env env,VerifyDoFinalCtx * ctx,napi_value result)467 static void ReturnDoFinalCallbackResult(napi_env env, VerifyDoFinalCtx *ctx, napi_value result)
468 {
469     napi_value businessError = nullptr;
470     if (ctx->errCode != HCF_SUCCESS) {
471         businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg);
472     }
473 
474     napi_value params[ARGS_SIZE_TWO] = { businessError, result };
475 
476     napi_value func = nullptr;
477     napi_get_reference_value(env, ctx->callback, &func);
478 
479     napi_value recv = nullptr;
480     napi_value callFuncRet = nullptr;
481     napi_get_undefined(env, &recv);
482     napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
483 }
484 
ReturnDoFinalPromiseResult(napi_env env,VerifyDoFinalCtx * ctx,napi_value result)485 static void ReturnDoFinalPromiseResult(napi_env env, VerifyDoFinalCtx *ctx, napi_value result)
486 {
487     if (ctx->errCode == HCF_SUCCESS) {
488         napi_resolve_deferred(env, ctx->deferred, result);
489     } else {
490         napi_reject_deferred(env, ctx->deferred,
491             GenerateBusinessError(env, ctx->errCode, ctx->errMsg));
492     }
493 }
494 
ReturnRecoverPromiseResult(napi_env env,VerifyRecoverCtx * ctx,napi_value result)495 static void ReturnRecoverPromiseResult(napi_env env, VerifyRecoverCtx *ctx, napi_value result)
496 {
497     if (ctx->errCode == HCF_SUCCESS) {
498         napi_resolve_deferred(env, ctx->deferred, result);
499     } else {
500         napi_reject_deferred(env, ctx->deferred, GenerateBusinessError(env, ctx->errCode, ctx->errMsg));
501     }
502 }
503 
VerifyJsInitAsyncWorkProcess(napi_env env,void * data)504 static void VerifyJsInitAsyncWorkProcess(napi_env env, void *data)
505 {
506     VerifyInitCtx *ctx = static_cast<VerifyInitCtx *>(data);
507 
508     ctx->errCode = ctx->verify->init(ctx->verify, ctx->params, ctx->pubKey);
509     if (ctx->errCode != HCF_SUCCESS) {
510         LOGD("[error] verify init fail.");
511         ctx->errMsg = "verify init fail.";
512     }
513 }
514 
VerifyJsInitAsyncWorkReturn(napi_env env,napi_status status,void * data)515 static void VerifyJsInitAsyncWorkReturn(napi_env env, napi_status status, void *data)
516 {
517     VerifyInitCtx *ctx = static_cast<VerifyInitCtx *>(data);
518 
519     if (ctx->asyncType == ASYNC_CALLBACK) {
520         ReturnInitCallbackResult(env, ctx, NapiGetNull(env));
521     } else {
522         ReturnInitPromiseResult(env, ctx, NapiGetNull(env));
523     }
524     FreeVerifyInitCtx(env, ctx);
525 }
526 
VerifyJsUpdateAsyncWorkProcess(napi_env env,void * data)527 static void VerifyJsUpdateAsyncWorkProcess(napi_env env, void *data)
528 {
529     VerifyUpdateCtx *ctx = static_cast<VerifyUpdateCtx *>(data);
530 
531     ctx->errCode = ctx->verify->update(ctx->verify, ctx->data);
532     if (ctx->errCode != HCF_SUCCESS) {
533         LOGD("[error] verify update fail.");
534         ctx->errMsg = "verify update fail.";
535     }
536 }
537 
VerifyJsUpdateAsyncWorkReturn(napi_env env,napi_status status,void * data)538 static void VerifyJsUpdateAsyncWorkReturn(napi_env env, napi_status status, void *data)
539 {
540     VerifyUpdateCtx *ctx = static_cast<VerifyUpdateCtx *>(data);
541 
542     if (ctx->asyncType == ASYNC_CALLBACK) {
543         ReturnUpdateCallbackResult(env, ctx, NapiGetNull(env));
544     } else {
545         ReturnUpdatePromiseResult(env, ctx, NapiGetNull(env));
546     }
547     FreeVerifyUpdateCtx(env, ctx);
548 }
549 
VerifyJsDoFinalAsyncWorkProcess(napi_env env,void * data)550 static void VerifyJsDoFinalAsyncWorkProcess(napi_env env, void *data)
551 {
552     VerifyDoFinalCtx *ctx = static_cast<VerifyDoFinalCtx *>(data);
553 
554     ctx->isVerifySucc = ctx->verify->verify(ctx->verify, ctx->data, ctx->signatureData);
555     ctx->errCode = HCF_SUCCESS;
556     if (!ctx->isVerifySucc) {
557         LOGD("[error] verify doFinal fail.");
558         return;
559     }
560 }
561 
VerifyJsDoFinalAsyncWorkReturn(napi_env env,napi_status status,void * data)562 static void VerifyJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, void *data)
563 {
564     VerifyDoFinalCtx *ctx = static_cast<VerifyDoFinalCtx *>(data);
565 
566     napi_value result = nullptr;
567     if (ctx->errCode == HCF_SUCCESS) {
568         napi_get_boolean(env, ctx->isVerifySucc, &result);
569     }
570 
571     if (ctx->asyncType == ASYNC_CALLBACK) {
572         ReturnDoFinalCallbackResult(env, ctx, result);
573     } else {
574         ReturnDoFinalPromiseResult(env, ctx, result);
575     }
576     FreeVerifyDoFinalCtx(env, ctx);
577 }
578 
VerifyJsRecoverAsyncWorkProcess(napi_env env,void * data)579 static void VerifyJsRecoverAsyncWorkProcess(napi_env env, void *data)
580 {
581     VerifyRecoverCtx *ctx = static_cast<VerifyRecoverCtx *>(data);
582 
583     ctx->errCode = ctx->verify->recover(ctx->verify, ctx->signatureData, &ctx->rawSignatureData);
584     if (ctx->errCode != HCF_SUCCESS) {
585         LOGD("[error] verify revover fail.");
586         ctx->errMsg = "verify revover fail.";
587     }
588 }
589 
VerifyJsRecoverAsyncWorkReturn(napi_env env,napi_status status,void * data)590 static void VerifyJsRecoverAsyncWorkReturn(napi_env env, napi_status status, void *data)
591 {
592     VerifyRecoverCtx *ctx = static_cast<VerifyRecoverCtx *>(data);
593 
594     napi_value dataBlob = nullptr;
595     if (ctx->errCode == HCF_SUCCESS) {
596         dataBlob = ConvertBlobToNapiValue(env, &ctx->rawSignatureData);
597     }
598 
599     ReturnRecoverPromiseResult(env, ctx, dataBlob);
600 
601     FreeVerifyRecoverCtx(env, ctx);
602 }
603 
NewVerifyJsInitAsyncWork(napi_env env,VerifyInitCtx * ctx)604 static napi_value NewVerifyJsInitAsyncWork(napi_env env, VerifyInitCtx *ctx)
605 {
606     napi_value resourceName = nullptr;
607     napi_create_string_utf8(env, "init", NAPI_AUTO_LENGTH, &resourceName);
608 
609     napi_create_async_work(
610         env, nullptr, resourceName,
611         [](napi_env env, void *data) {
612             VerifyJsInitAsyncWorkProcess(env, data);
613             return;
614         },
615         [](napi_env env, napi_status status, void *data) {
616             VerifyJsInitAsyncWorkReturn(env, status, data);
617             return;
618         },
619         static_cast<void *>(ctx),
620         &ctx->asyncWork);
621 
622     napi_queue_async_work(env, ctx->asyncWork);
623     if (ctx->asyncType == ASYNC_PROMISE) {
624         return ctx->promise;
625     } else {
626         return NapiGetNull(env);
627     }
628 }
629 
NewVerifyJsUpdateAsyncWork(napi_env env,VerifyUpdateCtx * ctx)630 static napi_value NewVerifyJsUpdateAsyncWork(napi_env env, VerifyUpdateCtx *ctx)
631 {
632     napi_value resourceName = nullptr;
633     napi_create_string_utf8(env, "update", NAPI_AUTO_LENGTH, &resourceName);
634 
635     napi_create_async_work(
636         env, nullptr, resourceName,
637         [](napi_env env, void *data) {
638             VerifyJsUpdateAsyncWorkProcess(env, data);
639             return;
640         },
641         [](napi_env env, napi_status status, void *data) {
642             VerifyJsUpdateAsyncWorkReturn(env, status, data);
643             return;
644         },
645         static_cast<void *>(ctx),
646         &ctx->asyncWork);
647 
648     napi_queue_async_work(env, ctx->asyncWork);
649     if (ctx->asyncType == ASYNC_PROMISE) {
650         return ctx->promise;
651     } else {
652         return NapiGetNull(env);
653     }
654 }
655 
NewVerifyJsDoFinalAsyncWork(napi_env env,VerifyDoFinalCtx * ctx)656 static napi_value NewVerifyJsDoFinalAsyncWork(napi_env env, VerifyDoFinalCtx *ctx)
657 {
658     napi_value resourceName = nullptr;
659     napi_create_string_utf8(env, "verify", NAPI_AUTO_LENGTH, &resourceName);
660 
661     napi_create_async_work(
662         env, nullptr, resourceName,
663         [](napi_env env, void *data) {
664             VerifyJsDoFinalAsyncWorkProcess(env, data);
665             return;
666         },
667         [](napi_env env, napi_status status, void *data) {
668             VerifyJsDoFinalAsyncWorkReturn(env, status, data);
669             return;
670         },
671         static_cast<void *>(ctx),
672         &ctx->asyncWork);
673 
674     napi_queue_async_work(env, ctx->asyncWork);
675     if (ctx->asyncType == ASYNC_PROMISE) {
676         return ctx->promise;
677     } else {
678         return NapiGetNull(env);
679     }
680 }
681 
NewVerifyJsRecoverAsyncWork(napi_env env,VerifyRecoverCtx * ctx)682 static napi_value NewVerifyJsRecoverAsyncWork(napi_env env, VerifyRecoverCtx *ctx)
683 {
684     napi_value resourceName = nullptr;
685     napi_create_string_utf8(env, "verify", NAPI_AUTO_LENGTH, &resourceName);
686 
687     napi_create_async_work(
688         env, nullptr, resourceName,
689         [](napi_env env, void *data) {
690             VerifyJsRecoverAsyncWorkProcess(env, data);
691             return;
692         },
693         [](napi_env env, napi_status status, void *data) {
694             VerifyJsRecoverAsyncWorkReturn(env, status, data);
695             return;
696         },
697         static_cast<void *>(ctx),
698         &ctx->asyncWork);
699 
700     napi_queue_async_work(env, ctx->asyncWork);
701     return ctx->promise;
702 }
703 
NapiVerify(HcfVerify * verify)704 NapiVerify::NapiVerify(HcfVerify *verify)
705 {
706     this->verify_ = verify;
707 }
708 
~NapiVerify()709 NapiVerify::~NapiVerify()
710 {
711     HcfObjDestroy(this->verify_);
712     this->verify_ = nullptr;
713 }
714 
GetVerify()715 HcfVerify *NapiVerify::GetVerify()
716 {
717     return this->verify_;
718 }
719 
JsInit(napi_env env,napi_callback_info info)720 napi_value NapiVerify::JsInit(napi_env env, napi_callback_info info)
721 {
722     VerifyInitCtx *ctx = static_cast<VerifyInitCtx *>(HcfMalloc(sizeof(VerifyInitCtx), 0));
723     if (ctx == nullptr) {
724         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail."));
725         LOGE("create context fail.");
726         return nullptr;
727     }
728 
729     if (!BuildVerifyJsInitCtx(env, info, ctx)) {
730         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail."));
731         LOGE("build context fail.");
732         FreeVerifyInitCtx(env, ctx);
733         return nullptr;
734     }
735 
736     return NewVerifyJsInitAsyncWork(env, ctx);
737 }
738 
JsInitSync(napi_env env,napi_callback_info info)739 napi_value NapiVerify::JsInitSync(napi_env env, napi_callback_info info)
740 {
741     napi_value thisVar = nullptr;
742     size_t argc = PARAMS_NUM_ONE;
743     napi_value argv[PARAMS_NUM_ONE] = { nullptr };
744     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
745     if (argc != PARAMS_NUM_ONE) {
746         LOGE("wrong argument num. require %{public}d arguments. [Argc]: %{public}zu!", PARAMS_NUM_ONE, argc);
747         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "wrong argument num."));
748         return nullptr;
749     }
750 
751     NapiVerify *napiVerify = nullptr;
752     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
753     if (status != napi_ok || napiVerify == nullptr) {
754         LOGE("failed to unwrap napi verify obj.");
755         napi_throw(env, GenerateBusinessError(env, HCF_ERR_NAPI, "failed to unwrap napi verify obj."));
756         return nullptr;
757     }
758 
759     NapiPubKey *napiPubKey = nullptr;
760     status = napi_unwrap(env, argv[PARAM0], reinterpret_cast<void **>(&napiPubKey));
761     if (status != napi_ok || napiPubKey == nullptr) {
762         LOGE("failed to unwrap napi pubKey obj.");
763         napi_throw(env, GenerateBusinessError(env, HCF_ERR_NAPI, "failed to unwrap napi pubKey obj."));
764         return nullptr;
765     }
766 
767     HcfVerify *verify = napiVerify->GetVerify();
768     HcfPubKey *pubKey = napiPubKey->GetPubKey();
769 
770     HcfResult ret = verify->init(verify, nullptr, pubKey);
771     if (ret != HCF_SUCCESS) {
772         LOGE("verify init fail.");
773         napi_throw(env, GenerateBusinessError(env, ret, "verify init fail."));
774         return nullptr;
775     }
776     napi_value instance = NapiGetNull(env);
777     return instance;
778 }
779 
JsUpdate(napi_env env,napi_callback_info info)780 napi_value NapiVerify::JsUpdate(napi_env env, napi_callback_info info)
781 {
782     VerifyUpdateCtx *ctx = static_cast<VerifyUpdateCtx *>(HcfMalloc(sizeof(VerifyUpdateCtx), 0));
783     if (ctx == nullptr) {
784         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail."));
785         LOGE("create context fail.");
786         return nullptr;
787     }
788 
789     if (!BuildVerifyJsUpdateCtx(env, info, ctx)) {
790         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail."));
791         LOGE("build context fail.");
792         FreeVerifyUpdateCtx(env, ctx);
793         return nullptr;
794     }
795 
796     return NewVerifyJsUpdateAsyncWork(env, ctx);
797 }
798 
JsUpdateSync(napi_env env,napi_callback_info info)799 napi_value NapiVerify::JsUpdateSync(napi_env env, napi_callback_info info)
800 {
801     napi_value thisVar = nullptr;
802     size_t argc = PARAMS_NUM_ONE;
803     napi_value argv[PARAMS_NUM_ONE] = { nullptr };
804     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
805     if (argc != PARAMS_NUM_ONE) {
806         LOGE("wrong argument num. require %{public}d arguments. [Argc]: %{public}zu!", PARAMS_NUM_ONE, argc);
807         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "wrong argument num."));
808         return nullptr;
809     }
810 
811     NapiVerify *napiVerify = nullptr;
812     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
813     if (status != napi_ok || napiVerify == nullptr) {
814         LOGE("failed to unwrap napi verify obj.");
815         napi_throw(env, GenerateBusinessError(env, HCF_ERR_NAPI, "failed to unwrap napi verify obj."));
816         return nullptr;
817     }
818 
819     HcfBlob blob = { 0 };
820     HcfResult ret = GetBlobFromNapiValue(env, argv[PARAM0], &blob);
821     if (ret != HCF_SUCCESS) {
822         LOGE("failed to get input blob!");
823         napi_throw(env, GenerateBusinessError(env, ret, "failed to get input blob."));
824         return nullptr;
825     }
826 
827     HcfVerify *verify = napiVerify->GetVerify();
828     if (verify == nullptr) {
829         LOGE("failed to get verify obj.");
830         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get verify obj."));
831         return nullptr;
832     }
833     ret = verify->update(verify, &blob);
834     HcfBlobDataFree(&blob);
835     if (ret != HCF_SUCCESS) {
836         LOGE("verify update fail.");
837         napi_throw(env, GenerateBusinessError(env, ret, "verify update fail."));
838     }
839     napi_value instance = NapiGetNull(env);
840     return instance;
841 }
842 
JsVerify(napi_env env,napi_callback_info info)843 napi_value NapiVerify::JsVerify(napi_env env, napi_callback_info info)
844 {
845     VerifyDoFinalCtx *ctx = static_cast<VerifyDoFinalCtx *>(HcfMalloc(sizeof(VerifyDoFinalCtx), 0));
846     if (ctx == nullptr) {
847         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail."));
848         LOGE("create context fail.");
849         return nullptr;
850     }
851 
852     if (!BuildVerifyJsDoFinalCtx(env, info, ctx)) {
853         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail."));
854         LOGE("build context fail.");
855         FreeVerifyDoFinalCtx(env, ctx);
856         return nullptr;
857     }
858 
859     return NewVerifyJsDoFinalAsyncWork(env, ctx);
860 }
861 
JsVerifySync(napi_env env,napi_callback_info info)862 napi_value NapiVerify::JsVerifySync(napi_env env, napi_callback_info info)
863 {
864     napi_value thisVar = nullptr;
865     size_t argc = PARAMS_NUM_TWO;
866     napi_value argv[PARAMS_NUM_TWO] = { nullptr };
867     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
868     if (argc != PARAMS_NUM_TWO) {
869         LOGE("wrong argument num. require %{public}d arguments. [Argc]: %{public}zu!", PARAMS_NUM_TWO, argc);
870         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "wrong argument num."));
871         return nullptr;
872     }
873 
874     NapiVerify *napiVerify = nullptr;
875     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
876     if (status != napi_ok || napiVerify == nullptr) {
877         LOGE("failed to unwrap napi verify obj.");
878         napi_throw(env, GenerateBusinessError(env, HCF_ERR_NAPI, "failed to unwrap napi verify obj."));
879         return nullptr;
880     }
881 
882     HcfBlob data = { 0 };
883     HcfBlob signatureData = { 0 };
884     HcfResult ret = GetDataAndSignatureFromInput(env, argv[PARAM0], argv[PARAM1], &data, &signatureData);
885     if (ret != HCF_SUCCESS) {
886         napi_throw(env, GenerateBusinessError(env, ret, "failed to parse param1 or param2."));
887         return nullptr;
888     }
889 
890     HcfVerify *verify = napiVerify->GetVerify();
891     bool isVerifySucc = verify->verify(verify, &data, &signatureData);
892     HcfBlobDataFree(&data);
893     HcfBlobDataFree(&signatureData);
894     if (!isVerifySucc) {
895         LOGD("verify doFinal fail.");
896     }
897     napi_value result = nullptr;
898     napi_get_boolean(env, isVerifySucc, &result);
899     return result;
900 }
901 
BuildVerifyJsRecoverCtx(napi_env env,napi_callback_info info,VerifyRecoverCtx * ctx)902 HcfResult BuildVerifyJsRecoverCtx(napi_env env, napi_callback_info info, VerifyRecoverCtx *ctx)
903 {
904     napi_value thisVar = nullptr;
905     size_t expectedArgc = PARAMS_NUM_ONE;
906     size_t argc = PARAMS_NUM_ONE;
907     napi_value argv[PARAMS_NUM_ONE] = { nullptr };
908     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
909     if (argc != expectedArgc) {
910         LOGE("wrong argument num. require %{public}zu arguments. [Argc]: %{public}zu!", expectedArgc, argc);
911         return HCF_INVALID_PARAMS;
912     }
913 
914     NapiVerify *napiVerify = nullptr;
915     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
916     if (status != napi_ok || napiVerify == nullptr) {
917         LOGE("failed to unwrap napi verify obj.");
918         return HCF_ERR_NAPI;
919     }
920 
921     ctx->verify = napiVerify->GetVerify();
922     if (ctx->verify == nullptr) {
923         LOGE("failed to get verify obj.");
924         return HCF_INVALID_PARAMS;
925     }
926 
927     ctx->signatureData = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
928     if (ctx->signatureData == nullptr) {
929         LOGE("failed to allocate newBlob memory!");
930         return HCF_ERR_MALLOC;
931     }
932 
933     HcfResult ret = GetBlobFromNapiValue(env, argv[PARAM0], ctx->signatureData);
934     if (ret != HCF_SUCCESS) {
935         return ret;
936     }
937 
938     if (napi_create_reference(env, thisVar, 1, &ctx->verifyRef) != napi_ok) {
939         LOGE("create verify ref failed when do verify recover!");
940         return HCF_ERR_NAPI;
941     }
942 
943     napi_create_promise(env, &ctx->deferred, &ctx->promise);
944     return HCF_SUCCESS;
945 }
946 
JsRecover(napi_env env,napi_callback_info info)947 napi_value NapiVerify::JsRecover(napi_env env, napi_callback_info info)
948 {
949     VerifyRecoverCtx *ctx = static_cast<VerifyRecoverCtx *>(HcfMalloc(sizeof(VerifyRecoverCtx), 0));
950     if (ctx == nullptr) {
951         LOGE("create context fail.");
952         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail."));
953         return nullptr;
954     }
955 
956     HcfResult ret = BuildVerifyJsRecoverCtx(env, info, ctx);
957     if (ret != HCF_SUCCESS) {
958         LOGE("build context fail.");
959         napi_throw(env, GenerateBusinessError(env, ret, "build context fail."));
960         FreeVerifyRecoverCtx(env, ctx);
961         return nullptr;
962     }
963 
964     return NewVerifyJsRecoverAsyncWork(env, ctx);
965 }
966 
JsRecoverSync(napi_env env,napi_callback_info info)967 napi_value NapiVerify::JsRecoverSync(napi_env env, napi_callback_info info)
968 {
969     napi_value thisVar = nullptr;
970     size_t expectedArgc = PARAMS_NUM_ONE;
971     size_t argc = PARAMS_NUM_ONE;
972     napi_value argv[PARAMS_NUM_ONE] = { nullptr };
973     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
974     if (argc != expectedArgc) {
975         LOGE("wrong argument num. require %{public}zu argument. [Argc]: %{public}zu!", expectedArgc, argc);
976         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "wrong argument num."));
977         return nullptr;
978     }
979 
980     NapiVerify *napiVerify = nullptr;
981     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
982     if (status != napi_ok || napiVerify == nullptr) {
983         LOGE("failed to unwrap napi verify obj.");
984         napi_throw(env, GenerateBusinessError(env, HCF_ERR_NAPI, "failed to unwrap napi verify obj."));
985         return nullptr;
986     }
987 
988     HcfVerify *verify = napiVerify->GetVerify();
989     if (verify == nullptr) {
990         LOGE("failed to get verify obj.");
991         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "fail to get verify obj."));
992         return nullptr;
993     }
994 
995     HcfBlob signatureData = { 0 };
996     HcfResult ret = GetBlobFromNapiValue(env, argv[PARAM0], &signatureData);
997     if (ret != HCF_SUCCESS) {
998         LOGE("failed to get signature data.");
999         napi_throw(env, GenerateBusinessError(env, ret, "failed to get signature data."));
1000         return nullptr;
1001     }
1002 
1003     HcfBlob rawSignatureData = { .data = nullptr, .len = 0};
1004     HcfResult res = verify->recover(verify, &signatureData, &rawSignatureData);
1005     HcfBlobDataFree(&signatureData);
1006     if (res != HCF_SUCCESS) {
1007         LOGE("failed to verify recover.");
1008         napi_throw(env, GenerateBusinessError(env, res, "failed to verify recover."));
1009         return nullptr;
1010     }
1011 
1012     napi_value instance = nullptr;
1013     res = ConvertDataBlobToNapiValue(env, &rawSignatureData, &instance);
1014     HcfBlobDataFree(&rawSignatureData);
1015     if (res != HCF_SUCCESS) {
1016         LOGE("verify recover convert dataBlob to napi_value failed!");
1017         napi_throw(env, GenerateBusinessError(env, res, "verify recover convert dataBlob to napi_value failed!"));
1018         return nullptr;
1019     }
1020 
1021     return instance;
1022 }
1023 
VerifyConstructor(napi_env env,napi_callback_info info)1024 napi_value NapiVerify::VerifyConstructor(napi_env env, napi_callback_info info)
1025 {
1026     napi_value thisVar = nullptr;
1027     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1028     return thisVar;
1029 }
1030 
NapiWrapVerify(napi_env env,napi_value instance,NapiVerify * napiVerify)1031 static napi_value NapiWrapVerify(napi_env env, napi_value instance, NapiVerify *napiVerify)
1032 {
1033     napi_status status = napi_wrap(
1034         env, instance, napiVerify,
1035         [](napi_env env, void *data, void *hint) {
1036             NapiVerify *napiVerify = static_cast<NapiVerify *>(data);
1037             delete napiVerify;
1038             return;
1039         }, nullptr, nullptr);
1040     if (status != napi_ok) {
1041         LOGE("failed to wrap napiVerify obj!");
1042         delete napiVerify;
1043         return nullptr;
1044     }
1045     return instance;
1046 }
1047 
CreateJsVerify(napi_env env,napi_callback_info info)1048 napi_value NapiVerify::CreateJsVerify(napi_env env, napi_callback_info info)
1049 {
1050     size_t expectedArgc = PARAMS_NUM_ONE;
1051     size_t argc = expectedArgc;
1052     napi_value argv[PARAMS_NUM_ONE] = { nullptr };
1053     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1054 
1055     if (argc != expectedArgc) {
1056         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
1057         LOGE("The input args num is invalid.");
1058         return nullptr;
1059     }
1060 
1061     napi_value instance;
1062     napi_value constructor = nullptr;
1063     napi_get_reference_value(env, classRef_, &constructor);
1064     napi_new_instance(env, constructor, argc, argv, &instance);
1065 
1066     std::string algName;
1067     if (!GetStringFromJSParams(env, argv[0], algName)) {
1068         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get algoName."));
1069         LOGE("failed to get algoName.");
1070         return nullptr;
1071     }
1072 
1073     HcfVerify *verify = nullptr;
1074     HcfResult ret = HcfVerifyCreate(algName.c_str(), &verify);
1075     if (ret != HCF_SUCCESS) {
1076         napi_throw(env, GenerateBusinessError(env, ret, "create c verify fail."));
1077         LOGE("create c verify fail.");
1078         return nullptr;
1079     }
1080 
1081     NapiVerify *napiVerify = new (std::nothrow) NapiVerify(verify);
1082     if (napiVerify == nullptr) {
1083         napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi verify failed"));
1084         LOGE("new napi verify failed");
1085         HcfObjDestroy(verify);
1086         verify = nullptr;
1087         return nullptr;
1088     }
1089 
1090     napi_value napiAlgName = nullptr;
1091     napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName);
1092     napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName);
1093 
1094     return NapiWrapVerify(env, instance, napiVerify);
1095 }
1096 
SetVerifyUserIdUintArray(napi_env env,napi_value * argv,HcfVerify * verify)1097 static HcfResult SetVerifyUserIdUintArray(napi_env env, napi_value *argv, HcfVerify *verify)
1098 {
1099     HcfBlob *blob = nullptr;
1100     blob = GetBlobFromNapiUint8Arr(env, argv[1]);
1101     if (blob == nullptr) {
1102         LOGE("failed to get blob.");
1103         return HCF_INVALID_PARAMS;
1104     }
1105     HcfResult ret = verify->setVerifySpecUint8Array(verify, SM2_USER_ID_UINT8ARR, *blob);
1106     if (ret != HCF_SUCCESS) {
1107         HcfBlobDataFree(blob);
1108         HcfFree(blob);
1109         blob = nullptr;
1110         LOGE("c SetVerifyUserIdUintArray failed.");
1111         return HCF_INVALID_PARAMS;
1112     }
1113     HcfBlobDataFree(blob);
1114     HcfFree(blob);
1115     blob = nullptr;
1116     return ret;
1117 }
1118 
SetVerifySaltLenInt(napi_env env,napi_value * argv,HcfVerify * verify)1119 static HcfResult SetVerifySaltLenInt(napi_env env, napi_value *argv, HcfVerify *verify)
1120 {
1121     int32_t saltLen = 0;
1122     if (napi_get_value_int32(env, argv[1], &saltLen) != napi_ok) {
1123         LOGE("get signSpec saltLen failed!");
1124         return HCF_INVALID_PARAMS;
1125     }
1126     HcfResult ret = verify->setVerifySpecInt(verify, PSS_SALT_LEN_INT, saltLen);
1127     if (ret != HCF_SUCCESS) {
1128         LOGE("c setSignSpecNumber fail.");
1129         return HCF_INVALID_PARAMS;
1130     }
1131     return ret;
1132 }
1133 
SetDetailVerifySpec(napi_env env,napi_value * argv,SignSpecItem item,HcfVerify * verify)1134 static HcfResult SetDetailVerifySpec(napi_env env, napi_value *argv, SignSpecItem item, HcfVerify *verify)
1135 {
1136     HcfResult result = HCF_INVALID_PARAMS;
1137 
1138     switch (item) {
1139         case SM2_USER_ID_UINT8ARR:
1140             result = SetVerifyUserIdUintArray(env, argv, verify);
1141             break;
1142         case PSS_SALT_LEN_INT:
1143             result = SetVerifySaltLenInt(env, argv, verify);
1144             break;
1145         default:
1146             LOGE("specItem not support.");
1147             break;
1148     }
1149     return result;
1150 }
1151 
1152 // verify setVerifySpec(itemType :VerifySpecItem, itemValue : number|string)
JsSetVerifySpec(napi_env env,napi_callback_info info)1153 napi_value NapiVerify::JsSetVerifySpec(napi_env env, napi_callback_info info)
1154 {
1155     napi_value thisVar = nullptr;
1156     NapiVerify *napiVerify = nullptr;
1157     size_t expectedArgc = ARGS_SIZE_TWO;
1158     size_t argc = ARGS_SIZE_TWO;
1159     napi_value argv[ARGS_SIZE_TWO] = { nullptr };
1160     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1161     if (argc != expectedArgc) {
1162         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num."));
1163         LOGE("wrong argument num. require 2 arguments. [Argc]: %{public}zu!", argc);
1164         return nullptr;
1165     }
1166     SignSpecItem item;
1167     if (napi_get_value_uint32(env, argv[0], reinterpret_cast<uint32_t *>(&item)) != napi_ok) {
1168         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get signSpecItem failed!"));
1169         LOGE("get signspecitem failed!");
1170         return nullptr;
1171     }
1172     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
1173     if (status != napi_ok || napiVerify == nullptr) {
1174         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiVerify obj!"));
1175         LOGE("failed to unwrap napiVerify obj!");
1176         return nullptr;
1177     }
1178     HcfVerify *verify = napiVerify->GetVerify();
1179     if (SetDetailVerifySpec(env, argv, item, verify) != HCF_SUCCESS) {
1180         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to set verify spec!"));
1181         LOGE("failed to set verify spec!");
1182         return nullptr;
1183     }
1184     return thisVar;
1185 }
1186 
GetVerifySpecString(napi_env env,SignSpecItem item,HcfVerify * verify)1187 static napi_value GetVerifySpecString(napi_env env, SignSpecItem item, HcfVerify *verify)
1188 {
1189     char *returnString = nullptr;
1190     HcfResult ret = verify->getVerifySpecString(verify, item, &returnString);
1191     if (ret != HCF_SUCCESS) {
1192         napi_throw(env, GenerateBusinessError(env, ret, "C getVerifySpecString failed."));
1193         LOGE("c getVerifySpecString fail.");
1194         return nullptr;
1195     }
1196 
1197     napi_value instance = nullptr;
1198     napi_create_string_utf8(env, returnString, NAPI_AUTO_LENGTH, &instance);
1199     HcfFree(returnString);
1200     returnString = nullptr;
1201     return instance;
1202 }
1203 
GetVerifySpecNumber(napi_env env,SignSpecItem item,HcfVerify * verify)1204 static napi_value GetVerifySpecNumber(napi_env env, SignSpecItem item, HcfVerify *verify)
1205 {
1206     int returnInt;
1207     HcfResult ret = verify->getVerifySpecInt(verify, item, &returnInt);
1208     if (ret != HCF_SUCCESS) {
1209         napi_throw(env, GenerateBusinessError(env, ret, "C getVerifySpecInt failed."));
1210         LOGE("c getVerifySpecInt fail.");
1211         return nullptr;
1212     }
1213 
1214     napi_value instance = nullptr;
1215     napi_create_int32(env, returnInt, &instance);
1216     return instance;
1217 }
1218 
JsGetVerifySpec(napi_env env,napi_callback_info info)1219 napi_value NapiVerify::JsGetVerifySpec(napi_env env, napi_callback_info info)
1220 {
1221     napi_value thisVar = nullptr;
1222     NapiVerify *napiVerify = nullptr;
1223     size_t expectedArgc = ARGS_SIZE_ONE;
1224     size_t argc = ARGS_SIZE_ONE;
1225     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
1226     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1227     if (argc != expectedArgc) {
1228         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num."));
1229         LOGE("wrong argument num. require 1 arguments. [Argc]: %{public}zu!", argc);
1230         return nullptr;
1231     }
1232     SignSpecItem item;
1233     if (napi_get_value_uint32(env, argv[0], reinterpret_cast<uint32_t *>(&item)) != napi_ok) {
1234         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get signSpecItem failed!"));
1235         LOGE("get signSpecItem failed!");
1236         return nullptr;
1237     }
1238 
1239     napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
1240     if (status != napi_ok || napiVerify == nullptr) {
1241         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiVerify obj!"));
1242         LOGE("failed to unwrap napiVerify obj!");
1243         return nullptr;
1244     }
1245     HcfVerify *verify = napiVerify->GetVerify();
1246     if (verify == nullptr) {
1247         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get verify obj!"));
1248         LOGE("failed to get verfiy obj!");
1249         return nullptr;
1250     }
1251 
1252     int32_t type = GetSignSpecType(item);
1253     if (type == SPEC_ITEM_TYPE_STR) {
1254         return GetVerifySpecString(env, item, verify);
1255     } else if (type == SPEC_ITEM_TYPE_NUM) {
1256         return GetVerifySpecNumber(env, item, verify);
1257     } else {
1258         napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "VerifySpecItem not support!"));
1259         return nullptr;
1260     }
1261 }
1262 
DefineVerifyJSClass(napi_env env,napi_value exports)1263 void NapiVerify::DefineVerifyJSClass(napi_env env, napi_value exports)
1264 {
1265     napi_property_descriptor desc[] = {
1266         DECLARE_NAPI_FUNCTION("createVerify", NapiVerify::CreateJsVerify),
1267     };
1268     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1269 
1270     napi_property_descriptor classDesc[] = {
1271         DECLARE_NAPI_FUNCTION("init", NapiVerify::JsInit),
1272         DECLARE_NAPI_FUNCTION("update", NapiVerify::JsUpdate),
1273         DECLARE_NAPI_FUNCTION("verify", NapiVerify::JsVerify),
1274         DECLARE_NAPI_FUNCTION("initSync", NapiVerify::JsInitSync),
1275         DECLARE_NAPI_FUNCTION("updateSync", NapiVerify::JsUpdateSync),
1276         DECLARE_NAPI_FUNCTION("verifySync", NapiVerify::JsVerifySync),
1277         DECLARE_NAPI_FUNCTION("recover", NapiVerify::JsRecover),
1278         DECLARE_NAPI_FUNCTION("recoverSync", NapiVerify::JsRecoverSync),
1279         DECLARE_NAPI_FUNCTION("setVerifySpec", NapiVerify::JsSetVerifySpec),
1280         DECLARE_NAPI_FUNCTION("getVerifySpec", NapiVerify::JsGetVerifySpec),
1281     };
1282     napi_value constructor = nullptr;
1283     napi_define_class(env, "Verify", NAPI_AUTO_LENGTH, NapiVerify::VerifyConstructor, nullptr,
1284         sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor);
1285     napi_create_reference(env, constructor, 1, &classRef_);
1286 }
1287 } // CryptoFramework
1288 } // OHOS
1289