• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2025 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 NO_FOUND_MSG = "the certificate do not exist";
32 static const std::string INCORRECT_FORMAT_MSG = "the input cert data is invalid";
33 static const std::string MAX_CERT_COUNT_REACHED_MSG = "the count of certificates or credentials reach the max";
34 static const std::string NO_AUTHORIZATION_MSG = "the application is not authorized by user";
35 static const std::string ALIAS_LENGTH_REACHED_LIMIT_MSG = "the input alias length reaches the max";
36 static const std::string DEVICE_ENTER_ADVSECMODE_MSG = "the device enters advanced security mode";
37 static const std::string PASSWORD_IS_ERROR_MSG = "the input password is error";
38 
39 static const std::unordered_map<int32_t, int32_t> NATIVE_CODE_TO_JS_CODE_MAP = {
40     // invalid params
41     { CMR_ERROR_INVALID_ARGUMENT, PARAM_ERROR },
42 
43     // no permission
44     { CMR_ERROR_PERMISSION_DENIED, HAS_NO_PERMISSION },
45     { CMR_ERROR_NOT_SYSTEMP_APP, NOT_SYSTEM_APP },
46 
47     { CMR_ERROR_INVALID_CERT_FORMAT, INVALID_CERT_FORMAT },
48     { CMR_ERROR_INSUFFICIENT_DATA, INVALID_CERT_FORMAT },
49     { CMR_ERROR_NOT_FOUND, NOT_FOUND },
50     { CMR_ERROR_NOT_EXIST, NOT_FOUND },
51     { CMR_ERROR_MAX_CERT_COUNT_REACHED, MAX_CERT_COUNT_REACHED },
52     { CMR_ERROR_AUTH_CHECK_FAILED, NO_AUTHORIZATION },
53     { CMR_ERROR_ALIAS_LENGTH_REACHED_LIMIT, ALIAS_LENGTH_REACHED_LIMIT },
54     { CMR_ERROR_DEVICE_ENTER_ADVSECMODE, DEVICE_ENTER_ADVSECMODE },
55     { CMR_ERROR_PASSWORD_IS_ERR, PASSWORD_IS_ERROR },
56 };
57 
58 static const std::unordered_map<int32_t, std::string> NATIVE_CODE_TO_MSG_MAP = {
59     { CMR_ERROR_PERMISSION_DENIED, NO_PERMISSION_MSG },
60     { CMR_ERROR_NOT_SYSTEMP_APP, NOT_SYSTEM_APP_MSG },
61     { CMR_ERROR_INVALID_ARGUMENT, INVALID_PARAMS_MSG },
62     { CMR_ERROR_NOT_FOUND, NO_FOUND_MSG },
63     { CMR_ERROR_NOT_EXIST, NO_FOUND_MSG },
64     { CMR_ERROR_INVALID_CERT_FORMAT, INCORRECT_FORMAT_MSG },
65     { CMR_ERROR_INSUFFICIENT_DATA, INCORRECT_FORMAT_MSG },
66     { CMR_ERROR_MAX_CERT_COUNT_REACHED, MAX_CERT_COUNT_REACHED_MSG },
67     { CMR_ERROR_AUTH_CHECK_FAILED, NO_AUTHORIZATION_MSG },
68     { CMR_ERROR_ALIAS_LENGTH_REACHED_LIMIT, ALIAS_LENGTH_REACHED_LIMIT_MSG },
69     { CMR_ERROR_DEVICE_ENTER_ADVSECMODE, DEVICE_ENTER_ADVSECMODE_MSG },
70     { CMR_ERROR_PASSWORD_IS_ERR, PASSWORD_IS_ERROR_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 
ParseStringCommon(napi_env env,napi_value object,CmBlob * & stringBlob,bool canBeEmpty)151 static napi_value ParseStringCommon(napi_env env, napi_value object, CmBlob *&stringBlob, bool canBeEmpty)
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 max length check
168     if (length > CM_MAX_DATA_LEN) {
169         CM_LOG_E("input string length is too large, length: %d", length);
170         return nullptr;
171     }
172     // add 0 length check
173     if (!canBeEmpty && length == 0) {
174         CM_LOG_E("input string length is 0");
175         return nullptr;
176     }
177 
178     char *data = static_cast<char *>(CmMalloc(length + 1));
179     if (data == nullptr) {
180         napi_throw_error(env, nullptr, "could not alloc memory");
181         CM_LOG_E("could not alloc memory");
182         return nullptr;
183     }
184     (void)memset_s(data, length + 1, 0, length + 1);
185 
186     size_t result = 0;
187     status = napi_get_value_string_utf8(env, object, data, length + 1, &result);
188     if (status != napi_ok) {
189         CmFree(data);
190         GET_AND_THROW_LAST_ERROR((env));
191         CM_LOG_E("could not get string");
192         return nullptr;
193     }
194 
195     stringBlob = static_cast<CmBlob *>(CmMalloc(sizeof(CmBlob)));
196     if (stringBlob == nullptr) {
197         CmFree(data);
198         napi_throw_error(env, nullptr, "could not alloc memory");
199         CM_LOG_E("could not alloc memory");
200         return nullptr;
201     }
202     stringBlob->data = reinterpret_cast<uint8_t *>(data);
203     stringBlob->size = static_cast<uint32_t>((length + 1) & UINT32_MAX);
204 
205     return GetInt32(env, 0);
206 }
207 
ParseString(napi_env env,napi_value object,CmBlob * & stringBlob)208 napi_value ParseString(napi_env env, napi_value object, CmBlob *&stringBlob)
209 {
210     return ParseStringCommon(env, object, stringBlob, false);
211 }
212 
ParsePasswd(napi_env env,napi_value object,CmBlob * & stringBlob)213 napi_value ParsePasswd(napi_env env, napi_value object, CmBlob *&stringBlob)
214 {
215     return ParseStringCommon(env, object, stringBlob, true);
216 }
217 
GetUint8Array(napi_env env,napi_value object,CmBlob & arrayBlob)218 napi_value GetUint8Array(napi_env env, napi_value object, CmBlob &arrayBlob)
219 {
220     napi_typedarray_type arrayType;
221     napi_value arrayBuffer = nullptr;
222     size_t length = 0;
223     size_t offset = 0;
224     void *rawData = nullptr;
225 
226     napi_status status = napi_get_typedarray_info(
227         env, object, &arrayType, &length, static_cast<void **>(&rawData), &arrayBuffer, &offset);
228     if (status != napi_ok) {
229         CM_LOG_E("the type of param is not uint8_array");
230         return nullptr;
231     }
232     if (length > CM_MAX_DATA_LEN) {
233         CM_LOG_E("Data is too large, length = %x", length);
234         return nullptr;
235     }
236     if (length == 0) {
237         CM_LOG_D("The memory length created is only 1 Byte");
238         // The memory length created is only 1 Byte
239         arrayBlob.data = static_cast<uint8_t *>(CmMalloc(1));
240     } else {
241         arrayBlob.data = static_cast<uint8_t *>(CmMalloc(length));
242     }
243     if (arrayBlob.data == nullptr) {
244         CM_LOG_E("Malloc failed");
245         return nullptr;
246     }
247     (void)memset_s(arrayBlob.data, length, 0, length);
248     if (memcpy_s(arrayBlob.data, length, rawData, length) != EOK) {
249         CM_LOG_E("memcpy_s fail, length = %x", length);
250         return nullptr;
251     }
252     arrayBlob.size = static_cast<uint32_t>(length);
253 
254     return GetInt32(env, 0);
255 }
256 
GetCallback(napi_env env,napi_value object)257 napi_ref GetCallback(napi_env env, napi_value object)
258 {
259     napi_valuetype valueType = napi_undefined;
260     napi_status status = napi_typeof(env, object, &valueType);
261     if (status != napi_ok) {
262         CM_LOG_E("could not get object type");
263         return nullptr;
264     }
265 
266     if (valueType != napi_function) {
267         CM_LOG_E("invalid type");
268         return nullptr;
269     }
270 
271     napi_ref ref = nullptr;
272     status = napi_create_reference(env, object, 1, &ref);
273     if (status != napi_ok) {
274         CM_LOG_E("could not create reference");
275         return nullptr;
276     }
277     return ref;
278 }
279 
GetCallback(napi_env env,napi_value object,napi_ref & callback)280 int32_t GetCallback(napi_env env, napi_value object, napi_ref &callback)
281 {
282     napi_valuetype valueType = napi_undefined;
283     napi_status status = napi_typeof(env, object, &valueType);
284     if (status != napi_ok) {
285         CM_LOG_E("could not get object type");
286         return CM_FAILURE;
287     }
288 
289     if (valueType == napi_null || valueType == napi_undefined) {
290         CM_LOG_D("callback is null or undefined, treat as promise");
291         return CM_SUCCESS;
292     }
293 
294     if (valueType != napi_function) {
295         CM_LOG_E("invalid type, not function");
296         return CM_FAILURE;
297     }
298 
299     napi_ref ref = nullptr;
300     status = napi_create_reference(env, object, 1, &ref);
301     if (status != napi_ok) {
302         CM_LOG_E("could not create reference");
303         return CM_FAILURE;
304     }
305     callback = ref;
306     return CM_SUCCESS;
307 }
308 
GenerateAarrayBuffer(napi_env env,uint8_t * data,uint32_t size)309 static napi_value GenerateAarrayBuffer(napi_env env, uint8_t *data, uint32_t size)
310 {
311     uint8_t *buffer = static_cast<uint8_t *>(CmMalloc(size));
312     if (buffer == nullptr) {
313         return nullptr;
314     }
315     (void)memcpy_s(buffer, size, data, size);
316 
317     napi_value outBuffer = nullptr;
318     napi_status status = napi_create_external_arraybuffer(
319         env, buffer, size, [](napi_env env, void *data, void *hint) { CmFree(data); }, nullptr, &outBuffer);
320     if (status == napi_ok) {
321         // free by finalize callback
322         buffer = nullptr;
323     } else {
324         CmFree(buffer);
325         GET_AND_THROW_LAST_ERROR((env));
326     }
327 
328     return outBuffer;
329 }
330 
GenerateCertAbstractArray(napi_env env,const struct CertAbstract * certAbstract,const uint32_t certCount)331 napi_value GenerateCertAbstractArray(napi_env env, const struct CertAbstract *certAbstract, const uint32_t certCount)
332 {
333     if (certCount == 0 || certAbstract == nullptr) {
334         return nullptr;
335     }
336     napi_value array = nullptr;
337     NAPI_CALL(env, napi_create_array(env, &array));
338     for (uint32_t i = 0; i < certCount; i++) {
339         napi_value uri = nullptr;
340         napi_value certAlias = nullptr;
341         napi_value subjectName = nullptr;
342         napi_value status = nullptr;
343 
344         napi_create_string_latin1(env, static_cast<const char *>(certAbstract[i].uri), NAPI_AUTO_LENGTH, &uri);
345         napi_create_string_latin1(env, static_cast<const char *>(certAbstract[i].certAlias),
346             NAPI_AUTO_LENGTH, &certAlias);
347         napi_create_string_latin1(env, static_cast<const char *>(certAbstract[i].subjectName),
348             NAPI_AUTO_LENGTH, &subjectName);
349         napi_get_boolean(env, certAbstract[i].status, &status);
350 
351         napi_value element = nullptr;
352         napi_create_object(env, &element);
353         napi_set_named_property (env, element, CM_CERT_PROPERTY_URI.c_str(), uri);
354         napi_set_named_property (env, element, CM_CERT_PROPERTY_CERTALIAS.c_str(), certAlias);
355         napi_set_named_property (env, element, CM_CERT_PROPERTY_STATUS.c_str(), status);
356         napi_set_named_property (env, element, CM_CERT_PROPERTY_STATE.c_str(), status);
357         napi_set_named_property (env, element, CM_CERT_PROPERTY_SUBJECTNAME.c_str(), subjectName);
358 
359         napi_set_element(env, array, i, element);
360     }
361     return array;
362 }
363 
GenerateCredentialAbstractArray(napi_env env,const struct CredentialAbstract * credentialAbstract,const uint32_t credentialCount)364 napi_value GenerateCredentialAbstractArray(napi_env env,
365     const struct CredentialAbstract *credentialAbstract, const uint32_t credentialCount)
366 {
367     if (credentialCount == 0 || credentialAbstract == nullptr) {
368         return nullptr;
369     }
370     napi_value array = nullptr;
371     NAPI_CALL(env, napi_create_array(env, &array));
372     for (uint32_t i = 0; i < credentialCount; i++) {
373         napi_value type = nullptr;
374         napi_value alias = nullptr;
375         napi_value keyUri = nullptr;
376         napi_create_string_latin1(env, static_cast<const char *>(credentialAbstract[i].type),
377             NAPI_AUTO_LENGTH, &type);
378         napi_create_string_latin1(env, static_cast<const char *>(credentialAbstract[i].alias),
379             NAPI_AUTO_LENGTH, &alias);
380         napi_create_string_latin1(env, static_cast<const char *>(credentialAbstract[i].keyUri),
381             NAPI_AUTO_LENGTH, &keyUri);
382 
383         napi_value element = nullptr;
384         napi_create_object(env, &element);
385         napi_set_named_property (env, element, CM_CERT_PROPERTY_TYPE.c_str(), type);
386         napi_set_named_property (env, element, CM_CERT_PROPERTY_CREDENTIAL_ALIAS.c_str(), alias);
387         napi_set_named_property (env, element, CM_CERT_PROPERTY_KEY_URI.c_str(), keyUri);
388 
389         napi_set_element(env, array, i, element);
390     }
391     return array;
392 }
393 
GenerateCertInfo(napi_env env,const struct CertInfo * certInfo)394 napi_value GenerateCertInfo(napi_env env, const struct CertInfo *certInfo)
395 {
396     if (certInfo == nullptr) {
397         return nullptr;
398     }
399     napi_value result = nullptr;
400     NAPI_CALL(env, napi_create_object(env, &result));
401 
402     struct CertInfoValue cInfVal = { nullptr };
403     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->uri),
404         NAPI_AUTO_LENGTH, &cInfVal.uri));
405     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->certAlias),
406         NAPI_AUTO_LENGTH, &cInfVal.certAlias));
407     NAPI_CALL(env, napi_get_boolean(env, certInfo->status, &cInfVal.status));
408     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->issuerName),
409         NAPI_AUTO_LENGTH, &cInfVal.issuerName));
410     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->subjectName),
411         NAPI_AUTO_LENGTH, &cInfVal.subjectName));
412     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->serial),
413         NAPI_AUTO_LENGTH, &cInfVal.serial));
414     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->notBefore),
415         NAPI_AUTO_LENGTH, &cInfVal.notBefore));
416     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->notAfter),
417         NAPI_AUTO_LENGTH, &cInfVal.notAfter));
418     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(certInfo->fingerprintSha256),
419         NAPI_AUTO_LENGTH, &cInfVal.fingerprintSha256));
420 
421     napi_value certBuffer = GenerateAarrayBuffer(env, certInfo->certInfo.data, certInfo->certInfo.size);
422     if (certBuffer != nullptr) {
423         NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, certInfo->certInfo.size,
424             certBuffer, 0, &cInfVal.certInfoBlob));
425     }
426 
427     napi_value elem = nullptr;
428     NAPI_CALL(env, napi_create_object(env, &elem));
429     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_URI.c_str(), cInfVal.uri));
430     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_CERTALIAS.c_str(), cInfVal.certAlias));
431     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_STATUS.c_str(), cInfVal.status));
432     NAPI_CALL(env, napi_set_named_property (env, elem, CM_CERT_PROPERTY_STATE.c_str(), cInfVal.status));
433 
434     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_ISSUERNAME.c_str(), cInfVal.issuerName));
435     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_SUBJECTNAME.c_str(), cInfVal.subjectName));
436     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_SERIAL.c_str(), cInfVal.serial));
437     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_BEFORE.c_str(), cInfVal.notBefore));
438     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_AFTER.c_str(), cInfVal.notAfter));
439     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_FINGERSHA256.c_str(),
440         cInfVal.fingerprintSha256));
441     NAPI_CALL(env, napi_set_named_property(env, elem, CM_CERT_PROPERTY_CERT_DATA.c_str(), cInfVal.certInfoBlob));
442 
443     return elem;
444 }
445 
GetJsErrorMsg(int32_t errCode)446 static const char *GetJsErrorMsg(int32_t errCode)
447 {
448     auto iter = NATIVE_CODE_TO_MSG_MAP.find(errCode);
449     if (iter != NATIVE_CODE_TO_MSG_MAP.end()) {
450         return (iter->second).c_str();
451     }
452     return GENERIC_MSG.c_str();
453 }
454 
TranformErrorCode(int32_t errorCode)455 int32_t TranformErrorCode(int32_t errorCode)
456 {
457     auto iter = NATIVE_CODE_TO_JS_CODE_MAP.find(errorCode);
458     if (iter != NATIVE_CODE_TO_JS_CODE_MAP.end()) {
459         return iter->second;
460     }
461     return INNER_FAILURE;
462 }
463 
GenerateBusinessError(napi_env env,int32_t errorCode)464 napi_value GenerateBusinessError(napi_env env, int32_t errorCode)
465 {
466     const char *errorMsg = GetJsErrorMsg(errorCode);
467     if (errorMsg == nullptr) {
468         return nullptr;
469     }
470 
471     napi_value code = nullptr;
472     int32_t outCode = TranformErrorCode(errorCode);
473     NAPI_CALL(env, napi_create_int32(env, outCode, &code));
474 
475     napi_value message = nullptr;
476     NAPI_CALL(env, napi_create_string_utf8(env, errorMsg, NAPI_AUTO_LENGTH, &message));
477 
478     napi_value businessError = nullptr;
479     NAPI_CALL(env, napi_create_error(env, nullptr, message, &businessError));
480     NAPI_CALL(env, napi_set_named_property(env, businessError, BUSINESS_ERROR_PROPERTY_CODE.c_str(), code));
481     return businessError;
482 }
483 
ThrowError(napi_env env,int32_t errorCode,std::string errMsg)484 void ThrowError(napi_env env, int32_t errorCode, std::string errMsg)
485 {
486     napi_value paramsError = nullptr;
487     napi_value code = nullptr;
488     napi_value message = nullptr;
489     NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, errorCode, &code));
490     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message));
491     NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &paramsError));
492     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, paramsError, BUSINESS_ERROR_PROPERTY_CODE.c_str(), code));
493     NAPI_CALL_RETURN_VOID(env, napi_throw(env, paramsError));
494 }
495 
GenerateAppCertInfo(napi_env env,const struct Credential * credential)496 napi_value GenerateAppCertInfo(napi_env env, const struct Credential *credential)
497 {
498     if (credential == nullptr) {
499         return nullptr;
500     }
501     napi_value result = nullptr;
502     NAPI_CALL(env, napi_create_object(env, &result));
503     napi_value type = nullptr;
504     napi_value alias = nullptr;
505     napi_value keyUri = nullptr;
506     napi_value certNum = nullptr;
507     napi_value keyNum = nullptr;
508     napi_value credData = nullptr;
509     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(credential->type),
510         NAPI_AUTO_LENGTH, &type));
511     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(credential->alias),
512         NAPI_AUTO_LENGTH, &alias));
513     NAPI_CALL(env, napi_create_string_latin1(env, static_cast<const char *>(credential->keyUri),
514         NAPI_AUTO_LENGTH, &keyUri));
515 
516     NAPI_CALL(env, napi_create_int32(env, credential->certNum, &certNum));
517     NAPI_CALL(env, napi_create_int32(env, credential->keyNum, &keyNum));
518 
519     napi_value crendentialBuffer = GenerateAarrayBuffer(env, credential->credData.data, credential->credData.size);
520     if (crendentialBuffer != nullptr) {
521         NAPI_CALL(env, napi_create_typedarray(env, napi_uint8_array, credential->credData.size,
522             crendentialBuffer, 0, &credData));
523     }
524 
525     napi_value element = nullptr;
526     NAPI_CALL(env, napi_create_object(env, &element));
527     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_TYPE.c_str(), type));
528     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CREDENTIAL_ALIAS.c_str(), alias));
529     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_KEY_URI.c_str(), keyUri));
530     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CERT_NUM.c_str(), certNum));
531     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_KEY_NUM.c_str(), keyNum));
532 
533     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CREDENTIAL_DATA.c_str(), credData));
534     NAPI_CALL(env, napi_set_named_property(env, element, CM_CERT_PROPERTY_CREDENTIAL_DATA_NEW.c_str(), credData));
535     return element;
536 }
537 
GeneratePromise(napi_env env,napi_deferred deferred,int32_t resultCode,napi_value * result,int32_t arrLength)538 void GeneratePromise(napi_env env, napi_deferred deferred, int32_t resultCode,
539     napi_value *result, int32_t arrLength)
540 {
541     if (arrLength < RESULT_NUMBER) {
542         return;
543     }
544     if (resultCode == CM_SUCCESS) {
545         NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, deferred, result[1]));
546     } else {
547         NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, deferred, result[0]));
548     }
549 }
550 
GenerateCallback(napi_env env,napi_ref callback,napi_value * result,int32_t arrLength,int32_t ret)551 void GenerateCallback(napi_env env, napi_ref callback, napi_value *result, int32_t arrLength, int32_t ret)
552 {
553     napi_value func = nullptr;
554     napi_value returnVal = nullptr;
555     if (arrLength < RESULT_NUMBER) {
556         return;
557     }
558     napi_value businessError = (ret == CM_SUCCESS) ? nullptr : result[0];
559     napi_value params[RESULT_NUMBER] = { businessError, result[1] };
560     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, callback, &func));
561 
562     napi_value recv = nullptr;
563     napi_get_undefined(env, &recv);
564     NAPI_CALL_RETURN_VOID(env, napi_call_function(env, recv, func, RESULT_NUMBER, params, &returnVal));
565 }
566 
GenerateNapiPromise(napi_env env,napi_ref callback,napi_deferred * deferred,napi_value * promise)567 void GenerateNapiPromise(napi_env env, napi_ref callback, napi_deferred *deferred, napi_value *promise)
568 {
569     if (callback == nullptr) {
570         NAPI_CALL_RETURN_VOID(env, napi_create_promise(env, deferred, promise));
571     } else {
572         NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, promise));
573     }
574 }
575 
DeleteNapiContext(napi_env env,napi_async_work & asyncWork,napi_ref & callback)576 void DeleteNapiContext(napi_env env, napi_async_work &asyncWork, napi_ref &callback)
577 {
578     if (asyncWork != nullptr) {
579         napi_delete_async_work(env, asyncWork);
580         asyncWork = nullptr;
581     }
582 
583     if (callback != nullptr) {
584         napi_delete_reference(env, callback);
585         callback = nullptr;
586     }
587 }
588 
FreeCmContext(CmContext * & context)589 void FreeCmContext(CmContext *&context)
590 {
591     if (context == nullptr) {
592         return;
593     }
594 
595     context->userId = 0;
596     context->uid = 0;
597 
598     CmFree(context);
599     context = nullptr;
600 }
601 
FreeCertList(CertList * & certList)602 void FreeCertList(CertList *&certList)
603 {
604     if (certList == nullptr || certList->certAbstract == nullptr) {
605         return;
606     }
607 
608     FreeCertAbstract(certList->certAbstract);
609     certList->certAbstract = nullptr;
610 
611     CmFree(certList);
612     certList = nullptr;
613 }
614 
FreeCredentialList(CredentialList * & credentialList)615 void FreeCredentialList(CredentialList *&credentialList)
616 {
617     if (credentialList == nullptr || credentialList->credentialAbstract == nullptr) {
618         return;
619     }
620 
621     FreeCredentialAbstract(credentialList->credentialAbstract);
622     credentialList->credentialAbstract = nullptr;
623 
624     CmFree(credentialList);
625     credentialList = nullptr;
626 }
627 
FreeCertInfo(CertInfo * & certInfo)628 void FreeCertInfo(CertInfo *&certInfo)
629 {
630     if (certInfo == nullptr) {
631         return;
632     }
633 
634     certInfo->status = false;
635 
636     if (certInfo->certInfo.data != nullptr) {
637         CmFree(certInfo->certInfo.data);
638     }
639 
640     CmFree(certInfo);
641     certInfo = nullptr;
642 }
643 
FreeCredential(Credential * & credential)644 void FreeCredential(Credential *&credential)
645 {
646     if (credential == nullptr) {
647         return;
648     }
649 
650     if (credential->credData.data != nullptr) {
651         CmFree(credential->credData.data);
652     }
653 
654     CmFree(credential);
655     credential = nullptr;
656 }
657 
IsValidCertType(const uint32_t certType)658 bool IsValidCertType(const uint32_t certType)
659 {
660     switch (static_cast<CmCertType>(certType)) {
661         case CM_CA_CERT_SYSTEM:
662         case CM_CA_CERT_USER:
663             return true;
664         default:
665             return false;
666     }
667 }
668 
IsValidCertScope(const uint32_t scope)669 bool IsValidCertScope(const uint32_t scope)
670 {
671     switch (static_cast<CmCertScope>(scope)) {
672         case CM_CURRENT_USER:
673         case CM_GLOBAL_USER:
674             return true;
675         default:
676             return false;
677     }
678 }
679 
IsValidCertAlg(const uint32_t certAlg)680 bool IsValidCertAlg(const uint32_t certAlg)
681 {
682     switch (static_cast<CmCertAlg>(certAlg)) {
683         case CM_ALG_INTERNATIONAL:
684         case CM_ALG_SM:
685             return true;
686         default:
687             return false;
688     }
689 }
690 }  // namespace CertManagerNapi
691