1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "cm_napi_sign_verify.h"
17
18 #include "securec.h"
19
20 #include "cert_manager_api.h"
21 #include "cm_log.h"
22 #include "cm_mem.h"
23 #include "cm_type.h"
24 #include "cm_napi_common.h"
25
26 namespace CMNapi {
27 namespace {
28 constexpr int CM_NAPI_INIT_ARGS_CNT = 3;
29 constexpr int CM_NAPI_UPDATE_ARGS_CNT = 3;
30 constexpr int CM_NAPI_FINISH_ARGS_CNT = 3;
31 constexpr int CM_NAPI_ABORT_ARGS_CNT = 2;
32
33 constexpr int CM_NAPI_CALLBACK_ARG_CNT = 1;
34 constexpr int CM_NAPI_SIGNATURE_ARG_CNT = 1;
35
36 constexpr uint32_t OUT_SIGNATURE_SIZE = 1000;
37 constexpr uint32_t OUT_HANLDE_SIZE = 8;
38 } // namespace
39
40 struct SignVerifyAsyncContextT {
41 napi_async_work asyncWork = nullptr;
42 napi_deferred deferred = nullptr;
43 napi_ref callback = nullptr;
44
45 int32_t errCode = 0;
46 bool isSign = false;
47 struct CmBlob *authUri = nullptr;
48 struct CmBlob *handle = nullptr;
49 struct CmBlob *inData = nullptr;
50 struct CmBlob *signature = nullptr;
51 struct CmSignatureSpec *spec = nullptr;
52 };
53 using SignVerifyAsyncContext = SignVerifyAsyncContextT *;
54
InitSignVerifyAsyncContext(void)55 static SignVerifyAsyncContext InitSignVerifyAsyncContext(void)
56 {
57 SignVerifyAsyncContext context = static_cast<SignVerifyAsyncContext>(CmMalloc(sizeof(SignVerifyAsyncContextT)));
58 if (context != nullptr) {
59 (void)memset_s(context, sizeof(SignVerifyAsyncContextT), 0, sizeof(SignVerifyAsyncContextT));
60 }
61 return context;
62 }
63
FreeSignVerifyAsyncContext(napi_env env,SignVerifyAsyncContext & context)64 static void FreeSignVerifyAsyncContext(napi_env env, SignVerifyAsyncContext &context)
65 {
66 if (context == nullptr) {
67 return;
68 }
69
70 DeleteNapiContext(env, context->asyncWork, context->callback);
71 FreeCmBlob(context->authUri);
72 FreeCmBlob(context->handle);
73 FreeCmBlob(context->inData);
74 FreeCmBlob(context->signature);
75 CM_FREE_PTR(context->spec);
76 CM_FREE_PTR(context);
77 }
78
ParseSpec(napi_env env,napi_value object,CmSignatureSpec * & spec)79 static napi_value ParseSpec(napi_env env, napi_value object, CmSignatureSpec *&spec)
80 {
81 napi_valuetype type = napi_undefined;
82 NAPI_CALL(env, napi_typeof(env, object, &type));
83 if (type != napi_object) {
84 CM_LOG_E("type of param spec is not object");
85 return nullptr;
86 }
87
88 napi_value purpose = nullptr;
89 napi_status status = napi_get_named_property(env, object, "purpose", &purpose);
90 if (status != napi_ok || purpose == nullptr) {
91 CM_LOG_E("get purpose failed");
92 return nullptr;
93 }
94
95 NAPI_CALL(env, napi_typeof(env, purpose, &type));
96 if (type != napi_number) {
97 CM_LOG_E("type of param purpose is not number");
98 return nullptr;
99 }
100
101 uint32_t purposeValue = 0;
102 status = napi_get_value_uint32(env, purpose, &purposeValue);
103 if (status != napi_ok) {
104 CM_LOG_E("get purpose value failed");
105 return nullptr;
106 }
107
108 spec = static_cast<CmSignatureSpec *>(CmMalloc(sizeof(CmSignatureSpec)));
109 if (spec == nullptr) {
110 CM_LOG_E("malloc spec struct failed");
111 return nullptr;
112 }
113 spec->purpose = purposeValue;
114 spec->padding = CM_PADDING_PSS;
115 spec->digest = CM_DIGEST_SHA256;
116
117 return GetInt32(env, 0);
118 }
119
GetBlob(napi_env env,napi_value object,CmBlob * & blob)120 static napi_value GetBlob(napi_env env, napi_value object, CmBlob *&blob)
121 {
122 blob = static_cast<CmBlob *>(CmMalloc(sizeof(CmBlob)));
123 if (blob == nullptr) {
124 CM_LOG_E("malloc blob failed");
125 return nullptr;
126 }
127 (void)memset_s(blob, sizeof(CmBlob), 0, sizeof(CmBlob));
128
129 napi_value result = GetUint8Array(env, object, *blob);
130 if (result == nullptr) {
131 CM_LOG_E("parse blob data failed");
132 return nullptr;
133 }
134
135 return GetInt32(env, 0);
136 }
137
ParseCMInitParams(napi_env env,napi_callback_info info,SignVerifyAsyncContext context)138 static napi_value ParseCMInitParams(napi_env env, napi_callback_info info, SignVerifyAsyncContext context)
139 {
140 size_t argc = CM_NAPI_INIT_ARGS_CNT;
141 napi_value argv[CM_NAPI_INIT_ARGS_CNT] = { nullptr };
142 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
143
144 if ((argc != CM_NAPI_INIT_ARGS_CNT) && (argc != (CM_NAPI_INIT_ARGS_CNT - CM_NAPI_CALLBACK_ARG_CNT))) {
145 ThrowParamsError(env, PARAM_ERROR, "init arguments count invalid");
146 CM_LOG_E("init arguments count is not expected");
147 return nullptr;
148 }
149
150 size_t index = 0;
151 napi_value result = ParseString(env, argv[index], context->authUri);
152 if (result == nullptr) {
153 ThrowParamsError(env, PARAM_ERROR, "get authUri type error");
154 CM_LOG_E("get uri failed when using init function");
155 return nullptr;
156 }
157
158 index++;
159 result = ParseSpec(env, argv[index], context->spec);
160 if (result == nullptr) {
161 ThrowParamsError(env, PARAM_ERROR, "get spec type error");
162 CM_LOG_E("get sepc failed when using init function");
163 return nullptr;
164 }
165
166 index++;
167 if (index < argc) {
168 context->callback = GetCallback(env, argv[index]);
169 if (context->callback == nullptr) {
170 ThrowParamsError(env, PARAM_ERROR, "Get callback type error");
171 CM_LOG_E("get callback function failed when using init function");
172 return nullptr;
173 }
174 }
175
176 return GetInt32(env, 0);
177 }
178
ParseCMUpdateParams(napi_env env,napi_callback_info info,SignVerifyAsyncContext context)179 static napi_value ParseCMUpdateParams(napi_env env, napi_callback_info info, SignVerifyAsyncContext context)
180 {
181 size_t argc = CM_NAPI_UPDATE_ARGS_CNT;
182 napi_value argv[CM_NAPI_UPDATE_ARGS_CNT] = { nullptr };
183 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
184
185 if ((argc != CM_NAPI_UPDATE_ARGS_CNT) && (argc != (CM_NAPI_UPDATE_ARGS_CNT - CM_NAPI_CALLBACK_ARG_CNT))) {
186 ThrowParamsError(env, PARAM_ERROR, "update arguments count invalid");
187 CM_LOG_E("update arguments count is not expected");
188 return nullptr;
189 }
190
191 size_t index = 0;
192 napi_value result = GetBlob(env, argv[index], context->handle);
193 if (result == nullptr) {
194 ThrowParamsError(env, PARAM_ERROR, "get handle type error");
195 CM_LOG_E("get handle failed when using update function");
196 return nullptr;
197 }
198
199 index++;
200 result = GetBlob(env, argv[index], context->inData);
201 if (result == nullptr) {
202 ThrowParamsError(env, PARAM_ERROR, "get inData type error");
203 CM_LOG_E("get inData failed when using update function");
204 return nullptr;
205 }
206
207 index++;
208 if (index < argc) {
209 context->callback = GetCallback(env, argv[index]);
210 if (context->callback == nullptr) {
211 ThrowParamsError(env, PARAM_ERROR, "get callback type error");
212 CM_LOG_E("get callback function failed when using update function");
213 return nullptr;
214 }
215 }
216
217 return GetInt32(env, 0);
218 }
219
MallocFinishOutData(napi_env env,SignVerifyAsyncContext context)220 static napi_value MallocFinishOutData(napi_env env, SignVerifyAsyncContext context)
221 {
222 context->signature = static_cast<CmBlob *>(CmMalloc(sizeof(CmBlob)));
223 if (context->signature == nullptr) { /* signature will free after all process */
224 CM_LOG_E("malloc outData failed when process sign finish");
225 ThrowParamsError(env, PARAM_ERROR, "malloc failed");
226 return nullptr;
227 }
228 (void)memset_s(context->signature, sizeof(CmBlob), 0, sizeof(CmBlob));
229
230 uint8_t *data = static_cast<uint8_t *>(CmMalloc(OUT_SIGNATURE_SIZE));
231 if (data == nullptr) {
232 CM_LOG_E("malloc outData.data failed when process sign finish");
233 ThrowParamsError(env, PARAM_ERROR, "malloc failed");
234 return nullptr;
235 }
236 (void)memset_s(data, OUT_SIGNATURE_SIZE, 0, OUT_SIGNATURE_SIZE);
237
238 context->signature->data = data;
239 context->signature->size = OUT_SIGNATURE_SIZE;
240 return GetInt32(env, 0);
241 }
242
ProcessFinishOneParam(napi_env env,SignVerifyAsyncContext context)243 static napi_value ProcessFinishOneParam(napi_env env, SignVerifyAsyncContext context)
244 {
245 /* promise: sign */
246 context->isSign = true;
247 return MallocFinishOutData(env, context);
248 }
249
CheckIsCallback(napi_env env,napi_value object,bool & isFunc)250 static int32_t CheckIsCallback(napi_env env, napi_value object, bool &isFunc)
251 {
252 isFunc = false;
253 napi_valuetype valueType = napi_undefined;
254 napi_status status = napi_typeof(env, object, &valueType);
255 if (status != napi_ok) {
256 CM_LOG_E("could not get object type");
257 return CMR_ERROR_INVALID_ARGUMENT;
258 }
259
260 if (valueType == napi_function) {
261 isFunc = true;
262 }
263 return CM_SUCCESS;
264 }
265
ProcessFinishTwoParam(napi_env env,napi_value * argv,SignVerifyAsyncContext context,size_t curIndex,size_t maxIndex)266 static napi_value ProcessFinishTwoParam(napi_env env, napi_value *argv, SignVerifyAsyncContext context,
267 size_t curIndex, size_t maxIndex)
268 {
269 curIndex++;
270 if (curIndex >= maxIndex) {
271 return nullptr; /* not possible */
272 }
273
274 /*
275 * check wether arg 2 is callback: if true, get callback function and return: callback sign.
276 * else is promise verify, then get arg 2 as signature
277 */
278 bool isFunc = false;
279 int32_t ret = CheckIsCallback(env, argv[curIndex], isFunc);
280 if (ret != CM_SUCCESS) {
281 return nullptr;
282 }
283
284 napi_value result = nullptr;
285 if (isFunc) {
286 /* callback: sign */
287 context->isSign = true;
288 result = MallocFinishOutData(env, context);
289 if (result == nullptr) {
290 return nullptr;
291 }
292
293 context->callback = GetCallback(env, argv[curIndex]); /* return if arg 2 is callback */
294 if (context->callback == nullptr) {
295 ThrowParamsError(env, PARAM_ERROR, "sign: get callback type error");
296 CM_LOG_E("arg2 is callback: get sign callback function failed when using finish function");
297 return nullptr;
298 }
299 return GetInt32(env, 0);
300 }
301
302 /* promise verify */
303 context->isSign = false;
304 result = GetBlob(env, argv[curIndex], context->signature);
305 if (result == nullptr) {
306 ThrowParamsError(env, PARAM_ERROR, "get signature type error");
307 CM_LOG_E("get signature failed when process promise verify");
308 return nullptr;
309 }
310
311 return GetInt32(env, 0);
312 }
313
ProcessFinishThreeParam(napi_env env,napi_value * argv,SignVerifyAsyncContext context,size_t curIndex,size_t maxIndex)314 static napi_value ProcessFinishThreeParam(napi_env env, napi_value *argv, SignVerifyAsyncContext context,
315 size_t curIndex, size_t maxIndex)
316 {
317 /* callback: verify */
318 context->isSign = false;
319
320 curIndex++;
321 if (curIndex >= maxIndex) {
322 return nullptr; /* not possible */
323 }
324
325 napi_value result = GetBlob(env, argv[curIndex], context->signature);
326 if (result == nullptr) {
327 ThrowParamsError(env, PARAM_ERROR, "get signature type error");
328 CM_LOG_E("get signature failed when process callback verify");
329 return nullptr;
330 }
331
332 curIndex++;
333 if (curIndex >= maxIndex) {
334 return nullptr; /* not possible */
335 }
336
337 context->callback = GetCallback(env, argv[curIndex]);
338 if (context->callback == nullptr) {
339 ThrowParamsError(env, PARAM_ERROR, "verify: get callback type error");
340 CM_LOG_E("get verify callback function failed when using finish function");
341 return nullptr;
342 }
343
344 return GetInt32(env, 0);
345 }
346
ParseCMFinishParams(napi_env env,napi_callback_info info,SignVerifyAsyncContext context)347 static napi_value ParseCMFinishParams(napi_env env, napi_callback_info info, SignVerifyAsyncContext context)
348 {
349 size_t argc = CM_NAPI_FINISH_ARGS_CNT;
350 napi_value argv[CM_NAPI_FINISH_ARGS_CNT] = { nullptr };
351 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
352
353 if ((argc != CM_NAPI_FINISH_ARGS_CNT) && (argc != (CM_NAPI_FINISH_ARGS_CNT - CM_NAPI_CALLBACK_ARG_CNT)) &&
354 (argc != (CM_NAPI_FINISH_ARGS_CNT - CM_NAPI_CALLBACK_ARG_CNT - CM_NAPI_SIGNATURE_ARG_CNT))) {
355 ThrowParamsError(env, PARAM_ERROR, "finish arguments count invalid");
356 CM_LOG_E("finish arguments count is not expected");
357 return nullptr;
358 }
359
360 size_t index = 0;
361 napi_value result = GetBlob(env, argv[index], context->handle);
362 if (result == nullptr) {
363 ThrowParamsError(env, PARAM_ERROR, "get handle type error");
364 CM_LOG_E("get handle failed when using finish function");
365 return nullptr;
366 }
367
368 if (argc == CM_NAPI_FINISH_ARGS_CNT) {
369 return ProcessFinishThreeParam(env, argv, context, index, argc);
370 } else if (argc == (CM_NAPI_FINISH_ARGS_CNT - CM_NAPI_CALLBACK_ARG_CNT)) {
371 return ProcessFinishTwoParam(env, argv, context, index, argc);
372 } else {
373 /* only this 3 types */
374 return ProcessFinishOneParam(env, context);
375 }
376 }
377
ParseCMAbortParams(napi_env env,napi_callback_info info,SignVerifyAsyncContext context)378 static napi_value ParseCMAbortParams(napi_env env, napi_callback_info info, SignVerifyAsyncContext context)
379 {
380 size_t argc = CM_NAPI_ABORT_ARGS_CNT;
381 napi_value argv[CM_NAPI_ABORT_ARGS_CNT] = { nullptr };
382 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
383
384 if ((argc != CM_NAPI_ABORT_ARGS_CNT) && (argc != (CM_NAPI_ABORT_ARGS_CNT - CM_NAPI_CALLBACK_ARG_CNT))) {
385 ThrowParamsError(env, PARAM_ERROR, "abort arguments count invalid");
386 CM_LOG_E("abort arguments count is not expected");
387 return nullptr;
388 }
389
390 size_t index = 0;
391 napi_value result = GetBlob(env, argv[index], context->handle);
392 if (result == nullptr) {
393 ThrowParamsError(env, PARAM_ERROR, "get handle type error");
394 CM_LOG_E("get handle failed when using abort function");
395 return nullptr;
396 }
397
398 index++;
399 if (index < argc) {
400 context->callback = GetCallback(env, argv[index]);
401 if (context->callback == nullptr) {
402 ThrowParamsError(env, PARAM_ERROR, "get callback type error");
403 CM_LOG_E("get callback function failed when using abort function");
404 return nullptr;
405 }
406 }
407
408 return GetInt32(env, 0);
409 }
410
InitExecute(napi_env env,void * data)411 static void InitExecute(napi_env env, void *data)
412 {
413 SignVerifyAsyncContext context = static_cast<SignVerifyAsyncContext>(data);
414 context->handle = static_cast<CmBlob *>(CmMalloc(sizeof(CmBlob)));
415 if (context->handle == nullptr) {
416 CM_LOG_E("malloc handle out failed");
417 context->errCode = CMR_ERROR_MALLOC_FAIL;
418 return;
419 }
420 (void)memset_s(context->handle, sizeof(CmBlob), 0, sizeof(CmBlob));
421
422 context->handle->data = static_cast<uint8_t *>(CmMalloc(OUT_HANLDE_SIZE));
423 if (context->handle->data == nullptr) {
424 CM_LOG_E("malloc handle.data failed");
425 context->errCode = CMR_ERROR_MALLOC_FAIL;
426 return;
427 }
428 (void)memset_s(context->handle->data, OUT_HANLDE_SIZE, 0, OUT_HANLDE_SIZE);
429 context->handle->size = OUT_HANLDE_SIZE;
430
431 context->errCode = CmInit(context->authUri, context->spec, context->handle);
432 }
433
GenerateArrayBuffer(napi_env env,uint8_t * data,uint32_t size)434 static napi_value GenerateArrayBuffer(napi_env env, uint8_t *data, uint32_t size)
435 {
436 uint8_t *tempBuf = static_cast<uint8_t *>(CmMalloc(size));
437 if (tempBuf == nullptr) {
438 CM_LOG_E("malloc outbuf failed");
439 return nullptr;
440 }
441 (void)memcpy_s(tempBuf, size, data, size);
442
443 napi_value outBuffer = nullptr;
444 napi_status status = napi_create_external_arraybuffer(
445 env, tempBuf, size, [](napi_env env, void *data, void *hint) { CmFree(data); }, nullptr, &outBuffer);
446 if (status == napi_ok) {
447 tempBuf = nullptr; /* free by finalize callback */
448 } else {
449 CM_LOG_E("create external array buffer failed");
450 CM_FREE_PTR(tempBuf);
451 GET_AND_THROW_LAST_ERROR((env));
452 }
453
454 return outBuffer;
455 }
456
ConvertResultHandle(napi_env env,const CmBlob * handle)457 static napi_value ConvertResultHandle(napi_env env, const CmBlob *handle)
458 {
459 napi_value result = nullptr;
460 NAPI_CALL(env, napi_create_object(env, &result));
461
462 napi_value handleNapi = nullptr;
463 napi_value handleBuf = GenerateArrayBuffer(env, handle->data, handle->size);
464 if (handleBuf != nullptr) {
465 NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, handle->size, handleBuf, 0, &handleNapi));
466 } else {
467 handleNapi = GetNull(env);
468 }
469 NAPI_CALL(env, napi_set_named_property(env, result, "handle", handleNapi));
470
471 return result;
472 }
473
InitComplete(napi_env env,napi_status status,void * data)474 static void InitComplete(napi_env env, napi_status status, void *data)
475 {
476 SignVerifyAsyncContext context = static_cast<SignVerifyAsyncContext>(data);
477 napi_value result[RESULT_NUMBER] = { nullptr };
478 if (context->errCode == CM_SUCCESS) {
479 napi_create_uint32(env, 0, &result[0]);
480 result[1] = ConvertResultHandle(env, context->handle);
481 } else {
482 result[0] = GenerateBusinessError(env, context->errCode, "init failed");
483 napi_get_undefined(env, &result[1]);
484 }
485
486 if (context->deferred != nullptr) {
487 GeneratePromise(env, context->deferred, context->errCode, result, sizeof(result));
488 } else {
489 GenerateCallback(env, context->callback, result, sizeof(result));
490 }
491 FreeSignVerifyAsyncContext(env, context);
492 }
493
UpdateExecute(napi_env env,void * data)494 static void UpdateExecute(napi_env env, void *data)
495 {
496 SignVerifyAsyncContext context = static_cast<SignVerifyAsyncContext>(data);
497 context->errCode = CmUpdate(context->handle, context->inData);
498 }
499
UpdateOrAbortComplete(napi_env env,napi_status status,void * data)500 static void UpdateOrAbortComplete(napi_env env, napi_status status, void *data)
501 {
502 SignVerifyAsyncContext context = static_cast<SignVerifyAsyncContext>(data);
503 napi_value result[RESULT_NUMBER] = { nullptr };
504 if (context->errCode == CM_SUCCESS) {
505 napi_create_uint32(env, 0, &result[0]);
506 napi_get_boolean(env, true, &result[1]);
507 } else {
508 result[0] = GenerateBusinessError(env, context->errCode, "update or abort process failed");
509 napi_get_undefined(env, &result[1]);
510 }
511
512 if (context->deferred != nullptr) {
513 GeneratePromise(env, context->deferred, context->errCode, result, sizeof(result));
514 } else {
515 GenerateCallback(env, context->callback, result, sizeof(result));
516 }
517 FreeSignVerifyAsyncContext(env, context);
518 }
519
FinishExecute(napi_env env,void * data)520 static void FinishExecute(napi_env env, void *data)
521 {
522 SignVerifyAsyncContext context = static_cast<SignVerifyAsyncContext>(data);
523 if (context->isSign) {
524 CmBlob inData = { 0, nullptr };
525 context->errCode = CmFinish(context->handle, &inData, context->signature);
526 return;
527 }
528
529 CmBlob outData = { 0, nullptr };
530 context->errCode = CmFinish(context->handle, context->signature, &outData);
531 }
532
ConvertResultSignature(napi_env env,bool isSign,const CmBlob * sign)533 static napi_value ConvertResultSignature(napi_env env, bool isSign, const CmBlob *sign)
534 {
535 napi_value result = nullptr;
536 NAPI_CALL(env, napi_create_object(env, &result));
537
538 napi_value signResultNapi = nullptr;
539 if (isSign) {
540 napi_value signBuf = GenerateArrayBuffer(env, sign->data, sign->size);
541 if (signBuf != nullptr) {
542 NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, sign->size, signBuf, 0, &signResultNapi));
543 } else {
544 signResultNapi = GetNull(env);
545 }
546 } else {
547 signResultNapi = GetNull(env);
548 }
549 NAPI_CALL(env, napi_set_named_property(env, result, "outData", signResultNapi));
550
551 return result;
552 }
553
FinishComplete(napi_env env,napi_status status,void * data)554 static void FinishComplete(napi_env env, napi_status status, void *data)
555 {
556 SignVerifyAsyncContext context = static_cast<SignVerifyAsyncContext>(data);
557 napi_value result[RESULT_NUMBER] = { nullptr };
558 if (context->errCode == CM_SUCCESS) {
559 napi_create_uint32(env, 0, &result[0]);
560 result[1] = ConvertResultSignature(env, context->isSign, context->signature);
561 } else {
562 result[0] = GenerateBusinessError(env, context->errCode, "finish failed");
563 napi_get_undefined(env, &result[1]);
564 }
565
566 if (context->deferred != nullptr) {
567 GeneratePromise(env, context->deferred, context->errCode, result, sizeof(result));
568 } else {
569 GenerateCallback(env, context->callback, result, sizeof(result));
570 }
571 FreeSignVerifyAsyncContext(env, context);
572 }
573
AbortExecute(napi_env env,void * data)574 static void AbortExecute(napi_env env, void *data)
575 {
576 SignVerifyAsyncContext context = static_cast<SignVerifyAsyncContext>(data);
577 context->errCode = CmAbort(context->handle);
578 }
579
CMInitAsyncWork(napi_env env,SignVerifyAsyncContext context)580 static napi_value CMInitAsyncWork(napi_env env, SignVerifyAsyncContext context)
581 {
582 napi_value promise = nullptr;
583 GenerateNapiPromise(env, context->callback, &context->deferred, &promise);
584
585 napi_value resourceName = nullptr;
586 NAPI_CALL(env, napi_create_string_latin1(env, "cminit", NAPI_AUTO_LENGTH, &resourceName));
587
588 NAPI_CALL(env, napi_create_async_work(
589 env, nullptr, resourceName,
590 InitExecute,
591 InitComplete,
592 static_cast<void *>(context),
593 &context->asyncWork));
594
595 napi_status status = napi_queue_async_work(env, context->asyncWork);
596 if (status != napi_ok) {
597 ThrowParamsError(env, PARAM_ERROR, "queue async work error");
598 CM_LOG_E("queue async work failed when using init function");
599 return nullptr;
600 }
601 return promise;
602 }
603
CMUpdateAsyncWork(napi_env env,SignVerifyAsyncContext context)604 static napi_value CMUpdateAsyncWork(napi_env env, SignVerifyAsyncContext context)
605 {
606 napi_value promise = nullptr;
607 GenerateNapiPromise(env, context->callback, &context->deferred, &promise);
608
609 napi_value resourceName = nullptr;
610 NAPI_CALL(env, napi_create_string_latin1(env, "cmupdate", NAPI_AUTO_LENGTH, &resourceName));
611
612 NAPI_CALL(env, napi_create_async_work(
613 env, nullptr, resourceName,
614 UpdateExecute,
615 UpdateOrAbortComplete,
616 static_cast<void *>(context),
617 &context->asyncWork));
618
619 napi_status status = napi_queue_async_work(env, context->asyncWork);
620 if (status != napi_ok) {
621 ThrowParamsError(env, PARAM_ERROR, "queue async work error");
622 CM_LOG_E("queue async work failed when using update function");
623 return nullptr;
624 }
625 return promise;
626 }
627
CMFinishAsyncWork(napi_env env,SignVerifyAsyncContext context)628 static napi_value CMFinishAsyncWork(napi_env env, SignVerifyAsyncContext context)
629 {
630 napi_value promise = nullptr;
631 GenerateNapiPromise(env, context->callback, &context->deferred, &promise);
632
633 napi_value resourceName = nullptr;
634 NAPI_CALL(env, napi_create_string_latin1(env, "cmfinish", NAPI_AUTO_LENGTH, &resourceName));
635
636 NAPI_CALL(env, napi_create_async_work(
637 env, nullptr, resourceName,
638 FinishExecute,
639 FinishComplete,
640 static_cast<void *>(context),
641 &context->asyncWork));
642
643 napi_status status = napi_queue_async_work(env, context->asyncWork);
644 if (status != napi_ok) {
645 ThrowParamsError(env, PARAM_ERROR, "queue async work error");
646 CM_LOG_E("queue async work failed when using finish function");
647 return nullptr;
648 }
649 return promise;
650 }
651
CMAbortAsyncWork(napi_env env,SignVerifyAsyncContext context)652 static napi_value CMAbortAsyncWork(napi_env env, SignVerifyAsyncContext context)
653 {
654 napi_value promise = nullptr;
655 GenerateNapiPromise(env, context->callback, &context->deferred, &promise);
656
657 napi_value resourceName = nullptr;
658 NAPI_CALL(env, napi_create_string_latin1(env, "cmabort", NAPI_AUTO_LENGTH, &resourceName));
659
660 NAPI_CALL(env, napi_create_async_work(
661 env, nullptr, resourceName,
662 AbortExecute,
663 UpdateOrAbortComplete,
664 static_cast<void *>(context),
665 &context->asyncWork));
666
667 napi_status status = napi_queue_async_work(env, context->asyncWork);
668 if (status != napi_ok) {
669 ThrowParamsError(env, PARAM_ERROR, "queue async work error");
670 CM_LOG_E("queue async work failed when using abort function");
671 return nullptr;
672 }
673 return promise;
674 }
675
CMNapiInit(napi_env env,napi_callback_info info)676 napi_value CMNapiInit(napi_env env, napi_callback_info info)
677 {
678 SignVerifyAsyncContext context = InitSignVerifyAsyncContext();
679 if (context == nullptr) {
680 CM_LOG_E("init cm init context failed");
681 return nullptr;
682 }
683
684 napi_value result = ParseCMInitParams(env, info, context);
685 if (result == nullptr) {
686 CM_LOG_E("parse cm init params failed");
687 FreeSignVerifyAsyncContext(env, context);
688 return nullptr;
689 }
690
691 result = CMInitAsyncWork(env, context);
692 if (result == nullptr) {
693 CM_LOG_E("start cm init async work failed");
694 FreeSignVerifyAsyncContext(env, context);
695 return nullptr;
696 }
697
698 return result;
699 }
700
CMNapiUpdate(napi_env env,napi_callback_info info)701 napi_value CMNapiUpdate(napi_env env, napi_callback_info info)
702 {
703 SignVerifyAsyncContext context = InitSignVerifyAsyncContext();
704 if (context == nullptr) {
705 CM_LOG_E("init cm update context failed");
706 return nullptr;
707 }
708
709 napi_value result = ParseCMUpdateParams(env, info, context);
710 if (result == nullptr) {
711 CM_LOG_E("parse cm update params failed");
712 FreeSignVerifyAsyncContext(env, context);
713 return nullptr;
714 }
715
716 result = CMUpdateAsyncWork(env, context);
717 if (result == nullptr) {
718 CM_LOG_E("start cm update async work failed");
719 FreeSignVerifyAsyncContext(env, context);
720 return nullptr;
721 }
722
723 return result;
724 }
725
CMNapiFinish(napi_env env,napi_callback_info info)726 napi_value CMNapiFinish(napi_env env, napi_callback_info info)
727 {
728 SignVerifyAsyncContext context = InitSignVerifyAsyncContext();
729 if (context == nullptr) {
730 CM_LOG_E("init cm finish context failed");
731 return nullptr;
732 }
733
734 napi_value result = ParseCMFinishParams(env, info, context);
735 if (result == nullptr) {
736 CM_LOG_E("parse cm finish params failed");
737 FreeSignVerifyAsyncContext(env, context);
738 return nullptr;
739 }
740
741 result = CMFinishAsyncWork(env, context);
742 if (result == nullptr) {
743 CM_LOG_E("start cm finish async work failed");
744 FreeSignVerifyAsyncContext(env, context);
745 return nullptr;
746 }
747
748 return result;
749 }
750
CMNapiAbort(napi_env env,napi_callback_info info)751 napi_value CMNapiAbort(napi_env env, napi_callback_info info)
752 {
753 SignVerifyAsyncContext context = InitSignVerifyAsyncContext();
754 if (context == nullptr) {
755 CM_LOG_E("init cm abort context failed");
756 return nullptr;
757 }
758
759 napi_value result = ParseCMAbortParams(env, info, context);
760 if (result == nullptr) {
761 CM_LOG_E("parse cm abort params failed");
762 FreeSignVerifyAsyncContext(env, context);
763 return nullptr;
764 }
765
766 result = CMAbortAsyncWork(env, context);
767 if (result == nullptr) {
768 CM_LOG_E("start cm abort async work failed");
769 FreeSignVerifyAsyncContext(env, context);
770 return nullptr;
771 }
772
773 return result;
774 }
775 } // namespace CMNapi
776
777