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 "cm_napi_common.h"
17 
18 #include <unordered_map>
19 #include "securec.h"
20 
21 #include "cm_log.h"
22 #include "cm_type.h"
23 
24 namespace CMNapi {
25 namespace {
26 constexpr int CM_MAX_DATA_LEN = 0x6400000; // The maximum length is 100M
27 
28 static const std::string NO_PERMISSION_MSG = "the caller has no permission";
29 static const std::string NOT_SYSTEM_APP_MSG = "the caller is not a system application";
30 static const std::string INVALID_PARAMS_MSG = "the input parameters is invalid";
31 static const std::string GENERIC_MSG = "there is an internal error";
32 static const std::string NO_FOUND_MSG = "the certificate do not exist";
33 static const std::string INCORRECT_FORMAT_MSG = "the input cert data is invalid";
34 static const std::string MAX_CERT_COUNT_REACHED_MSG = "the count of certificates or credentials reach the max";
35 static const std::string NO_AUTHORIZATION_MSG = "the application is not authorized by user";
36 static const std::string ALIAS_LENGTH_REACHED_LIMIT_MSG = "the input alias length reaches the max";
37 static const std::string DEVICE_ENTER_ADVSECMODE_MSG = "the device enters advanced security mode";
38 static const std::string PASSWORD_IS_ERROR_MSG = "the input password is error";
39 
40 static const std::unordered_map<int32_t, int32_t> NATIVE_CODE_TO_JS_CODE_MAP = {
41     // invalid params
42     { CMR_ERROR_INVALID_ARGUMENT, PARAM_ERROR },
43 
44     // no permission
45     { CMR_ERROR_PERMISSION_DENIED, HAS_NO_PERMISSION },
46     { CMR_ERROR_NOT_SYSTEMP_APP, NOT_SYSTEM_APP },
47 
48     { CMR_ERROR_INVALID_CERT_FORMAT, INVALID_CERT_FORMAT },
49     { CMR_ERROR_INSUFFICIENT_DATA, INVALID_CERT_FORMAT },
50     { CMR_ERROR_NOT_FOUND, NOT_FOUND },
51     { CMR_ERROR_NOT_EXIST, NOT_FOUND },
52     { CMR_ERROR_MAX_CERT_COUNT_REACHED, MAX_CERT_COUNT_REACHED },
53     { CMR_ERROR_AUTH_CHECK_FAILED, NO_AUTHORIZATION },
54     { CMR_ERROR_ALIAS_LENGTH_REACHED_LIMIT, ALIAS_LENGTH_REACHED_LIMIT },
55     { CMR_ERROR_DEVICE_ENTER_ADVSECMODE, DEVICE_ENTER_ADVSECMODE },
56     { CMR_ERROR_PASSWORD_IS_ERR, PASSWORD_IS_ERROR },
57 };
58 
59 static const std::unordered_map<int32_t, std::string> NATIVE_CODE_TO_MSG_MAP = {
60     { CMR_ERROR_PERMISSION_DENIED, NO_PERMISSION_MSG },
61     { CMR_ERROR_NOT_SYSTEMP_APP, NOT_SYSTEM_APP_MSG },
62     { CMR_ERROR_INVALID_ARGUMENT, INVALID_PARAMS_MSG },
63     { CMR_ERROR_NOT_FOUND, NO_FOUND_MSG },
64     { CMR_ERROR_NOT_EXIST, NO_FOUND_MSG },
65     { CMR_ERROR_INVALID_CERT_FORMAT, INCORRECT_FORMAT_MSG },
66     { CMR_ERROR_INSUFFICIENT_DATA, INCORRECT_FORMAT_MSG },
67     { CMR_ERROR_MAX_CERT_COUNT_REACHED, MAX_CERT_COUNT_REACHED_MSG },
68     { CMR_ERROR_AUTH_CHECK_FAILED, NO_AUTHORIZATION_MSG },
69     { CMR_ERROR_ALIAS_LENGTH_REACHED_LIMIT, ALIAS_LENGTH_REACHED_LIMIT_MSG },
70     { CMR_ERROR_DEVICE_ENTER_ADVSECMODE, DEVICE_ENTER_ADVSECMODE_MSG },
71 };
72 }  // namespace
73 
ParseUint32(napi_env env,napi_value object,uint32_t & store)74 napi_value ParseUint32(napi_env env, napi_value object, uint32_t &store)
75 {
76     napi_valuetype valueType;
77     napi_typeof(env, object, &valueType);
78     if (valueType != napi_number) {
79         CM_LOG_E("param type is not number");
80         return nullptr;
81     }
82     uint32_t temp = 0;
83     napi_get_value_uint32(env, object, &temp);
84     store = temp;
85     return GetInt32(env, 0);
86 }
87 
ParseBoolean(napi_env env,napi_value object,bool & status)88 napi_value ParseBoolean(napi_env env, napi_value object, bool &status)
89 {
90     napi_valuetype valueType;
91     napi_typeof(env, object, &valueType);
92     if (valueType != napi_boolean) {
93         CM_LOG_E("param type is not bool");
94         return nullptr;
95     }
96     bool temp = false;
97     napi_get_value_bool(env, object, &temp);
98     status = temp;
99     return GetInt32(env, 0);
100 }
101 
ParseCertAlias(napi_env env,napi_value napiObj,CmBlob * & certAlias)102 napi_value ParseCertAlias(napi_env env, napi_value napiObj, CmBlob *&certAlias)
103 {
104     napi_valuetype valueType = napi_undefined;
105     NAPI_CALL(env, napi_typeof(env, napiObj, &valueType));
106     if (valueType != napi_string) {
107         CM_LOG_E("the type of napiObj is not string");
108         return nullptr;
109     }
110     size_t length = 0;
111     napi_status status = napi_get_value_string_utf8(env, napiObj, nullptr, 0, &length);
112     if (status != napi_ok) {
113         GET_AND_THROW_LAST_ERROR((env));
114         CM_LOG_E("Failed to get string length");
115         return nullptr;
116     }
117     if (length > CM_MAX_DATA_LEN) { /* alias can be empty */
118         CM_LOG_E("input alias length is too large, length: %d", length);
119         return nullptr;
120     }
121 
122     char *value = static_cast<char *>(CmMalloc(length + 1));
123     if (value == nullptr) {
124         napi_throw_error(env, nullptr, "could not alloc memory");
125         CM_LOG_E("could not alloc memory");
126         return nullptr;
127     }
128     (void)memset_s(value, length + 1, 0, length + 1);
129 
130     size_t result = 0;
131     status = napi_get_value_string_utf8(env, napiObj, value, length + 1, &result);
132     if (status != napi_ok) {
133         CmFree(value);
134         GET_AND_THROW_LAST_ERROR((env));
135         CM_LOG_E("could not get string");
136         return nullptr;
137     }
138 
139     certAlias = static_cast<CmBlob *>(CmMalloc(sizeof(CmBlob)));
140     if (certAlias == nullptr) {
141         CmFree(value);
142         napi_throw_error(env, nullptr, "could not alloc memory");
143         CM_LOG_E("could not alloc memory");
144         return nullptr;
145     }
146     certAlias->data = reinterpret_cast<uint8_t *>(value);
147     certAlias->size = static_cast<uint32_t>((length + 1) & UINT32_MAX);
148     return GetInt32(env, 0);
149 }
150 
ParseString(napi_env env,napi_value object,CmBlob * & stringBlob)151 napi_value ParseString(napi_env env, napi_value object, CmBlob *&stringBlob)
152 {
153     napi_valuetype valueType = napi_undefined;
154     NAPI_CALL(env, napi_typeof(env, object, &valueType));
155     if (valueType != napi_string) {
156         CM_LOG_E("the type of param is not string");
157         return nullptr;
158     }
159     size_t length = 0;
160     napi_status status = napi_get_value_string_utf8(env, object, nullptr, 0, &length);
161     if (status != napi_ok) {
162         GET_AND_THROW_LAST_ERROR((env));
163         CM_LOG_E("could not get string length");
164         return nullptr;
165     }
166 
167     // add 0 length check
168     if ((length == 0) || (length > CM_MAX_DATA_LEN)) {
169         CM_LOG_E("input string length is 0 or too large, length: %d", length);
170         return nullptr;
171     }
172 
173     char *data = static_cast<char *>(CmMalloc(length + 1));
174     if (data == nullptr) {
175         napi_throw_error(env, nullptr, "could not alloc memory");
176         CM_LOG_E("could not alloc memory");
177         return nullptr;
178     }
179     (void)memset_s(data, length + 1, 0, length + 1);
180 
181     size_t result = 0;
182     status = napi_get_value_string_utf8(env, object, data, length + 1, &result);
183     if (status != napi_ok) {
184         CmFree(data);
185         GET_AND_THROW_LAST_ERROR((env));
186         CM_LOG_E("could not get string");
187         return nullptr;
188     }
189 
190     stringBlob = static_cast<CmBlob *>(CmMalloc(sizeof(CmBlob)));
191     if (stringBlob == nullptr) {
192         CmFree(data);
193         napi_throw_error(env, nullptr, "could not alloc memory");
194         CM_LOG_E("could not alloc memory");
195         return nullptr;
196     }
197     stringBlob->data = reinterpret_cast<uint8_t *>(data);
198     stringBlob->size = static_cast<uint32_t>((length + 1) & UINT32_MAX);
199 
200     return GetInt32(env, 0);
201 }
202 
GetUint8Array(napi_env env,napi_value object,CmBlob & arrayBlob)203 napi_value GetUint8Array(napi_env env, napi_value object, CmBlob &arrayBlob)
204 {
205     napi_typedarray_type arrayType;
206     napi_value arrayBuffer = nullptr;
207     size_t length = 0;
208     size_t offset = 0;
209     void *rawData = nullptr;
210 
211     napi_status status = napi_get_typedarray_info(
212         env, object, &arrayType, &length, static_cast<void **>(&rawData), &arrayBuffer, &offset);
213     if (status != napi_ok) {
214         CM_LOG_E("the type of param is not uint8_array");
215         return nullptr;
216     }
217     if (length > CM_MAX_DATA_LEN) {
218         CM_LOG_E("Data is too large, length = %x", length);
219         return nullptr;
220     }
221     if (length == 0) {
222         CM_LOG_D("The memory length created is only 1 Byte");
223         // The memory length created is only 1 Byte
224         arrayBlob.data = static_cast<uint8_t *>(CmMalloc(1));
225     } else {
226         arrayBlob.data = static_cast<uint8_t *>(CmMalloc(length));
227     }
228     if (arrayBlob.data == nullptr) {
229         CM_LOG_E("Malloc failed");
230         return nullptr;
231     }
232     (void)memset_s(arrayBlob.data, length, 0, length);
233     if (memcpy_s(arrayBlob.data, length, rawData, length) != EOK) {
234         CM_LOG_E("memcpy_s fail, length = %x", length);
235         return nullptr;
236     }
237     arrayBlob.size = static_cast<uint32_t>(length);
238 
239     return GetInt32(env, 0);
240 }
241 
GetCallback(napi_env env,napi_value object)242 napi_ref GetCallback(napi_env env, napi_value object)
243 {
244     napi_valuetype valueType = napi_undefined;
245     napi_status status = napi_typeof(env, object, &valueType);
246     if (status != napi_ok) {
247         CM_LOG_E("could not get object type");
248         return nullptr;
249     }
250 
251     if (valueType != napi_function) {
252         CM_LOG_E("invalid type");
253         return nullptr;
254     }
255 
256     napi_ref ref = nullptr;
257     status = napi_create_reference(env, object, 1, &ref);
258     if (status != napi_ok) {
259         CM_LOG_E("could not create reference");
260         return nullptr;
261     }
262     return ref;
263 }
264 
GetCallback(napi_env env,napi_value object,napi_ref & callback)265 int32_t GetCallback(napi_env env, napi_value object, napi_ref &callback)
266 {
267     napi_valuetype valueType = napi_undefined;
268     napi_status status = napi_typeof(env, object, &valueType);
269     if (status != napi_ok) {
270         CM_LOG_E("could not get object type");
271         return CM_FAILURE;
272     }
273 
274     if (valueType == napi_null || valueType == napi_undefined) {
275         CM_LOG_D("callback is null or undefined, treat as promise");
276         return CM_SUCCESS;
277     }
278 
279     if (valueType != napi_function) {
280         CM_LOG_E("invalid type, not function");
281         return CM_FAILURE;
282     }
283 
284     napi_ref ref = nullptr;
285     status = napi_create_reference(env, object, 1, &ref);
286     if (status != napi_ok) {
287         CM_LOG_E("could not create reference");
288         return CM_FAILURE;
289     }
290     callback = ref;
291     return CM_SUCCESS;
292 }
293 
GenerateAarrayBuffer(napi_env env,uint8_t * data,uint32_t size)294 static napi_value GenerateAarrayBuffer(napi_env env, uint8_t *data, uint32_t size)
295 {
296     uint8_t *buffer = static_cast<uint8_t *>(CmMalloc(size));
297     if (buffer == nullptr) {
298         return nullptr;
299     }
300     (void)memcpy_s(buffer, size, data, size);
301 
302     napi_value outBuffer = nullptr;
303     napi_status status = napi_create_external_arraybuffer(
304         env, buffer, size, [](napi_env env, void *data, void *hint) { CmFree(data); }, nullptr, &outBuffer);
305     if (status == napi_ok) {
306         // free by finalize callback
307         buffer = nullptr;
308     } else {
309         CmFree(buffer);
310         GET_AND_THROW_LAST_ERROR((env));
311     }
312 
313     return outBuffer;
314 }
315 
GenerateCertAbstractArray(napi_env env,const struct CertAbstract * certAbstract,const uint32_t certCount)316 napi_value GenerateCertAbstractArray(napi_env env, const struct CertAbstract *certAbstract, const uint32_t certCount)
317 {
318     if (certCount == 0 || certAbstract == nullptr) {
319         return nullptr;
320     }
321     napi_value array = nullptr;
322     NAPI_CALL(env, napi_create_array(env, &array));
323     for (uint32_t i = 0; i < certCount; i++) {
324         napi_value uri = nullptr;
325         napi_value certAlias = nullptr;
326         napi_value subjectName = nullptr;
327         napi_value status = nullptr;
328 
329         napi_create_string_latin1(env, static_cast<const char *>(certAbstract[i].uri), NAPI_AUTO_LENGTH, &uri);
330         napi_create_string_latin1(env, static_cast<const char *>(certAbstract[i].certAlias),
331             NAPI_AUTO_LENGTH, &certAlias);
332         napi_create_string_latin1(env, static_cast<const char *>(certAbstract[i].subjectName),
333             NAPI_AUTO_LENGTH, &subjectName);
334         napi_get_boolean(env, certAbstract[i].status, &status);
335 
336         napi_value element = nullptr;
337         napi_create_object(env, &element);
338         napi_set_named_property (env, element, CM_CERT_PROPERTY_URI.c_str(), uri);
339         napi_set_named_property (env, element, CM_CERT_PROPERTY_CERTALIAS.c_str(), certAlias);
340         napi_set_named_property (env, element, CM_CERT_PROPERTY_STATUS.c_str(), status);
341         napi_set_named_property (env, element, CM_CERT_PROPERTY_STATE.c_str(), status);
342         napi_set_named_property (env, element, CM_CERT_PROPERTY_SUBJECTNAME.c_str(), subjectName);
343 
344         napi_set_element(env, array, i, element);
345     }
346     return array;
347 }
348 
GenerateCredentialAbstractArray(napi_env env,const struct CredentialAbstract * credentialAbstract,const uint32_t credentialCount)349 napi_value GenerateCredentialAbstractArray(napi_env env,
350     const struct CredentialAbstract *credentialAbstract, const uint32_t credentialCount)
351 {
352     if (credentialCount == 0 || credentialAbstract == nullptr) {
353         return nullptr;
354     }
355     napi_value array = nullptr;
356     NAPI_CALL(env, napi_create_array(env, &array));
357     for (uint32_t i = 0; i < credentialCount; i++) {
358         napi_value type = nullptr;
359         napi_value alias = nullptr;
360         napi_value keyUri = nullptr;
361         napi_create_string_latin1(env, static_cast<const char *>(credentialAbstract[i].type),
362             NAPI_AUTO_LENGTH, &type);
363         napi_create_string_latin1(env, static_cast<const char *>(credentialAbstract[i].alias),
364             NAPI_AUTO_LENGTH, &alias);
365         napi_create_string_latin1(env, static_cast<const char *>(credentialAbstract[i].keyUri),
366             NAPI_AUTO_LENGTH, &keyUri);
367 
368         napi_value element = nullptr;
369         napi_create_object(env, &element);
370         napi_set_named_property (env, element, CM_CERT_PROPERTY_TYPE.c_str(), type);
371         napi_set_named_property (env, element, CM_CERT_PROPERTY_CREDENTIAL_ALIAS.c_str(), alias);
372         napi_set_named_property (env, element, CM_CERT_PROPERTY_KEY_URI.c_str(), keyUri);
373 
374         napi_set_element(env, array, i, element);
375     }
376     return array;
377 }
378 
GenerateCertInfo(napi_env env,const struct CertInfo * certInfo)379 napi_value GenerateCertInfo(napi_env env, const struct CertInfo *certInfo)
380 {
381     if (certInfo == nullptr) {
382         return nullptr;
383     }
384     napi_value result = nullptr;
385     NAPI_CALL(env, napi_create_object(env, &result));
386 
387     struct CertInfoValue cInfVal = { nullptr };
388     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->uri),
389         NAPI_AUTO_LENGTH, &cInfVal.uri));
390     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->certAlias),
391         NAPI_AUTO_LENGTH, &cInfVal.certAlias));
392     NAPI_CALL(env, napi_get_boolean(env, certInfo->status, &cInfVal.status));
393     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->issuerName),
394         NAPI_AUTO_LENGTH, &cInfVal.issuerName));
395     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->subjectName),
396         NAPI_AUTO_LENGTH, &cInfVal.subjectName));
397     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->serial),
398         NAPI_AUTO_LENGTH, &cInfVal.serial));
399     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->notBefore),
400         NAPI_AUTO_LENGTH, &cInfVal.notBefore));
401     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->notAfter),
402         NAPI_AUTO_LENGTH, &cInfVal.notAfter));
403     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->fingerprintSha256),
404         NAPI_AUTO_LENGTH, &cInfVal.fingerprintSha256));
405 
406     napi_value certBuffer = GenerateAarrayBuffer(env, certInfo->certInfo.data, certInfo->certInfo.size);
407     if (certBuffer != nullptr) {
408         NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, certInfo->certInfo.size,
409             certBuffer, 0, &cInfVal.certInfoBlob));
410     }
411 
412     napi_value elem = nullptr;
413     NAPI_CALL(env, napi_create_object(env, &elem));
414     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_URI.c_str(), cInfVal.uri));
415     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_CERTALIAS.c_str(), cInfVal.certAlias));
416     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_STATUS.c_str(), cInfVal.status));
417     NAPI_CALL(env, napi_set_named_property (env, elem, CM_CERT_PROPERTY_STATE.c_str(), cInfVal.status));
418 
419     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_ISSUERNAME.c_str(), cInfVal.issuerName));
420     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_SUBJECTNAME.c_str(), cInfVal.subjectName));
421     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_SERIAL.c_str(), cInfVal.serial));
422     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_BEFORE.c_str(), cInfVal.notBefore));
423     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_AFTER.c_str(), cInfVal.notAfter));
424     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_FINGERSHA256.c_str(),
425         cInfVal.fingerprintSha256));
426     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_CERT_DATA.c_str(), cInfVal.certInfoBlob));
427 
428     return elem;
429 }
430 
GetJsErrorMsg(int32_t errCode)431 static const char *GetJsErrorMsg(int32_t errCode)
432 {
433     auto iter = NATIVE_CODE_TO_MSG_MAP.find(errCode);
434     if (iter != NATIVE_CODE_TO_MSG_MAP.end()) {
435         return (iter->second).c_str();
436     }
437     return GENERIC_MSG.c_str();
438 }
439 
TranformErrorCode(int32_t errorCode)440 int32_t TranformErrorCode(int32_t errorCode)
441 {
442     auto iter = NATIVE_CODE_TO_JS_CODE_MAP.find(errorCode);
443     if (iter != NATIVE_CODE_TO_JS_CODE_MAP.end()) {
444         return iter->second;
445     }
446     return INNER_FAILURE;
447 }
448 
GenerateBusinessError(napi_env env,int32_t errorCode)449 napi_value GenerateBusinessError(napi_env env, int32_t errorCode)
450 {
451     const char *errorMsg = GetJsErrorMsg(errorCode);
452     if (errorMsg == nullptr) {
453         return nullptr;
454     }
455 
456     napi_value businessError = nullptr;
457     NAPI_CALL(env, napi_create_object(env, &businessError));
458 
459     napi_value code = nullptr;
460     int32_t outCode = TranformErrorCode(errorCode);
461     NAPI_CALL(env, napi_create_int32(env, outCode, &code));
462     NAPI_CALL(env, napi_set_named_property(env, businessError, BUSINESS_ERROR_PROPERTY_CODE.c_str(), code));
463     napi_value message = nullptr;
464     NAPI_CALL(env, napi_create_string_utf8(env, errorMsg, NAPI_AUTO_LENGTH, &message));
465     NAPI_CALL(env, napi_set_named_property(env, businessError, BUSINESS_ERROR_PROPERTY_MESSAGE.c_str(), message));
466     return businessError;
467 }
468 
ThrowError(napi_env env,int32_t errorCode,std::string errMsg)469 void ThrowError(napi_env env, int32_t errorCode, std::string errMsg)
470 {
471     napi_value paramsError = nullptr;
472     napi_value code = nullptr;
473     napi_value message = nullptr;
474     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, errorCode, &code));
475     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message));
476     NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &paramsError));
477     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, paramsError, BUSINESS_ERROR_PROPERTY_CODE.c_str(), code));
478     NAPI_CALL_RETURN_VOID(env, napi_throw(env, paramsError));
479 }
480 
GenerateAppCertInfo(napi_env env,const struct Credential * credential)481 napi_value GenerateAppCertInfo(napi_env env, const struct Credential *credential)
482 {
483     if (credential == nullptr) {
484         return nullptr;
485     }
486     napi_value result = nullptr;
487     NAPI_CALL(env, napi_create_object(env, &result));
488     napi_value type = nullptr;
489     napi_value alias = nullptr;
490     napi_value keyUri = nullptr;
491     napi_value certNum = nullptr;
492     napi_value keyNum = nullptr;
493     napi_value credData = nullptr;
494     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(credential->type),
495         NAPI_AUTO_LENGTH, &type));
496     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(credential->alias),
497         NAPI_AUTO_LENGTH, &alias));
498     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(credential->keyUri),
499         NAPI_AUTO_LENGTH, &keyUri));
500 
501     NAPI_CALL(env, napi_create_int32(env, credential->certNum, &certNum));
502     NAPI_CALL(env, napi_create_int32(env, credential->keyNum, &keyNum));
503 
504     napi_value crendentialBuffer = GenerateAarrayBuffer(env, credential->credData.data, credential->credData.size);
505     if (crendentialBuffer != nullptr) {
506         NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, credential->credData.size,
507             crendentialBuffer, 0, &credData));
508     }
509 
510     napi_value element = nullptr;
511     NAPI_CALL(env, napi_create_object(env, &element));
512     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_TYPE.c_str(), type));
513     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CREDENTIAL_ALIAS.c_str(), alias));
514     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_KEY_URI.c_str(), keyUri));
515     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CERT_NUM.c_str(), certNum));
516     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_KEY_NUM.c_str(), keyNum));
517 
518     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CREDENTIAL_DATA.c_str(), credData));
519     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CREDENTIAL_DATA_NEW.c_str(), credData));
520     return element;
521 }
522 
GeneratePromise(napi_env env,napi_deferred deferred,int32_t resultCode,napi_value * result,int32_t arrLength)523 void GeneratePromise(napi_env env, napi_deferred deferred, int32_t resultCode,
524     napi_value *result, int32_t arrLength)
525 {
526     if (arrLength < RESULT_NUMBER) {
527         return;
528     }
529     if (resultCode == CM_SUCCESS) {
530         NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, deferred, result[1]));
531     } else {
532         NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, deferred, result[0]));
533     }
534 }
535 
GenerateCallback(napi_env env,napi_ref callback,napi_value * result,int32_t arrLength,int32_t ret)536 void GenerateCallback(napi_env env, napi_ref callback, napi_value *result, int32_t arrLength, int32_t ret)
537 {
538     napi_value func = nullptr;
539     napi_value returnVal = nullptr;
540     if (arrLength < RESULT_NUMBER) {
541         return;
542     }
543     napi_value businessError = (ret == CM_SUCCESS) ? nullptr : result[0];
544     napi_value params[RESULT_NUMBER] = { businessError, result[1] };
545     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, callback, &func));
546 
547     napi_value recv = nullptr;
548     napi_get_undefined(env, &recv);
549     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, recv, func, RESULT_NUMBER, params, &returnVal));
550 }
551 
GenerateNapiPromise(napi_env env,napi_ref callback,napi_deferred * deferred,napi_value * promise)552 void GenerateNapiPromise(napi_env env, napi_ref callback, napi_deferred *deferred, napi_value *promise)
553 {
554     if (callback == nullptr) {
555         NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, deferred, promise));
556     } else {
557         NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, promise));
558     }
559 }
560 
DeleteNapiContext(napi_env env,napi_async_work & asyncWork,napi_ref & callback)561 void DeleteNapiContext(napi_env env, napi_async_work &asyncWork, napi_ref &callback)
562 {
563     if (asyncWork != nullptr) {
564         napi_delete_async_work(env, asyncWork);
565         asyncWork = nullptr;
566     }
567 
568     if (callback != nullptr) {
569         napi_delete_reference(env, callback);
570         callback = nullptr;
571     }
572 }
573 
FreeCmContext(CmContext * & context)574 void FreeCmContext(CmContext *&context)
575 {
576     if (context == nullptr) {
577         return;
578     }
579 
580     context->userId = 0;
581     context->uid = 0;
582 
583     CmFree(context);
584     context = nullptr;
585 }
586 
FreeCertList(CertList * & certList)587 void FreeCertList(CertList *&certList)
588 {
589     if (certList == nullptr || certList->certAbstract == nullptr) {
590         return;
591     }
592 
593     FreeCertAbstract(certList->certAbstract);
594     certList->certAbstract = nullptr;
595 
596     CmFree(certList);
597     certList = nullptr;
598 }
599 
FreeCredentialList(CredentialList * & credentialList)600 void FreeCredentialList(CredentialList *&credentialList)
601 {
602     if (credentialList == nullptr || credentialList->credentialAbstract == nullptr) {
603         return;
604     }
605 
606     FreeCredentialAbstract(credentialList->credentialAbstract);
607     credentialList->credentialAbstract = nullptr;
608 
609     CmFree(credentialList);
610     credentialList = nullptr;
611 }
612 
FreeCertInfo(CertInfo * & certInfo)613 void FreeCertInfo(CertInfo *&certInfo)
614 {
615     if (certInfo == nullptr) {
616         return;
617     }
618 
619     certInfo->status = false;
620 
621     if (certInfo->certInfo.data != nullptr) {
622         CmFree(certInfo->certInfo.data);
623     }
624 
625     CmFree(certInfo);
626     certInfo = nullptr;
627 }
628 
FreeCredential(Credential * & credential)629 void FreeCredential(Credential *&credential)
630 {
631     if (credential == nullptr) {
632         return;
633     }
634 
635     if (credential->credData.data != nullptr) {
636         CmFree(credential->credData.data);
637     }
638 
639     CmFree(credential);
640     credential = nullptr;
641 }
642 }  // namespace CertManagerNapi
643