1 /*
2 * Copyright (C) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi_verify.h"
17
18 #include "securec.h"
19 #include "log.h"
20 #include "memory.h"
21
22 #include "napi_crypto_framework_defines.h"
23 #include "napi_pri_key.h"
24 #include "napi_pub_key.h"
25 #include "napi_utils.h"
26
27 namespace OHOS {
28 namespace CryptoFramework {
29 struct VerifyInitCtx {
30 napi_env env = nullptr;
31
32 AsyncType asyncType = ASYNC_CALLBACK;
33 napi_ref callback = nullptr;
34 napi_deferred deferred = nullptr;
35 napi_value promise = nullptr;
36 napi_async_work asyncWork = nullptr;
37
38 HcfVerify *verify = nullptr;
39 HcfParamsSpec *params = nullptr;
40 HcfPubKey *pubKey = nullptr;
41
42 HcfResult errCode = HCF_SUCCESS;
43 const char *errMsg = nullptr;
44 };
45
46 struct VerifyUpdateCtx {
47 napi_env env = nullptr;
48
49 AsyncType asyncType = ASYNC_CALLBACK;
50 napi_ref callback = nullptr;
51 napi_deferred deferred = nullptr;
52 napi_value promise = nullptr;
53 napi_async_work asyncWork = nullptr;
54
55 HcfVerify *verify = nullptr;
56 HcfBlob *data = nullptr;
57
58 HcfResult errCode = HCF_SUCCESS;
59 const char *errMsg = nullptr;
60 };
61
62 struct VerifyDoFinalCtx {
63 napi_env env = nullptr;
64
65 AsyncType asyncType = ASYNC_CALLBACK;
66 napi_ref callback = nullptr;
67 napi_deferred deferred = nullptr;
68 napi_value promise = nullptr;
69 napi_async_work asyncWork = nullptr;
70
71 HcfVerify *verify = nullptr;
72 HcfBlob *data = nullptr;
73 HcfBlob *signatureData = nullptr;
74
75 HcfResult errCode = HCF_SUCCESS;
76 const char *errMsg = nullptr;
77 bool isVerifySucc;
78 };
79
80 thread_local napi_ref NapiVerify::classRef_ = nullptr;
81
FreeVerifyInitCtx(napi_env env,VerifyInitCtx * ctx)82 static void FreeVerifyInitCtx(napi_env env, VerifyInitCtx *ctx)
83 {
84 if (ctx == nullptr) {
85 return;
86 }
87
88 if (ctx->asyncWork != nullptr) {
89 napi_delete_async_work(env, ctx->asyncWork);
90 ctx->asyncWork = nullptr;
91 }
92
93 if (ctx->callback != nullptr) {
94 napi_delete_reference(env, ctx->callback);
95 ctx->callback = nullptr;
96 }
97
98 HcfFree(ctx);
99 }
100
FreeVerifyUpdateCtx(napi_env env,VerifyUpdateCtx * ctx)101 static void FreeVerifyUpdateCtx(napi_env env, VerifyUpdateCtx *ctx)
102 {
103 if (ctx == nullptr) {
104 return;
105 }
106
107 if (ctx->asyncWork != nullptr) {
108 napi_delete_async_work(env, ctx->asyncWork);
109 ctx->asyncWork = nullptr;
110 }
111
112 if (ctx->callback != nullptr) {
113 napi_delete_reference(env, ctx->callback);
114 ctx->callback = nullptr;
115 }
116
117 HcfBlobDataFree(ctx->data);
118 HcfFree(ctx->data);
119 HcfFree(ctx);
120 }
121
FreeVerifyDoFinalCtx(napi_env env,VerifyDoFinalCtx * ctx)122 static void FreeVerifyDoFinalCtx(napi_env env, VerifyDoFinalCtx *ctx)
123 {
124 if (ctx == nullptr) {
125 return;
126 }
127
128 if (ctx->asyncWork != nullptr) {
129 napi_delete_async_work(env, ctx->asyncWork);
130 ctx->asyncWork = nullptr;
131 }
132
133 if (ctx->callback != nullptr) {
134 napi_delete_reference(env, ctx->callback);
135 ctx->callback = nullptr;
136 }
137
138 HcfBlobDataFree(ctx->data);
139 HcfFree(ctx->data);
140 HcfBlobDataFree(ctx->signatureData);
141 HcfFree(ctx->signatureData);
142 HcfFree(ctx);
143 }
144
BuildVerifyJsInitCtx(napi_env env,napi_callback_info info,VerifyInitCtx * ctx)145 static bool BuildVerifyJsInitCtx(napi_env env, napi_callback_info info, VerifyInitCtx *ctx)
146 {
147 napi_value thisVar = nullptr;
148 size_t expectedArgc = PARAMS_NUM_TWO;
149 size_t argc = expectedArgc;
150 napi_value argv[PARAMS_NUM_TWO] = { nullptr, nullptr };
151 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
152 if ((argc != expectedArgc) && (argc != expectedArgc - 1)) {
153 LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc);
154 return false;
155 }
156 ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
157
158 NapiVerify *napiVerify = nullptr;
159 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
160 if (status != napi_ok || napiVerify == nullptr) {
161 LOGE("failed to unwrap napi verify obj.");
162 return false;
163 }
164
165 size_t index = 0;
166 NapiPubKey *napiPubKey = nullptr;
167 status = napi_unwrap(env, argv[index], reinterpret_cast<void **>(&napiPubKey));
168 if (status != napi_ok || napiPubKey == nullptr) {
169 LOGE("failed to unwrap napi pubKey obj.");
170 return false;
171 }
172
173 ctx->verify = napiVerify->GetVerify();
174 ctx->params = nullptr;
175 ctx->pubKey = napiPubKey->GetPubKey();
176
177 if (ctx->asyncType == ASYNC_PROMISE) {
178 napi_create_promise(env, &ctx->deferred, &ctx->promise);
179 return true;
180 } else {
181 return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback);
182 }
183 }
184
BuildVerifyJsUpdateCtx(napi_env env,napi_callback_info info,VerifyUpdateCtx * ctx)185 static bool BuildVerifyJsUpdateCtx(napi_env env, napi_callback_info info, VerifyUpdateCtx *ctx)
186 {
187 napi_value thisVar = nullptr;
188 size_t expectedArgc = PARAMS_NUM_TWO;
189 size_t argc = expectedArgc;
190 napi_value argv[PARAMS_NUM_TWO] = { nullptr, nullptr };
191 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
192 if ((argc != expectedArgc) && (argc != expectedArgc - 1)) {
193 LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc);
194 return false;
195 }
196 ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
197
198 NapiVerify *napiVerify = nullptr;
199 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
200 if (status != napi_ok || napiVerify == nullptr) {
201 LOGE("failed to unwrap napi verify obj.");
202 return false;
203 }
204
205 size_t index = 0;
206 HcfBlob *blob = GetBlobFromNapiValue(env, argv[index]);
207 if (blob == nullptr) {
208 return false;
209 }
210
211 ctx->verify = napiVerify->GetVerify();
212 ctx->data = blob;
213
214 if (ctx->asyncType == ASYNC_PROMISE) {
215 napi_create_promise(env, &ctx->deferred, &ctx->promise);
216 return true;
217 } else {
218 return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback);
219 }
220 }
221
GetDataBlobAndSignatureFromInput(napi_env env,napi_value dataValue,napi_value signatureDataValue,HcfBlob ** returnData,HcfBlob ** returnSignatureData)222 static bool GetDataBlobAndSignatureFromInput(napi_env env, napi_value dataValue, napi_value signatureDataValue,
223 HcfBlob **returnData, HcfBlob **returnSignatureData)
224 {
225 napi_valuetype valueType;
226 napi_typeof(env, dataValue, &valueType);
227 HcfBlob *data = nullptr;
228 if (valueType != napi_null) {
229 data = GetBlobFromNapiValue(env, dataValue);
230 if (data == nullptr) {
231 LOGE("failed to get data.");
232 return false;
233 }
234 }
235
236 HcfBlob *signatureData = GetBlobFromNapiValue(env, signatureDataValue);
237 if (signatureData == nullptr) {
238 LOGE("failed to get signature.");
239 HcfBlobDataFree(data);
240 HcfFree(data);
241 return false;
242 }
243
244 *returnData = data;
245 *returnSignatureData = signatureData;
246 return true;
247 }
248
BuildVerifyJsDoFinalCtx(napi_env env,napi_callback_info info,VerifyDoFinalCtx * ctx)249 static bool BuildVerifyJsDoFinalCtx(napi_env env, napi_callback_info info, VerifyDoFinalCtx *ctx)
250 {
251 napi_value thisVar = nullptr;
252 size_t expectedArgc = PARAMS_NUM_THREE;
253 size_t argc = expectedArgc;
254 napi_value argv[PARAMS_NUM_THREE] = { nullptr, nullptr, nullptr };
255 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
256 if ((argc != expectedArgc) && (argc != expectedArgc - 1)) {
257 LOGE("wrong argument num. require %zu or %zu arguments. [Argc]: %zu!", expectedArgc - 1, expectedArgc, argc);
258 return false;
259 }
260 ctx->asyncType = isCallback(env, argv[expectedArgc - 1], argc, expectedArgc) ? ASYNC_CALLBACK : ASYNC_PROMISE;
261
262 NapiVerify *napiVerify = nullptr;
263 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
264 if (status != napi_ok || napiVerify == nullptr) {
265 LOGE("failed to unwrap napi verify obj.");
266 return false;
267 }
268
269 HcfBlob *data = nullptr;
270 HcfBlob *signatureData = nullptr;
271 if (!GetDataBlobAndSignatureFromInput(env, argv[PARAM0], argv[PARAM1], &data, &signatureData)) {
272 return false;
273 }
274
275 ctx->verify = napiVerify->GetVerify();
276 ctx->data = data;
277 ctx->signatureData = signatureData;
278
279 if (ctx->asyncType == ASYNC_PROMISE) {
280 napi_create_promise(env, &ctx->deferred, &ctx->promise);
281 return true;
282 } else {
283 return GetCallbackFromJSParams(env, argv[expectedArgc - 1], &ctx->callback);
284 }
285 }
286
ReturnInitCallbackResult(napi_env env,VerifyInitCtx * ctx,napi_value result)287 static void ReturnInitCallbackResult(napi_env env, VerifyInitCtx *ctx, napi_value result)
288 {
289 napi_value businessError = nullptr;
290 if (ctx->errCode != HCF_SUCCESS) {
291 businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg);
292 }
293
294 napi_value params[ARGS_SIZE_ONE] = { businessError };
295
296 napi_value func = nullptr;
297 napi_get_reference_value(env, ctx->callback, &func);
298
299 napi_value recv = nullptr;
300 napi_value callFuncRet = nullptr;
301 napi_get_undefined(env, &recv);
302 napi_call_function(env, recv, func, ARGS_SIZE_ONE, params, &callFuncRet);
303 }
304
ReturnInitPromiseResult(napi_env env,VerifyInitCtx * ctx,napi_value result)305 static void ReturnInitPromiseResult(napi_env env, VerifyInitCtx *ctx, napi_value result)
306 {
307 if (ctx->errCode == HCF_SUCCESS) {
308 napi_resolve_deferred(env, ctx->deferred, result);
309 } else {
310 napi_reject_deferred(env, ctx->deferred,
311 GenerateBusinessError(env, ctx->errCode, ctx->errMsg));
312 }
313 }
314
ReturnUpdateCallbackResult(napi_env env,VerifyUpdateCtx * ctx,napi_value result)315 static void ReturnUpdateCallbackResult(napi_env env, VerifyUpdateCtx *ctx, napi_value result)
316 {
317 napi_value businessError = nullptr;
318 if (ctx->errCode != HCF_SUCCESS) {
319 businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg);
320 }
321
322 napi_value params[ARGS_SIZE_ONE] = { businessError };
323
324 napi_value func = nullptr;
325 napi_get_reference_value(env, ctx->callback, &func);
326
327 napi_value recv = nullptr;
328 napi_value callFuncRet = nullptr;
329 napi_get_undefined(env, &recv);
330 napi_call_function(env, recv, func, ARGS_SIZE_ONE, params, &callFuncRet);
331 }
332
ReturnUpdatePromiseResult(napi_env env,VerifyUpdateCtx * ctx,napi_value result)333 static void ReturnUpdatePromiseResult(napi_env env, VerifyUpdateCtx *ctx, napi_value result)
334 {
335 if (ctx->errCode == HCF_SUCCESS) {
336 napi_resolve_deferred(env, ctx->deferred, result);
337 } else {
338 napi_reject_deferred(env, ctx->deferred,
339 GenerateBusinessError(env, ctx->errCode, ctx->errMsg));
340 }
341 }
342
ReturnDoFinalCallbackResult(napi_env env,VerifyDoFinalCtx * ctx,napi_value result)343 static void ReturnDoFinalCallbackResult(napi_env env, VerifyDoFinalCtx *ctx, napi_value result)
344 {
345 napi_value businessError = nullptr;
346 if (ctx->errCode != HCF_SUCCESS) {
347 businessError = GenerateBusinessError(env, ctx->errCode, ctx->errMsg);
348 }
349
350 napi_value params[ARGS_SIZE_TWO] = { businessError, result };
351
352 napi_value func = nullptr;
353 napi_get_reference_value(env, ctx->callback, &func);
354
355 napi_value recv = nullptr;
356 napi_value callFuncRet = nullptr;
357 napi_get_undefined(env, &recv);
358 napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
359 }
360
ReturnDoFinalPromiseResult(napi_env env,VerifyDoFinalCtx * ctx,napi_value result)361 static void ReturnDoFinalPromiseResult(napi_env env, VerifyDoFinalCtx *ctx, napi_value result)
362 {
363 if (ctx->errCode == HCF_SUCCESS) {
364 napi_resolve_deferred(env, ctx->deferred, result);
365 } else {
366 napi_reject_deferred(env, ctx->deferred,
367 GenerateBusinessError(env, ctx->errCode, ctx->errMsg));
368 }
369 }
370
VerifyJsInitAsyncWorkProcess(napi_env env,void * data)371 void VerifyJsInitAsyncWorkProcess(napi_env env, void *data)
372 {
373 VerifyInitCtx *ctx = static_cast<VerifyInitCtx *>(data);
374
375 ctx->errCode = ctx->verify->init(ctx->verify, ctx->params, ctx->pubKey);
376 if (ctx->errCode != HCF_SUCCESS) {
377 LOGE("verify init fail.");
378 ctx->errMsg = "verify init fail.";
379 }
380 }
381
VerifyJsInitAsyncWorkReturn(napi_env env,napi_status status,void * data)382 void VerifyJsInitAsyncWorkReturn(napi_env env, napi_status status, void *data)
383 {
384 VerifyInitCtx *ctx = static_cast<VerifyInitCtx *>(data);
385
386 if (ctx->asyncType == ASYNC_CALLBACK) {
387 ReturnInitCallbackResult(env, ctx, NapiGetNull(env));
388 } else {
389 ReturnInitPromiseResult(env, ctx, NapiGetNull(env));
390 }
391 FreeVerifyInitCtx(env, ctx);
392 }
393
VerifyJsUpdateAsyncWorkProcess(napi_env env,void * data)394 void VerifyJsUpdateAsyncWorkProcess(napi_env env, void *data)
395 {
396 VerifyUpdateCtx *ctx = static_cast<VerifyUpdateCtx *>(data);
397
398 ctx->errCode = ctx->verify->update(ctx->verify, ctx->data);
399 if (ctx->errCode != HCF_SUCCESS) {
400 LOGE("verify update fail.");
401 ctx->errMsg = "verify update fail.";
402 }
403 }
404
VerifyJsUpdateAsyncWorkReturn(napi_env env,napi_status status,void * data)405 void VerifyJsUpdateAsyncWorkReturn(napi_env env, napi_status status, void *data)
406 {
407 VerifyUpdateCtx *ctx = static_cast<VerifyUpdateCtx *>(data);
408
409 if (ctx->asyncType == ASYNC_CALLBACK) {
410 ReturnUpdateCallbackResult(env, ctx, NapiGetNull(env));
411 } else {
412 ReturnUpdatePromiseResult(env, ctx, NapiGetNull(env));
413 }
414 FreeVerifyUpdateCtx(env, ctx);
415 }
416
VerifyJsDoFinalAsyncWorkProcess(napi_env env,void * data)417 void VerifyJsDoFinalAsyncWorkProcess(napi_env env, void *data)
418 {
419 VerifyDoFinalCtx *ctx = static_cast<VerifyDoFinalCtx *>(data);
420
421 ctx->isVerifySucc = ctx->verify->verify(ctx->verify, ctx->data, ctx->signatureData);
422 ctx->errCode = HCF_SUCCESS;
423 if (!ctx->isVerifySucc) {
424 LOGE("verify doFinal fail.");
425 return;
426 }
427 }
428
VerifyJsDoFinalAsyncWorkReturn(napi_env env,napi_status status,void * data)429 void VerifyJsDoFinalAsyncWorkReturn(napi_env env, napi_status status, void *data)
430 {
431 VerifyDoFinalCtx *ctx = static_cast<VerifyDoFinalCtx *>(data);
432
433 napi_value result = nullptr;
434 if (ctx->errCode == HCF_SUCCESS) {
435 napi_get_boolean(env, ctx->isVerifySucc, &result);
436 }
437
438 if (ctx->asyncType == ASYNC_CALLBACK) {
439 ReturnDoFinalCallbackResult(env, ctx, result);
440 } else {
441 ReturnDoFinalPromiseResult(env, ctx, result);
442 }
443 FreeVerifyDoFinalCtx(env, ctx);
444 }
445
NewVerifyJsInitAsyncWork(napi_env env,VerifyInitCtx * ctx)446 static napi_value NewVerifyJsInitAsyncWork(napi_env env, VerifyInitCtx *ctx)
447 {
448 napi_value resourceName = nullptr;
449 napi_create_string_utf8(env, "init", NAPI_AUTO_LENGTH, &resourceName);
450
451 napi_create_async_work(
452 env, nullptr, resourceName,
453 [](napi_env env, void *data) {
454 VerifyJsInitAsyncWorkProcess(env, data);
455 return;
456 },
457 [](napi_env env, napi_status status, void *data) {
458 VerifyJsInitAsyncWorkReturn(env, status, data);
459 return;
460 },
461 static_cast<void *>(ctx),
462 &ctx->asyncWork);
463
464 napi_queue_async_work(env, ctx->asyncWork);
465 if (ctx->asyncType == ASYNC_PROMISE) {
466 return ctx->promise;
467 } else {
468 return NapiGetNull(env);
469 }
470 }
471
NewVerifyJsUpdateAsyncWork(napi_env env,VerifyUpdateCtx * ctx)472 static napi_value NewVerifyJsUpdateAsyncWork(napi_env env, VerifyUpdateCtx *ctx)
473 {
474 napi_value resourceName = nullptr;
475 napi_create_string_utf8(env, "update", NAPI_AUTO_LENGTH, &resourceName);
476
477 napi_create_async_work(
478 env, nullptr, resourceName,
479 [](napi_env env, void *data) {
480 VerifyJsUpdateAsyncWorkProcess(env, data);
481 return;
482 },
483 [](napi_env env, napi_status status, void *data) {
484 VerifyJsUpdateAsyncWorkReturn(env, status, data);
485 return;
486 },
487 static_cast<void *>(ctx),
488 &ctx->asyncWork);
489
490 napi_queue_async_work(env, ctx->asyncWork);
491 if (ctx->asyncType == ASYNC_PROMISE) {
492 return ctx->promise;
493 } else {
494 return NapiGetNull(env);
495 }
496 }
497
NewVerifyJsDoFinalAsyncWork(napi_env env,VerifyDoFinalCtx * ctx)498 static napi_value NewVerifyJsDoFinalAsyncWork(napi_env env, VerifyDoFinalCtx *ctx)
499 {
500 napi_value resourceName = nullptr;
501 napi_create_string_utf8(env, "verify", NAPI_AUTO_LENGTH, &resourceName);
502
503 napi_create_async_work(
504 env, nullptr, resourceName,
505 [](napi_env env, void *data) {
506 VerifyJsDoFinalAsyncWorkProcess(env, data);
507 return;
508 },
509 [](napi_env env, napi_status status, void *data) {
510 VerifyJsDoFinalAsyncWorkReturn(env, status, data);
511 return;
512 },
513 static_cast<void *>(ctx),
514 &ctx->asyncWork);
515
516 napi_queue_async_work(env, ctx->asyncWork);
517 if (ctx->asyncType == ASYNC_PROMISE) {
518 return ctx->promise;
519 } else {
520 return NapiGetNull(env);
521 }
522 }
523
NapiVerify(HcfVerify * verify)524 NapiVerify::NapiVerify(HcfVerify *verify)
525 {
526 this->verify_ = verify;
527 }
528
~NapiVerify()529 NapiVerify::~NapiVerify()
530 {
531 HcfObjDestroy(this->verify_);
532 }
533
GetVerify()534 HcfVerify *NapiVerify::GetVerify()
535 {
536 return this->verify_;
537 }
538
JsInit(napi_env env,napi_callback_info info)539 napi_value NapiVerify::JsInit(napi_env env, napi_callback_info info)
540 {
541 VerifyInitCtx *ctx = static_cast<VerifyInitCtx *>(HcfMalloc(sizeof(VerifyInitCtx), 0));
542 if (ctx == nullptr) {
543 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail."));
544 LOGE("create context fail.");
545 return nullptr;
546 }
547
548 if (!BuildVerifyJsInitCtx(env, info, ctx)) {
549 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail."));
550 LOGE("build context fail.");
551 FreeVerifyInitCtx(env, ctx);
552 return nullptr;
553 }
554
555 return NewVerifyJsInitAsyncWork(env, ctx);
556 }
557
JsUpdate(napi_env env,napi_callback_info info)558 napi_value NapiVerify::JsUpdate(napi_env env, napi_callback_info info)
559 {
560 VerifyUpdateCtx *ctx = static_cast<VerifyUpdateCtx *>(HcfMalloc(sizeof(VerifyUpdateCtx), 0));
561 if (ctx == nullptr) {
562 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail."));
563 LOGE("create context fail.");
564 return nullptr;
565 }
566
567 if (!BuildVerifyJsUpdateCtx(env, info, ctx)) {
568 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail."));
569 LOGE("build context fail.");
570 FreeVerifyUpdateCtx(env, ctx);
571 return nullptr;
572 }
573
574 return NewVerifyJsUpdateAsyncWork(env, ctx);
575 }
576
JsVerify(napi_env env,napi_callback_info info)577 napi_value NapiVerify::JsVerify(napi_env env, napi_callback_info info)
578 {
579 VerifyDoFinalCtx *ctx = static_cast<VerifyDoFinalCtx *>(HcfMalloc(sizeof(VerifyDoFinalCtx), 0));
580 if (ctx == nullptr) {
581 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "create context fail."));
582 LOGE("create context fail.");
583 return nullptr;
584 }
585
586 if (!BuildVerifyJsDoFinalCtx(env, info, ctx)) {
587 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "build context fail."));
588 LOGE("build context fail.");
589 FreeVerifyDoFinalCtx(env, ctx);
590 return nullptr;
591 }
592
593 return NewVerifyJsDoFinalAsyncWork(env, ctx);
594 }
595
VerifyConstructor(napi_env env,napi_callback_info info)596 napi_value NapiVerify::VerifyConstructor(napi_env env, napi_callback_info info)
597 {
598 napi_value thisVar = nullptr;
599 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
600 return thisVar;
601 }
602
NapiWrapVerify(napi_env env,napi_value instance,NapiVerify * napiVerify)603 static napi_value NapiWrapVerify(napi_env env, napi_value instance, NapiVerify *napiVerify)
604 {
605 napi_status status = napi_wrap(
606 env, instance, napiVerify,
607 [](napi_env env, void *data, void *hint) {
608 NapiVerify *napiVerify = static_cast<NapiVerify *>(data);
609 delete napiVerify;
610 return;
611 }, nullptr, nullptr);
612 if (status != napi_ok) {
613 LOGE("failed to wrap napiVerify obj!");
614 delete napiVerify;
615 napiVerify = nullptr;
616 return nullptr;
617 }
618 return instance;
619 }
620
CreateJsVerify(napi_env env,napi_callback_info info)621 napi_value NapiVerify::CreateJsVerify(napi_env env, napi_callback_info info)
622 {
623 size_t expectedArgc = PARAMS_NUM_ONE;
624 size_t argc = expectedArgc;
625 napi_value argv[PARAMS_NUM_ONE] = { nullptr };
626 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
627
628 if (argc != expectedArgc) {
629 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "The input args num is invalid."));
630 LOGE("The input args num is invalid.");
631 return nullptr;
632 }
633
634 napi_value instance;
635 napi_value constructor = nullptr;
636 napi_get_reference_value(env, classRef_, &constructor);
637 napi_new_instance(env, constructor, argc, argv, &instance);
638
639 std::string algName;
640 if (!GetStringFromJSParams(env, argv[0], algName)) {
641 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get algoName."));
642 LOGE("failed to get algoName.");
643 return nullptr;
644 }
645
646 HcfVerify *verify = nullptr;
647 HcfResult res = HcfVerifyCreate(algName.c_str(), &verify);
648 if (res != HCF_SUCCESS) {
649 napi_throw(env, GenerateBusinessError(env, res, "create c verify fail."));
650 LOGE("create c verify fail.");
651 return nullptr;
652 }
653
654 NapiVerify *napiVerify = new (std::nothrow) NapiVerify(verify);
655 if (napiVerify == nullptr) {
656 napi_throw(env, GenerateBusinessError(env, HCF_ERR_MALLOC, "new napi verify failed"));
657 LOGE("new napi verify failed");
658 HcfObjDestroy(verify);
659 return nullptr;
660 }
661
662 napi_value napiAlgName = nullptr;
663 napi_create_string_utf8(env, algName.c_str(), NAPI_AUTO_LENGTH, &napiAlgName);
664 napi_set_named_property(env, instance, CRYPTO_TAG_ALG_NAME.c_str(), napiAlgName);
665
666 return NapiWrapVerify(env, instance, napiVerify);
667 }
668
669 // verify setVerifySpec(itemType :VerifySpecItem, itemValue : number)
JsSetVerifySpec(napi_env env,napi_callback_info info)670 napi_value NapiVerify::JsSetVerifySpec(napi_env env, napi_callback_info info)
671 {
672 napi_value thisVar = nullptr;
673 NapiVerify *napiVerify = nullptr;
674 size_t expectedArgc = ARGS_SIZE_TWO;
675 size_t argc = ARGS_SIZE_TWO;
676 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
677 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
678 if (argc != expectedArgc) {
679 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num."));
680 LOGE("wrong argument num. require 2 arguments. [Argc]: %zu!", argc);
681 return nullptr;
682 }
683 SignSpecItem item;
684 if (napi_get_value_uint32(env, argv[0], reinterpret_cast<uint32_t *>(&item)) != napi_ok) {
685 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get signSpecItem failed!"));
686 LOGE("get signspecitem failed!");
687 return nullptr;
688 }
689 int32_t saltLen;
690 if (napi_get_value_int32(env, argv[1], &saltLen) != napi_ok) {
691 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get VerifySpec saltLen failed!"));
692 LOGE("get VerifySpec saltLen failed!");
693 return nullptr;
694 }
695 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
696 if (status != napi_ok || napiVerify == nullptr) {
697 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiVerify obj!"));
698 LOGE("failed to unwrap napiVerify obj!");
699 return nullptr;
700 }
701 HcfVerify *verify = napiVerify->GetVerify();
702 HcfResult res = verify->setVerifySpecInt(verify, item, saltLen);
703 if (res != HCF_SUCCESS) {
704 napi_throw(env, GenerateBusinessError(env, res, "c setVerifySpecNumber fail."));
705 LOGE("c setVerifySpecNumber fail.");
706 return nullptr;
707 }
708 return thisVar;
709 }
710
GetVerifySpecString(napi_env env,SignSpecItem item,HcfVerify * verify)711 static napi_value GetVerifySpecString(napi_env env, SignSpecItem item, HcfVerify *verify)
712 {
713 char *returnString = nullptr;
714 HcfResult res = verify->getVerifySpecString(verify, item, &returnString);
715 if (res != HCF_SUCCESS) {
716 napi_throw(env, GenerateBusinessError(env, res, "C getVerifySpecString failed."));
717 LOGE("c getVerifySpecString fail.");
718 return nullptr;
719 }
720
721 napi_value instance = nullptr;
722 napi_create_string_utf8(env, returnString, NAPI_AUTO_LENGTH, &instance);
723 HcfFree(returnString);
724 return instance;
725 }
726
GetVerifySpecNumber(napi_env env,SignSpecItem item,HcfVerify * verify)727 static napi_value GetVerifySpecNumber(napi_env env, SignSpecItem item, HcfVerify *verify)
728 {
729 int returnInt;
730 HcfResult res = verify->getVerifySpecInt(verify, item, &returnInt);
731 if (res != HCF_SUCCESS) {
732 napi_throw(env, GenerateBusinessError(env, res, "C getVerifySpecInt failed."));
733 LOGE("c getVerifySpecInt fail.");
734 return nullptr;
735 }
736
737 napi_value instance = nullptr;
738 napi_create_int32(env, returnInt, &instance);
739 return instance;
740 }
741
JsGetVerifySpec(napi_env env,napi_callback_info info)742 napi_value NapiVerify::JsGetVerifySpec(napi_env env, napi_callback_info info)
743 {
744 napi_value thisVar = nullptr;
745 NapiVerify *napiVerify = nullptr;
746 size_t expectedArgc = ARGS_SIZE_ONE;
747 size_t argc = ARGS_SIZE_ONE;
748 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
749 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
750 if (argc != expectedArgc) {
751 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "init failed for wrong argument num."));
752 LOGE("wrong argument num. require 1 arguments. [Argc]: %zu!", argc);
753 return nullptr;
754 }
755 SignSpecItem item;
756 if (napi_get_value_uint32(env, argv[0], reinterpret_cast<uint32_t *>(&item)) != napi_ok) {
757 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "get getVerifySpecString failed!"));
758 LOGE("get getVerifySpecString failed!");
759 return nullptr;
760 }
761
762 napi_status status = napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiVerify));
763 if (status != napi_ok || napiVerify == nullptr) {
764 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to unwrap napiVerify obj!"));
765 LOGE("failed to unwrap napiVerify obj!");
766 return nullptr;
767 }
768 HcfVerify *verify = napiVerify->GetVerify();
769 if (verify == nullptr) {
770 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "failed to get verify obj!"));
771 LOGE("failed to get verfiy obj!");
772 return nullptr;
773 }
774
775 int32_t type = GetSignSpecType(item);
776 if (type == SPEC_ITEM_TYPE_STR) {
777 return GetVerifySpecString(env, item, verify);
778 } else if (type == SPEC_ITEM_TYPE_NUM) {
779 return GetVerifySpecNumber(env, item, verify);
780 } else {
781 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "VerifySpecItem not support!"));
782 return nullptr;
783 }
784 }
785
DefineVerifyJSClass(napi_env env,napi_value exports)786 void NapiVerify::DefineVerifyJSClass(napi_env env, napi_value exports)
787 {
788 napi_property_descriptor desc[] = {
789 DECLARE_NAPI_FUNCTION("createVerify", NapiVerify::CreateJsVerify),
790 };
791 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
792
793 napi_property_descriptor classDesc[] = {
794 DECLARE_NAPI_FUNCTION("init", NapiVerify::JsInit),
795 DECLARE_NAPI_FUNCTION("update", NapiVerify::JsUpdate),
796 DECLARE_NAPI_FUNCTION("verify", NapiVerify::JsVerify),
797 DECLARE_NAPI_FUNCTION("setVerifySpec", NapiVerify::JsSetVerifySpec),
798 DECLARE_NAPI_FUNCTION("getVerifySpec", NapiVerify::JsGetVerifySpec),
799 };
800 napi_value constructor = nullptr;
801 napi_define_class(env, "Verify", NAPI_AUTO_LENGTH, NapiVerify::VerifyConstructor, nullptr,
802 sizeof(classDesc) / sizeof(classDesc[0]), classDesc, &constructor);
803 napi_create_reference(env, constructor, 1, &classRef_);
804 }
805 } // CryptoFramework
806 } // OHOS
807