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