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