• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <string>
17 
18 #include "napi/native_api.h"
19 #include "napi/native_node_api.h"
20 
21 #include "cipher.h"
22 #include "cipher_log.h"
23 #include "securec.h"
24 
25 namespace OHOS::Ace::Napi {
26 namespace {
27 }
28 
29 struct CallbackContext {
30     napi_ref callbackSuccess = nullptr;
31     napi_ref callbackFail = nullptr;
32     napi_ref callbackComplete = nullptr;
33 };
34 
35 struct CommonNapiValue {
36     napi_env env = nullptr;
37     napi_async_work work = nullptr;
38     napi_value action_napi = nullptr;
39     napi_value text_napi = nullptr;
40     napi_value key_napi = nullptr;
41     napi_value transformation_napi = nullptr;
42 };
43 
44 struct RsaAsyncContext {
45     CommonNapiValue *commonNapi = nullptr;
46     CallbackContext *callback = nullptr;
47     RsaKeyData *rsaKey = nullptr;
48     RsaData *textIn = nullptr;
49     RsaData *textOut = nullptr;
50     int32_t ret = 0;
51 };
52 
53 struct AesAsyncContext {
54     CommonNapiValue *commonNapi = nullptr;
55     napi_value iv_napi = nullptr;
56     napi_value ivOffset_napi = nullptr;
57     napi_value ivLen_napi = nullptr;
58     CallbackContext *callback = nullptr;
59     char *key = nullptr;
60     char *textIn = nullptr;
61     char *textOut = nullptr;
62     char *action = nullptr;
63     char *transformation = nullptr;
64     char *ivBuf = nullptr;
65     int32_t ivOffset = 0;
66     int32_t ivLen = 0;
67     int32_t ret = 0;
68 };
69 
70 static const char g_failCode[] = "System error";
71 static const int g_errorCode = 200;
72 static const int g_failArg = 2;
73 static const int g_ivLen = 16;
74 
75 #define SELF_FREE_PTR(PTR, FREE_FUNC) \
76 { \
77     if ((PTR) != nullptr) { \
78         FREE_FUNC(PTR); \
79         (PTR) = nullptr; \
80     } \
81 }
82 
83 #define CIPHER_FREE_PTR(p) SELF_FREE_PTR(p, free)
84 
GetString(napi_env env,napi_value object,char ** element,size_t * len)85 static int32_t GetString(napi_env env, napi_value object, char **element, size_t *len)
86 {
87     napi_valuetype valueType = napi_undefined;
88     napi_status status = napi_typeof(env, object, &valueType);
89     if (status != napi_ok) {
90         return ERROR_CODE_GENERAL;
91     }
92 
93     if (valueType != napi_string) {
94         *element = nullptr;
95         CIPHER_LOG_E("input is not a string-type object");
96         return ERROR_SUCCESS;
97     }
98 
99     status = napi_get_value_string_utf8(env, object, nullptr, 0, len);
100     if (status != napi_ok) {
101         return ERROR_CODE_GENERAL;
102     }
103 
104     *element = (char *)malloc(*len + 1);
105     if (*element == nullptr) {
106         CIPHER_LOG_E("malloc element fail");
107         return ERROR_CODE_GENERAL;
108     }
109     (void)memset_s(*element, *len + 1, 0, *len + 1);
110     size_t result = 0;
111     status = napi_get_value_string_utf8(env, object, *element, *len + 1, &result);
112     if (status != napi_ok) {
113         return ERROR_CODE_GENERAL;
114     }
115     return ERROR_SUCCESS;
116 }
117 
GetCallbackFuncProperty(napi_env env,napi_value object,napi_value * successFunc,napi_value * failFunc,napi_value * completeFunc)118 static int32_t GetCallbackFuncProperty(napi_env env, napi_value object, napi_value *successFunc,
119     napi_value *failFunc, napi_value *completeFunc)
120 {
121     napi_status status = napi_get_named_property(env, object, "success", successFunc);
122     if (status != napi_ok || *successFunc == nullptr) {
123         CIPHER_LOG_E("get success property fail");
124         return ERROR_CODE_GENERAL;
125     }
126     status = napi_get_named_property(env, object, "fail", failFunc);
127     if (status != napi_ok || *failFunc == nullptr) {
128         CIPHER_LOG_E("get fail property fail");
129         return ERROR_CODE_GENERAL;
130     }
131     status = napi_get_named_property(env, object, "complete", completeFunc);
132     if (status != napi_ok || *completeFunc == nullptr) {
133         CIPHER_LOG_E("get complete property fail");
134         return ERROR_CODE_GENERAL;
135     }
136     return ERROR_SUCCESS;
137 }
138 
CreateCallbackReference(napi_env env,napi_value successFunc,napi_value failFunc,napi_value completeFunc,CallbackContext * callback)139 static int32_t CreateCallbackReference(napi_env env, napi_value successFunc, napi_value failFunc,
140     napi_value completeFunc, CallbackContext *callback)
141 {
142     napi_valuetype valueType = napi_undefined;
143     napi_status status = napi_typeof(env, successFunc, &valueType);
144     if (status != napi_ok) {
145         return ERROR_CODE_GENERAL;
146     }
147     if (valueType != napi_function) {
148         return ERROR_CODE_GENERAL;
149     }
150 
151     status = napi_create_reference(env, successFunc, 1, &callback->callbackSuccess);
152     if (status != napi_ok) {
153         CIPHER_LOG_E("create success reference fail");
154         return ERROR_CODE_GENERAL;
155     }
156 
157     status = napi_create_reference(env, failFunc, 1, &callback->callbackFail);
158     if (status != napi_ok) {
159         CIPHER_LOG_E("create fail reference fail");
160         return ERROR_CODE_GENERAL;
161     }
162 
163     status = napi_create_reference(env, completeFunc, 1, &callback->callbackComplete);
164     if (status != napi_ok) {
165         CIPHER_LOG_E("create complete reference fail");
166         return ERROR_CODE_GENERAL;
167     }
168 
169     return ERROR_SUCCESS;
170 }
171 
ReadAesData(napi_env env,AesAsyncContext * context)172 static int32_t ReadAesData(napi_env env, AesAsyncContext *context)
173 {
174     size_t len = 0;
175     int32_t ret = GetString(env, context->commonNapi->action_napi, &context->action, &len);
176     if (ret != ERROR_SUCCESS || context->action == nullptr) {
177         CIPHER_LOG_E("get action fail");
178         return ret;
179     }
180 
181     len = 0;
182     ret = GetString(env, context->commonNapi->text_napi, &context->textIn, &len);
183     if (ret != ERROR_SUCCESS || context->textIn == nullptr) {
184         CIPHER_LOG_E("get text fail");
185         return ret;
186     }
187 
188     len = 0;
189     ret = GetString(env, context->commonNapi->key_napi, &context->key, &len);
190     if (ret != ERROR_SUCCESS || context->key == nullptr) {
191         CIPHER_LOG_E("get key fail");
192         return ret;
193     }
194 
195     len = 0;
196     ret = GetString(env, context->commonNapi->transformation_napi, &context->transformation, &len);
197     if (ret != ERROR_SUCCESS) {
198         CIPHER_LOG_E("get transformition fail");
199         return ret;
200     }
201 
202     (void)context->ivLen_napi;
203     context->ivLen = g_ivLen;
204 
205     len = 0;
206     ret = GetString(env, context->iv_napi, &context->ivBuf, &len);
207     if (ret != ERROR_SUCCESS) {
208         CIPHER_LOG_E("get ivBuf fail");
209         return ret;
210     }
211 
212     (void)context->ivOffset_napi;
213     context->ivOffset = 0;
214     return ret;
215 }
216 
GetCommonProperties(napi_env env,napi_value object,CommonNapiValue * commonNapi)217 static int32_t GetCommonProperties(napi_env env, napi_value object, CommonNapiValue *commonNapi)
218 {
219     napi_status status = napi_get_named_property(env, object, "action", &commonNapi->action_napi);
220     if (status != napi_ok || commonNapi->action_napi == nullptr) {
221         CIPHER_LOG_E("get action property fail");
222         return ERROR_CODE_GENERAL;
223     }
224     status = napi_get_named_property(env, object, "text", &commonNapi->text_napi);
225     if (status != napi_ok || commonNapi->text_napi == nullptr) {
226         CIPHER_LOG_E("get text property fail");
227         return ERROR_CODE_GENERAL;
228     }
229     status = napi_get_named_property(env, object, "key", &commonNapi->key_napi);
230     if (status != napi_ok || commonNapi->key_napi == nullptr) {
231         CIPHER_LOG_E("get key property fail");
232         return ERROR_CODE_GENERAL;
233     }
234     status = napi_get_named_property(env, object, "transformation", &commonNapi->transformation_napi);
235     if (status != napi_ok) {
236         CIPHER_LOG_E("get transformation property fail");
237         return ERROR_CODE_GENERAL;
238     }
239     return ERROR_SUCCESS;
240 }
241 
GetAesProperties(napi_env env,napi_value object,AesAsyncContext * context)242 static int32_t GetAesProperties(napi_env env, napi_value object, AesAsyncContext *context)
243 {
244     int32_t ret = GetCommonProperties(env, object, context->commonNapi);
245     if (ret != ERROR_SUCCESS) {
246         return ret;
247     }
248 
249     napi_status status = napi_get_named_property(env, object, "iv", &context->iv_napi);
250     if (status != napi_ok) {
251         CIPHER_LOG_E("get iv property fail");
252         return ERROR_CODE_GENERAL;
253     }
254     status = napi_get_named_property(env, object, "ivOffset", &context->ivOffset_napi);
255     if (status != napi_ok || context->ivOffset_napi == nullptr) {
256         CIPHER_LOG_E("get ivOffset property fail");
257         return ERROR_CODE_GENERAL;
258     }
259     status = napi_get_named_property(env, object, "ivLen", &context->ivLen_napi);
260     if (status != napi_ok || context->ivLen_napi == nullptr) {
261         CIPHER_LOG_E("get ivLen property fail");
262         return ERROR_CODE_GENERAL;
263     }
264     return ERROR_SUCCESS;
265 }
266 
GetAesInput(napi_env env,napi_value object,AesAsyncContext * context)267 static int32_t GetAesInput(napi_env env, napi_value object, AesAsyncContext *context)
268 {
269     napi_value successFunc = nullptr;
270     napi_value failFunc = nullptr;
271     napi_value completeFunc = nullptr;
272     napi_valuetype valueType = napi_undefined;
273     context->commonNapi = (CommonNapiValue *)malloc(sizeof(struct CommonNapiValue));
274     if (context->commonNapi == nullptr) {
275         return ERROR_CODE_GENERAL;
276     }
277     (void)memset_s(context->commonNapi, sizeof(struct CommonNapiValue), 0, sizeof(struct CommonNapiValue));
278 
279     napi_status status = napi_typeof(env, object, &valueType);
280     if (status != napi_ok) {
281         return ERROR_CODE_GENERAL;
282     }
283     if (valueType != napi_object) {
284         return ERROR_CODE_GENERAL;
285     }
286 
287     int32_t ret = GetAesProperties(env, object, context);
288     if (ret != ERROR_SUCCESS) {
289         return ret;
290     }
291 
292     ret = GetCallbackFuncProperty(env, object, &successFunc, &failFunc, &completeFunc);
293     if (ret != ERROR_SUCCESS) {
294         return ret;
295     }
296 
297     context->callback = (CallbackContext *)malloc(sizeof(struct CallbackContext));
298     if (context->callback == nullptr) {
299         return ERROR_CODE_GENERAL;
300     }
301     (void)memset_s(context->callback, sizeof(struct CallbackContext), 0, sizeof(struct CallbackContext));
302 
303     ret = CreateCallbackReference(env, successFunc, failFunc, completeFunc, context->callback);
304     if (ret != ERROR_SUCCESS) {
305     }
306 
307     return ReadAesData(env, context);
308 }
309 
AesExcute(AesAsyncContext * asyncContext)310 static int32_t AesExcute(AesAsyncContext *asyncContext)
311 {
312     AesCryptContext aes = { { nullptr, nullptr, 0, 0, 0 }, CIPHER_AES_ECB, { nullptr, nullptr, 0, 0 } };
313     AesIvMode iv = { nullptr, nullptr, 0, 0 };
314     iv.ivBuf = asyncContext->ivBuf;
315     iv.ivLen = asyncContext->ivLen;
316     iv.ivOffset = asyncContext->ivOffset;
317     iv.transformation = asyncContext->transformation;
318 
319     int ret = InitAesCryptData(asyncContext->action, asyncContext->textIn, asyncContext->key, &iv, &aes);
320     if (ret != ERROR_SUCCESS) {
321         CIPHER_LOG_E("InitAesCryptData fail, ret is %d", ret);
322         return ret;
323     }
324 
325     ret = AesCrypt(&aes);
326     if (ret != ERROR_SUCCESS) {
327         CIPHER_LOG_E("AesCrypt fail, ret is %d", ret);
328     }
329     asyncContext->textOut = (char *)malloc(strlen(aes.data.text) + 1);
330     if (asyncContext->textOut == nullptr) {
331         DeinitAesCryptData(&aes);
332         return ERROR_CODE_GENERAL;
333     }
334     (void)memset_s(asyncContext->textOut, strlen(aes.data.text) + 1, 0, strlen(aes.data.text) + 1);
335     (void)memcpy_s(asyncContext->textOut, strlen(aes.data.text) + 1, aes.data.text, strlen(aes.data.text));
336     DeinitAesCryptData(&aes);
337 
338     return ret;
339 }
340 
ReadRsaData(napi_env env,RsaAsyncContext * context)341 static int32_t ReadRsaData(napi_env env, RsaAsyncContext *context)
342 {
343     context->rsaKey = (RsaKeyData *)malloc(sizeof(RsaKeyData));
344     if (context->rsaKey == nullptr) {
345         return ERROR_CODE_GENERAL;
346     }
347     (void)memset_s(context->rsaKey, sizeof(RsaKeyData), 0, sizeof(RsaKeyData));
348 
349     context->rsaKey->trans = nullptr;
350     context->textIn = (RsaData *)malloc(sizeof(RsaData));
351     if (context->textIn == nullptr) {
352         return ERROR_CODE_GENERAL;
353     }
354     (void)memset_s(context->textIn, sizeof(RsaData), 0, sizeof(RsaData));
355 
356     context->textOut = (RsaData *)malloc(sizeof(RsaData));
357     if (context->textOut == nullptr) {
358         return ERROR_CODE_GENERAL;
359     }
360     (void)memset_s(context->textOut, sizeof(RsaData), 0, sizeof(RsaData));
361 
362     context->textOut->data = nullptr;
363     context->textOut->length = 0;
364 
365     size_t len = 0;
366     int32_t ret = GetString(env, context->commonNapi->action_napi, &context->rsaKey->action, &len);
367     if (ret != ERROR_SUCCESS || context->rsaKey->action == nullptr) {
368         CIPHER_LOG_E("get action fail");
369         return ret;
370     }
371 
372     ret = GetString(env, context->commonNapi->text_napi, &context->textIn->data, &context->textIn->length);
373     if (ret != ERROR_SUCCESS || context->textIn->data == nullptr) {
374         CIPHER_LOG_E("get textIn fail");
375         return ret;
376     }
377 
378     ret = GetString(env, context->commonNapi->key_napi, &context->rsaKey->key, &context->rsaKey->keyLen);
379     if (ret != ERROR_SUCCESS || context->rsaKey->key == nullptr) {
380         CIPHER_LOG_E("get key fail");
381         return ret;
382     }
383 
384     len = 0;
385     ret = GetString(env, context->commonNapi->transformation_napi, &context->rsaKey->trans, &len);
386     if (ret != ERROR_SUCCESS) {
387         CIPHER_LOG_E("get trans fail");
388     }
389     return ret;
390 }
391 
GetRsaInput(napi_env env,napi_value object,RsaAsyncContext * context)392 static int32_t GetRsaInput(napi_env env, napi_value object, RsaAsyncContext *context)
393 {
394     napi_value successFunc = nullptr;
395     napi_value failFunc = nullptr;
396     napi_value completeFunc = nullptr;
397     napi_valuetype valueType = napi_undefined;
398     context->commonNapi = (CommonNapiValue *)malloc(sizeof(struct CommonNapiValue));
399     if (context->commonNapi == nullptr) {
400         return ERROR_CODE_GENERAL;
401     }
402     (void)memset_s(context->commonNapi, sizeof(struct CommonNapiValue), 0, sizeof(struct CommonNapiValue));
403 
404     napi_status status = napi_typeof(env, object, &valueType);
405     if (status != napi_ok) {
406         return ERROR_CODE_GENERAL;
407     }
408     if (valueType != napi_object) {
409         return ERROR_CODE_GENERAL;
410     }
411 
412     int32_t ret = GetCommonProperties(env, object, context->commonNapi);
413     if (ret != ERROR_SUCCESS) {
414         return ret;
415     }
416 
417     ret = GetCallbackFuncProperty(env, object, &successFunc, &failFunc, &completeFunc);
418     if (ret != ERROR_SUCCESS) {
419         return ret;
420     }
421 
422     context->callback = (CallbackContext *)malloc(sizeof(struct CallbackContext));
423     if (context->callback == nullptr) {
424         return ERROR_CODE_GENERAL;
425     }
426     (void)memset_s(context->callback, sizeof(struct CallbackContext), 0, sizeof(struct CallbackContext));
427 
428     ret = CreateCallbackReference(env, successFunc, failFunc, completeFunc, context->callback);
429     if (ret != ERROR_SUCCESS) {
430     }
431 
432     return ReadRsaData(env, context);
433 }
434 
RsaExcute(RsaAsyncContext * asyncContext)435 static int32_t RsaExcute(RsaAsyncContext *asyncContext)
436 {
437     if ((asyncContext->rsaKey->key == nullptr) || (asyncContext->textIn->data == nullptr)) {
438         return ERROR_CODE_GENERAL;
439     }
440 
441     int32_t ret = RsaCrypt(asyncContext->rsaKey, asyncContext->textIn, asyncContext->textOut);
442     if ((ret != ERROR_SUCCESS) || (asyncContext->textOut->length == 0)) {
443         return ERROR_CODE_GENERAL;
444     }
445 
446     asyncContext->textOut->data = (char *)malloc(asyncContext->textOut->length);
447     if (asyncContext->textOut->data == nullptr) {
448         return ERROR_CODE_GENERAL;
449     }
450     (void)memset_s(asyncContext->textOut->data, asyncContext->textOut->length, 0, asyncContext->textOut->length);
451 
452     ret = RsaCrypt(asyncContext->rsaKey, asyncContext->textIn, asyncContext->textOut);
453     if (ret != ERROR_SUCCESS) {
454         return ret;
455     }
456     return ret;
457 }
458 
SetComplete(napi_env env,CallbackContext * asyncContext)459 void SetComplete(napi_env env, CallbackContext *asyncContext)
460 {
461     napi_value callback = nullptr;
462     napi_value ret = 0;
463     napi_get_reference_value(env, asyncContext->callbackComplete, &callback);
464     napi_call_function(env, nullptr, callback, 0, nullptr, &ret);
465     napi_delete_reference(env, asyncContext->callbackComplete);
466 }
467 
SetSuccess(napi_env env,char * textOut,size_t textLength,CallbackContext * asyncContext)468 void SetSuccess(napi_env env, char *textOut, size_t textLength, CallbackContext *asyncContext)
469 {
470     napi_value callback = nullptr;
471     napi_value ret;
472 
473     napi_value result = nullptr;
474     napi_value returnObj = nullptr;
475     napi_create_object(env, &returnObj);
476     napi_create_string_utf8(env, textOut, textLength, &result);
477     napi_set_named_property(env, returnObj, "text", result);
478 
479     napi_get_reference_value(env, asyncContext->callbackSuccess, &callback);
480     napi_call_function(env, nullptr, callback, 1, &returnObj, &ret);
481     napi_delete_reference(env, asyncContext->callbackSuccess);
482 }
483 
SetFail(napi_env env,CallbackContext * asyncContext)484 void SetFail(napi_env env, CallbackContext *asyncContext)
485 {
486     napi_value callback = nullptr;
487     napi_value ret;
488 
489     napi_value result = nullptr;
490     napi_create_string_utf8(env, g_failCode, sizeof(g_failCode), &result);
491 
492     napi_value errorCode = nullptr;
493     napi_create_int32(env, g_errorCode, &errorCode);
494 
495     napi_value params[g_failArg] = { result, errorCode };
496     napi_get_reference_value(env, asyncContext->callbackFail, &callback);
497     napi_call_function(env, nullptr, callback, g_failArg, params, &ret);
498     napi_delete_reference(env, asyncContext->callbackFail);
499 }
500 
DeleteRsaAsyncContext(napi_env env,RsaAsyncContext * context)501 static void DeleteRsaAsyncContext(napi_env env, RsaAsyncContext *context)
502 {
503     if (context == nullptr) {
504         return;
505     }
506 
507     CIPHER_FREE_PTR(context->commonNapi);
508 
509     CIPHER_FREE_PTR(context->callback);
510 
511     CIPHER_FREE_PTR(context->textIn->data);
512     CIPHER_FREE_PTR(context->textIn);
513 
514     if (context->textOut->data != nullptr) {
515         (void)memset_s(context->textOut->data, context->textOut->length, 0, context->textOut->length);
516     }
517     CIPHER_FREE_PTR(context->textOut->data);
518     CIPHER_FREE_PTR(context->textOut);
519 
520     CIPHER_FREE_PTR(context->rsaKey->trans);
521     CIPHER_FREE_PTR(context->rsaKey->action);
522     if (context->rsaKey->key != nullptr) {
523         (void)memset_s(context->rsaKey->key, context->rsaKey->keyLen, 0, context->rsaKey->keyLen);
524     }
525     CIPHER_FREE_PTR(context->rsaKey->key);
526     CIPHER_FREE_PTR(context->rsaKey);
527 }
528 
DeleteAesAsyncContext(napi_env env,AesAsyncContext * context)529 static void DeleteAesAsyncContext(napi_env env, AesAsyncContext *context)
530 {
531     if (context == nullptr) {
532         return;
533     }
534 
535     CIPHER_FREE_PTR(context->commonNapi);
536 
537     CIPHER_FREE_PTR(context->callback);
538 
539     if (context->key != nullptr) {
540         (void)memset_s(context->key, strlen(context->key), 0, strlen(context->key));
541     }
542     CIPHER_FREE_PTR(context->key);
543     CIPHER_FREE_PTR(context->textIn);
544     CIPHER_FREE_PTR(context->action);
545 
546     CIPHER_FREE_PTR(context->ivBuf);
547     CIPHER_FREE_PTR(context->transformation);
548 
549     if (context->textOut != nullptr) {
550         (void)memset_s(context->textOut, strlen(context->textOut), 0, strlen(context->textOut));
551     }
552     CIPHER_FREE_PTR(context->textOut);
553 }
554 
JSCipherRsa(napi_env env,napi_callback_info info)555 static napi_value JSCipherRsa(napi_env env, napi_callback_info info)
556 {
557     size_t argc = 1;
558     napi_value argv[1] = {0};
559     void *data = nullptr;
560     napi_get_cb_info(env, info, &argc, argv, nullptr, &data);
561     auto rsaAsyncContext = new RsaAsyncContext();
562 
563     rsaAsyncContext->ret = GetRsaInput(env, argv[0], rsaAsyncContext);
564 
565     napi_value resource = nullptr;
566     napi_create_string_utf8(env, "JSCipherRsa", NAPI_AUTO_LENGTH, &resource);
567     napi_create_async_work(
568         env, nullptr, resource,
569         [](napi_env env, void *data) {
570             RsaAsyncContext *asyncContext = (RsaAsyncContext *)data;
571             if (asyncContext->ret == ERROR_SUCCESS) {
572                 asyncContext->ret = RsaExcute(asyncContext);
573             }
574         },
575 
576         [](napi_env env, napi_status status, void *data) {
577             RsaAsyncContext *asyncContext = (RsaAsyncContext *)data;
578             if (asyncContext->ret != ERROR_SUCCESS) {
579                 SetFail(env, asyncContext->callback);
580                 SetComplete(env, asyncContext->callback);
581                 napi_delete_reference(env, asyncContext->callback->callbackSuccess);
582             } else {
583                 SetSuccess(env, asyncContext->textOut->data, asyncContext->textOut->length, asyncContext->callback);
584                 SetComplete(env, asyncContext->callback);
585                 napi_delete_reference(env, asyncContext->callback->callbackFail);
586             }
587             napi_delete_async_work(env, asyncContext->commonNapi->work);
588             DeleteRsaAsyncContext(env, asyncContext);
589             delete asyncContext;
590         },
591         (void *)rsaAsyncContext,
592         &rsaAsyncContext->commonNapi->work);
593         napi_queue_async_work(env, rsaAsyncContext->commonNapi->work);
594         return nullptr;
595 }
596 
JSCipherAes(napi_env env,napi_callback_info info)597 static napi_value JSCipherAes(napi_env env, napi_callback_info info)
598 {
599     size_t argc = 1;
600     napi_value argv[1] = {0};
601     void *data = nullptr;
602     napi_get_cb_info(env, info, &argc, argv, nullptr, &data);
603     auto aesAsyncContext = new AesAsyncContext();
604 
605     aesAsyncContext->ret = GetAesInput(env, argv[0], aesAsyncContext);
606 
607     napi_value resource = nullptr;
608     napi_create_string_utf8(env, "JSCipherAes", NAPI_AUTO_LENGTH, &resource);
609     napi_create_async_work(
610         env, nullptr, resource,
611         [](napi_env env, void *data) {
612             AesAsyncContext *asyncContext = (AesAsyncContext *)data;
613             if (asyncContext->ret == ERROR_SUCCESS) {
614                 asyncContext->ret = AesExcute(asyncContext);
615             }
616         },
617 
618         [](napi_env env, napi_status status, void *data) {
619             AesAsyncContext *asyncContext = (AesAsyncContext *)data;
620             if (asyncContext->ret != ERROR_SUCCESS) {
621                 SetFail(env, asyncContext->callback);
622                 SetComplete(env, asyncContext->callback);
623                 napi_delete_reference(env, asyncContext->callback->callbackSuccess);
624             } else {
625                 SetSuccess(env, asyncContext->textOut, (size_t)(strlen(asyncContext->textOut)),
626                     asyncContext->callback);
627                 SetComplete(env, asyncContext->callback);
628                 napi_delete_reference(env, asyncContext->callback->callbackFail);
629             }
630             napi_delete_async_work(env, asyncContext->commonNapi->work);
631             DeleteAesAsyncContext(env, asyncContext);
632             delete asyncContext;
633         },
634         (void *)aesAsyncContext,
635         &aesAsyncContext->commonNapi->work);
636         napi_queue_async_work(env, aesAsyncContext->commonNapi->work);
637         return nullptr;
638 }
639 
640 
CipherExport(napi_env env,napi_value exports)641 static napi_value CipherExport(napi_env env, napi_value exports)
642 {
643     static napi_property_descriptor cipherDesc[] = {
644         DECLARE_NAPI_FUNCTION("aes", JSCipherAes),
645         DECLARE_NAPI_FUNCTION("rsa", JSCipherRsa),
646     };
647     NAPI_CALL(env, napi_define_properties(
648         env, exports, sizeof(cipherDesc) / sizeof(cipherDesc[0]), cipherDesc));
649     return exports;
650 }
651 
652 static napi_module CipherModule = {
653     .nm_version = 1,
654     .nm_flags = 0,
655     .nm_filename = nullptr,
656     .nm_register_func = CipherExport,
657     .nm_modname = "cipher",
658     .nm_priv = ((void*)0),
659     .reserved = { 0 },
660 };
661 
CipherRegister()662 extern "C" __attribute__((constructor)) void CipherRegister()
663 {
664     napi_module_register(&CipherModule);
665 }
666 }
667