• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_cert_utils.h"
17 
18 #include "cf_log.h"
19 #include "cf_memory.h"
20 #include "config.h"
21 #include "securec.h"
22 #include "cipher.h"
23 #include "napi_cert_defines.h"
24 #include "detailed_iv_params.h"
25 #include "detailed_gcm_params.h"
26 #include "detailed_ccm_params.h"
27 
28 namespace OHOS {
29 namespace CertFramework {
30 using namespace std;
31 
32 struct CfResultCodeMap {
33     CfResult retValue;
34     ResultCode retCode;
35 };
36 
37 const struct CfResultCodeMap CODE_MAP[] = {
38     { CF_SUCCESS, JS_SUCCESS },
39     { CF_INVALID_PARAMS, JS_ERR_CERT_INVALID_PARAMS },
40     { CF_NOT_SUPPORT, JS_ERR_CERT_NOT_SUPPORT },
41     { CF_ERR_MALLOC, JS_ERR_CERT_OUT_OF_MEMORY },
42     { CF_ERR_CRYPTO_OPERATION, JS_ERR_CERT_CRYPTO_OPERATION },
43     { CF_ERR_CERT_SIGNATURE_FAILURE, JS_ERR_CERT_SIGNATURE_FAILURE },
44     { CF_ERR_CERT_NOT_YET_VALID, JS_ERR_CERT_NOT_YET_VALID },
45     { CF_ERR_CERT_HAS_EXPIRED, JS_ERR_CERT_HAS_EXPIRED },
46     { CF_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, JS_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY },
47     { CF_ERR_KEYUSAGE_NO_CERTSIGN, JS_ERR_KEYUSAGE_NO_CERTSIGN },
48     { CF_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE, JS_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE },
49 };
50 
CertNapiGetNull(napi_env env)51 napi_value CertNapiGetNull(napi_env env)
52 {
53     napi_value result = nullptr;
54     napi_get_null(env, &result);
55     return result;
56 }
57 
ConvertArrayToNapiValue(napi_env env,CfArray * array)58 napi_value ConvertArrayToNapiValue(napi_env env, CfArray *array)
59 {
60     if (array == nullptr) {
61         LOGE("array is null!");
62         return nullptr;
63     }
64     if (array->count == 0) {
65         LOGE("array count is 0!");
66         return nullptr;
67     }
68     napi_value returnArray = nullptr;
69     napi_create_array(env, &returnArray);
70     if (returnArray == nullptr) {
71         LOGE("create return array failed!");
72         return nullptr;
73     }
74     for (uint32_t i = 0; i < array->count; i++) {
75         CfBlob *blob = reinterpret_cast<CfBlob *>(array->data + i);
76         napi_value outBuffer = GenerateArrayBuffer(env, blob->data, blob->size);
77         if (outBuffer == nullptr) {
78             LOGE("generate array buffer failed!");
79             return nullptr;
80         }
81         napi_value element = nullptr;
82         napi_create_typedarray(env, napi_uint8_array, blob->size, outBuffer, 0, &element);
83         napi_set_element(env, returnArray, i, element);
84     }
85     napi_value returnValue = nullptr;
86     napi_create_object(env, &returnValue);
87     napi_set_named_property(env, returnValue, CERT_TAG_DATA.c_str(), returnArray);
88     return returnValue;
89 }
90 
GenerateArrayBuffer(napi_env env,uint8_t * data,uint32_t size)91 napi_value GenerateArrayBuffer(napi_env env, uint8_t *data, uint32_t size)
92 {
93     uint8_t *buffer = static_cast<uint8_t *>(HcfMalloc(size, 0));
94     if (buffer == nullptr) {
95         LOGE("malloc uint8 array buffer failed!");
96         return nullptr;
97     }
98 
99     if (memcpy_s(buffer, size, data, size) != EOK) {
100         LOGE("memcpy_s data to buffer failed!");
101         CfFree(buffer);
102         return nullptr;
103     }
104 
105     napi_value outBuffer = nullptr;
106     napi_status status = napi_create_external_arraybuffer(
107         env, buffer, size, [](napi_env env, void *data, void *hint) { CfFree(data); }, nullptr, &outBuffer);
108     if (status != napi_ok) {
109         LOGE("create uint8 array buffer failed!");
110         CfFree(buffer);
111         return nullptr;
112     }
113     buffer = nullptr;
114     return outBuffer;
115 }
116 
GetDataOfEncodingBlob(napi_env env,napi_value data,CfEncodingBlob * encodingBlob)117 static bool GetDataOfEncodingBlob(napi_env env, napi_value data, CfEncodingBlob *encodingBlob)
118 {
119     napi_typedarray_type arrayType;
120     napi_value arrayBuffer = nullptr;
121     size_t length = 0;
122     size_t offset = 0;
123     void *rawData = nullptr;
124 
125     napi_status status = napi_get_typedarray_info(env, data, &arrayType, &length,
126         reinterpret_cast<void **>(&rawData), &arrayBuffer, &offset);
127     if (status != napi_ok) {
128         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get array data failed"));
129         LOGE("failed to get array data!");
130         return false;
131     }
132     if (arrayType != napi_uint8_array) {
133         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "array type is not uint8 array"));
134         LOGE("array is not uint8 array!");
135         return false;
136     }
137 
138     if (length == 0) {
139         LOGE("input data length is 0");
140         return false;
141     }
142     encodingBlob->data = static_cast<uint8_t *>(HcfMalloc(length, 0));
143     if (encodingBlob->data == nullptr) {
144         LOGE("malloc encoding blob data failed!");
145         return false;
146     }
147     if (memcpy_s(encodingBlob->data, length, rawData, length) != EOK) {
148         LOGE("memcpy_s encoding blob data failed!");
149         CfFree(encodingBlob->data);
150         encodingBlob->data = nullptr;
151         return false;
152     }
153     encodingBlob->len = length;
154     return true;
155 }
156 
GetEncodingBlobFromValue(napi_env env,napi_value obj,CfEncodingBlob ** encodingBlob)157 bool GetEncodingBlobFromValue(napi_env env, napi_value obj, CfEncodingBlob **encodingBlob)
158 {
159     *encodingBlob = static_cast<CfEncodingBlob *>(HcfMalloc(sizeof(CfEncodingBlob), 0));
160     if (*encodingBlob == nullptr) {
161         LOGE("malloc encoding blob failed!");
162         return false;
163     }
164     napi_value data = nullptr;
165     napi_status status = napi_get_named_property(env, obj, CERT_TAG_DATA.c_str(), &data);
166     if (status != napi_ok) {
167         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get encoding blob data failed"));
168         LOGE("failed to get encoding blob data!");
169         CfFree(*encodingBlob);
170         *encodingBlob = nullptr;
171         return false;
172     }
173     if (!GetDataOfEncodingBlob(env, data, *encodingBlob)) {
174         CfFree(*encodingBlob);
175         *encodingBlob = nullptr;
176         return false;
177     }
178     napi_value format = nullptr;
179     status = napi_get_named_property(env, obj, CERT_TAG_ENCODING_FORMAT.c_str(), &format);
180     if (status != napi_ok) {
181         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get encoding blob format failed"));
182         LOGE("failed to get encoding blob format!");
183         CfFree((*encodingBlob)->data);
184         (*encodingBlob)->data = nullptr;
185         CfFree(*encodingBlob);
186         *encodingBlob = nullptr;
187         return false;
188     }
189     napi_get_value_uint32(env, format, reinterpret_cast<uint32_t *>(&(*encodingBlob)->encodingFormat));
190     return true;
191 }
192 
ConvertEncodingBlobToNapiValue(napi_env env,CfEncodingBlob * encodingBlob)193 napi_value ConvertEncodingBlobToNapiValue(napi_env env, CfEncodingBlob *encodingBlob)
194 {
195     napi_value outBuffer = GenerateArrayBuffer(env, encodingBlob->data, encodingBlob->len);
196     if (outBuffer == nullptr) {
197         LOGE("generate array buffer failed!");
198         return nullptr;
199     }
200     napi_value outData = nullptr;
201     napi_create_typedarray(env, napi_uint8_array, encodingBlob->len, outBuffer, 0, &outData);
202     napi_value encoding = nullptr;
203     napi_create_uint32(env, encodingBlob->encodingFormat, &encoding);
204     napi_value returnEncodingBlob = nullptr;
205     napi_create_object(env, &returnEncodingBlob);
206     napi_set_named_property(env, returnEncodingBlob, CERT_TAG_DATA.c_str(), outData);
207     napi_set_named_property(env, returnEncodingBlob, CERT_TAG_ENCODING_FORMAT.c_str(), encoding);
208     return returnEncodingBlob;
209 }
210 
CertGetBlobFromNapiValue(napi_env env,napi_value arg)211 CfBlob *CertGetBlobFromNapiValue(napi_env env, napi_value arg)
212 {
213     if ((env == nullptr) || (arg == nullptr)) {
214         LOGE("Invalid parmas!");
215         return nullptr;
216     }
217     napi_value data = nullptr;
218     napi_status status = napi_get_named_property(env, arg, CERT_TAG_DATA.c_str(), &data);
219     if ((status != napi_ok) || (data == nullptr)) {
220         LOGE("failed to get valid data property!");
221         return nullptr;
222     }
223 
224     size_t length = 0;
225     size_t offset = 0;
226     void *rawData = nullptr;
227     napi_value arrayBuffer = nullptr;
228     napi_typedarray_type arrayType;
229     // Warning: Do not release the rawData returned by this interface because the rawData is managed by VM.
230     status = napi_get_typedarray_info(env, data, &arrayType, &length,
231         reinterpret_cast<void **>(&rawData), &arrayBuffer, &offset);
232     if ((status != napi_ok) || (length == 0) || (rawData == nullptr)) {
233         LOGE("failed to get valid rawData.");
234         return nullptr;
235     }
236     if (arrayType != napi_uint8_array) {
237         LOGE("input data is not uint8 array.");
238         return nullptr;
239     }
240 
241     CfBlob *newBlob = reinterpret_cast<CfBlob *>(HcfMalloc(sizeof(CfBlob), 0));
242     if (newBlob == nullptr) {
243         LOGE("Failed to allocate newBlob memory!");
244         return nullptr;
245     }
246     newBlob->size = length;
247     newBlob->data = static_cast<uint8_t *>(HcfMalloc(length, 0));
248     if (newBlob->data == nullptr) {
249         LOGE("malloc blob data failed!");
250         CfFree(newBlob);
251         return nullptr;
252     }
253     if (memcpy_s(newBlob->data, length, rawData, length) != EOK) {
254         LOGE("memcpy_s blob data failed!");
255         CfFree(newBlob->data);
256         CfFree(newBlob);
257         return nullptr;
258     }
259 
260     return newBlob;
261 }
262 
CertConvertBlobToNapiValue(napi_env env,CfBlob * blob)263 napi_value CertConvertBlobToNapiValue(napi_env env, CfBlob *blob)
264 {
265     if (blob == nullptr || blob->data == nullptr || blob->size == 0) {
266         LOGE("Invalid blob!");
267         return nullptr;
268     }
269     uint8_t *buffer = static_cast<uint8_t *>(HcfMalloc(blob->size, 0));
270     if (buffer == nullptr) {
271         LOGE("malloc uint8 array buffer failed!");
272         return nullptr;
273     }
274 
275     if (memcpy_s(buffer, blob->size, blob->data, blob->size) != EOK) {
276         LOGE("memcpy_s data to buffer failed!");
277         CfFree(buffer);
278         return nullptr;
279     }
280 
281     napi_value outBuffer = nullptr;
282     napi_status status = napi_create_external_arraybuffer(
283         env, buffer, blob->size, [](napi_env env, void *data, void *hint) { CfFree(data); }, nullptr, &outBuffer);
284     if (status != napi_ok) {
285         LOGE("create uint8 array buffer failed!");
286         CfFree(buffer);
287         return nullptr;
288     }
289     buffer = nullptr;
290 
291     napi_value outData = nullptr;
292     napi_create_typedarray(env, napi_uint8_array, blob->size, outBuffer, 0, &outData);
293     napi_value dataBlob = nullptr;
294     napi_create_object(env, &dataBlob);
295     napi_set_named_property(env, dataBlob, CERT_TAG_DATA.c_str(), outData);
296 
297     return dataBlob;
298 }
299 
GetDataOfCertChain(napi_env env,napi_value data,HcfCertChainData * certChain)300 static bool GetDataOfCertChain(napi_env env, napi_value data, HcfCertChainData *certChain)
301 {
302     napi_typedarray_type arrayType;
303     napi_value arrayBuffer = nullptr;
304     size_t length = 0;
305     size_t offset = 0;
306     void *rawData = nullptr;
307 
308     napi_status status = napi_get_typedarray_info(env, data, &arrayType, &length,
309         reinterpret_cast<void **>(&rawData), &arrayBuffer, &offset);
310     if (status != napi_ok) {
311         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get array data failed"));
312         LOGE("failed to get array data!");
313         return false;
314     }
315     if (arrayType != napi_uint8_array) {
316         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "array type is not uint8 array"));
317         LOGE("array is not uint8 array!");
318         return false;
319     }
320 
321     if (length == 0) {
322         LOGE("input data length is 0");
323         return false;
324     }
325     certChain->data = static_cast<uint8_t *>(HcfMalloc(length, 0));
326     if (certChain->data == nullptr) {
327         LOGE("malloc cert chain data failed!");
328         return false;
329     }
330     if (memcpy_s(certChain->data, length, rawData, length) != EOK) {
331         LOGE("memcpy_s cert chain data failed!");
332         CfFree(certChain->data);
333         certChain->data = nullptr;
334         return false;
335     }
336     certChain->dataLen = length;
337     return true;
338 }
339 
GetCertChainFromValue(napi_env env,napi_value obj,HcfCertChainData ** certChainData)340 bool GetCertChainFromValue(napi_env env, napi_value obj, HcfCertChainData **certChainData)
341 {
342     *certChainData = static_cast<HcfCertChainData *>(HcfMalloc(sizeof(HcfCertChainData), 0));
343     if (*certChainData == nullptr) {
344         LOGE("malloc certChainData failed!");
345         return false;
346     }
347     napi_value data = nullptr;
348     napi_status status = napi_get_named_property(env, obj, CERT_TAG_DATA.c_str(), &data);
349     if (status != napi_ok) {
350         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get cert chain data failed"));
351         LOGE("failed to get cert chain data!");
352         CfFree(*certChainData);
353         *certChainData = nullptr;
354         return false;
355     }
356     if (!GetDataOfCertChain(env, data, *certChainData)) {
357         CfFree(*certChainData);
358         *certChainData = nullptr;
359         return false;
360     }
361 
362     napi_value certCount = nullptr;
363     status = napi_get_named_property(env, obj, CERT_TAG_COUNT.c_str(), &certCount);
364     if (status != napi_ok) {
365         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get cert chain count failed"));
366         LOGE("failed to get cert count!");
367         CfFree((*certChainData)->data);
368         (*certChainData)->data = nullptr;
369         CfFree(*certChainData);
370         *certChainData = nullptr;
371         return false;
372     }
373     napi_get_value_uint32(env, certCount, reinterpret_cast<uint32_t *>(&(*certChainData)->count));
374 
375     napi_value format = nullptr;
376     status = napi_get_named_property(env, obj, CERT_TAG_ENCODING_FORMAT.c_str(), &format);
377     if (status != napi_ok) {
378         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get cert chain format failed"));
379         LOGE("failed to get cert chain format!");
380         CfFree((*certChainData)->data);
381         (*certChainData)->data = nullptr;
382         CfFree(*certChainData);
383         *certChainData = nullptr;
384         return false;
385     }
386     napi_get_value_uint32(env, format, reinterpret_cast<uint32_t *>(&(*certChainData)->format));
387     return true;
388 }
389 
CertGetStringFromJSParams(napi_env env,napi_value arg,string & returnStr)390 bool CertGetStringFromJSParams(napi_env env, napi_value arg, string &returnStr)
391 {
392     napi_valuetype valueType;
393     napi_typeof(env, arg, &valueType);
394     if (valueType != napi_string) {
395         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "param type is not string"));
396         LOGE("wrong argument type. expect string type. [Type]: %d", valueType);
397         return false;
398     }
399 
400     size_t length = 0;
401     if (napi_get_value_string_utf8(env, arg, nullptr, 0, &length) != napi_ok) {
402         LOGE("can not get string length");
403         return false;
404     }
405     returnStr.reserve(length + 1);
406     returnStr.resize(length);
407     if (napi_get_value_string_utf8(env, arg, returnStr.data(), (length + 1), &length) != napi_ok) {
408         LOGE("can not get string value");
409         return false;
410     }
411     return true;
412 }
413 
CertGetInt32FromJSParams(napi_env env,napi_value arg,int32_t & returnInt)414 bool CertGetInt32FromJSParams(napi_env env, napi_value arg, int32_t &returnInt)
415 {
416     napi_valuetype valueType;
417     napi_typeof(env, arg, &valueType);
418     if (valueType != napi_number) {
419         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "param type is not number"));
420         LOGE("wrong argument type. expect int type. [Type]: %d", valueType);
421         return false;
422     }
423 
424     if (napi_get_value_int32(env, arg, &returnInt) != napi_ok) {
425         LOGE("can not get int value");
426         return false;
427     }
428     return true;
429 }
430 
CertGetCallbackFromJSParams(napi_env env,napi_value arg,napi_ref * returnCb)431 bool CertGetCallbackFromJSParams(napi_env env, napi_value arg, napi_ref *returnCb)
432 {
433     napi_valuetype valueType = napi_undefined;
434     napi_typeof(env, arg, &valueType);
435     if (valueType != napi_function) {
436         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "param type is not function"));
437         LOGE("wrong argument type. expect callback type. [Type]: %d", valueType);
438         return false;
439     }
440 
441     napi_create_reference(env, arg, 1, returnCb);
442     return true;
443 }
444 
GetCertErrValueByErrCode(int32_t errCode)445 static uint32_t GetCertErrValueByErrCode(int32_t errCode)
446 {
447     uint32_t count = sizeof(CODE_MAP) / sizeof(CODE_MAP[0]);
448     for (uint32_t i = 0; i < count; i++) {
449         if (errCode == CODE_MAP[i].retValue) {
450             return CODE_MAP[i].retCode;
451         }
452     }
453     return JS_ERR_CERT_RUNTIME_ERROR;
454 }
455 
CertGenerateBusinessError(napi_env env,int32_t errCode,const char * errMsg)456 napi_value CertGenerateBusinessError(napi_env env, int32_t errCode, const char *errMsg)
457 {
458     napi_value businessError = nullptr;
459 
460     napi_value code = nullptr;
461     napi_create_uint32(env, GetCertErrValueByErrCode(errCode), &code);
462 
463     napi_value msg = nullptr;
464     napi_create_string_utf8(env, errMsg, NAPI_AUTO_LENGTH, &msg);
465 
466     napi_create_error(env, nullptr, msg, &businessError);
467     napi_set_named_property(env, businessError, CERT_TAG_ERR_CODE.c_str(), code);
468 
469     return businessError;
470 }
471 
CertCheckArgsCount(napi_env env,size_t argc,size_t expectedCount,bool isSync)472 bool CertCheckArgsCount(napi_env env, size_t argc, size_t expectedCount, bool isSync)
473 {
474     if (isSync) {
475         if (argc != expectedCount) {
476             napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "invalid params count"));
477             LOGE("invalid params count!");
478             return false;
479         }
480     } else {
481         if ((argc != expectedCount) && (argc != (expectedCount - ARGS_SIZE_ONE))) {
482             napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "invalid params count"));
483             LOGE("invalid params count!");
484             return false;
485         }
486     }
487     return true;
488 }
489 
GetAsyncType(napi_env env,size_t argc,size_t maxCount,napi_value arg)490 AsyncType GetAsyncType(napi_env env, size_t argc, size_t maxCount, napi_value arg)
491 {
492     if (argc == (maxCount - 1)) { /* inner caller func: maxCount is bigger than 1 */
493         return ASYNC_TYPE_PROMISE;
494     }
495 
496     napi_valuetype valueType = napi_undefined;
497     napi_typeof(env, arg, &valueType);
498     /* If the input is undefined or null, the value is processed as promise type. */
499     if ((valueType == napi_undefined) || (valueType == napi_null)) {
500         CF_LOG_I("input value is undefined or null");
501         return ASYNC_TYPE_PROMISE;
502     }
503 
504     return ASYNC_TYPE_CALLBACK;
505 }
506 
CertGetResourceName(napi_env env,const char * name)507 napi_value CertGetResourceName(napi_env env, const char *name)
508 {
509     napi_value resourceName = nullptr;
510     napi_create_string_utf8(env, name, NAPI_AUTO_LENGTH, &resourceName);
511     return resourceName;
512 }
513 
ConvertBlobToNapiValue(napi_env env,const CfBlob * blob)514 napi_value ConvertBlobToNapiValue(napi_env env, const CfBlob *blob)
515 {
516     if (blob == nullptr || blob->data == nullptr || blob->size == 0) {
517         LOGE("Invalid blob!");
518         return nullptr;
519     }
520     uint8_t *buffer = static_cast<uint8_t *>(HcfMalloc(blob->size, 0));
521     if (buffer == nullptr) {
522         LOGE("malloc uint8 array buffer failed!");
523         return nullptr;
524     }
525 
526     if (memcpy_s(buffer, blob->size, blob->data, blob->size) != EOK) {
527         LOGE("memcpy_s data to buffer failed!");
528         CfFree(buffer);
529         return nullptr;
530     }
531 
532     napi_value outBuffer = nullptr;
533     napi_status status = napi_create_external_arraybuffer(
534         env, buffer, blob->size, [](napi_env env, void *data, void *hint) { CfFree(data); }, nullptr, &outBuffer);
535     if (status != napi_ok) {
536         LOGE("create uint8 array buffer failed!");
537         CfFree(buffer);
538         return nullptr;
539     }
540     buffer = nullptr;
541 
542     napi_value outData = nullptr;
543     napi_create_typedarray(env, napi_uint8_array, blob->size, outBuffer, 0, &outData);
544     napi_value dataBlob = nullptr;
545     napi_create_object(env, &dataBlob);
546     napi_set_named_property(env, dataBlob, CERT_TAG_DATA.c_str(), outData);
547 
548     return dataBlob;
549 }
550 
ConvertBlobToWords(const CfBlob & blob,uint64_t * & words,uint32_t & wordsCount)551 static CfResult ConvertBlobToWords(const CfBlob &blob, uint64_t *&words, uint32_t &wordsCount)
552 {
553     uint32_t blockSize = sizeof(uint64_t);
554     uint32_t convertDataSize = ((blob.size + (blockSize - 1)) >> QUAD_WORD_ALIGN_UP) << QUAD_WORD_ALIGN_UP;
555     uint8_t *convertData = static_cast<uint8_t *>(CfMalloc(convertDataSize));
556     if (convertData == nullptr) {
557         LOGE("malloc convert data failed");
558         return CF_ERR_MALLOC;
559     }
560 
561     /* convertData has been initialized 0, reverse blob data */
562     for (uint32_t i = 0; i < blob.size; ++i) {
563         convertData[i] = blob.data[blob.size - 1 - i];
564     }
565 
566     words = reinterpret_cast<uint64_t *>(convertData);
567     wordsCount = convertDataSize / blockSize;
568     return CF_SUCCESS;
569 }
570 
ConvertBlobToBigIntWords(napi_env env,const CfBlob & blob)571 napi_value ConvertBlobToBigIntWords(napi_env env, const CfBlob &blob)
572 {
573     if (blob.data == nullptr || blob.size == 0 || blob.size > MAX_SN_BYTE_CNT) {
574         LOGE("Invalid blob!");
575         return nullptr;
576     }
577 
578     uint64_t *words = nullptr;
579     uint32_t wordsCount = 0;
580     CfResult ret = ConvertBlobToWords(blob, words, wordsCount);
581     if (ret != CF_SUCCESS) {
582         napi_throw(env, CertGenerateBusinessError(env, ret, "convert data to words failed"));
583         LOGE("convert data to words failed");
584         return nullptr;
585     }
586 
587     napi_value result = nullptr;
588     napi_create_bigint_words(env, 0, wordsCount, words, &result);
589     CfFree(words);
590     return result;
591 }
592 
ConvertBlobToInt64(napi_env env,const CfBlob & blob)593 napi_value ConvertBlobToInt64(napi_env env, const CfBlob &blob)
594 {
595     if (blob.data == nullptr || blob.size == 0 || blob.size > sizeof(int64_t)) {
596         LOGE("Invalid blob!");
597         return nullptr;
598     }
599 
600     uint64_t serialNumber = 0;
601     for (uint32_t i = 0; i < blob.size; ++i) {
602         serialNumber = ((serialNumber << (BYTE_TO_BIT_CNT * i)) | static_cast<uint64_t>(blob.data[i]));
603     }
604 
605     napi_value result = nullptr;
606     napi_create_int64(env, static_cast<long>(serialNumber), &result);
607     return result;
608 }
609 }  // namespace CertFramework
610 }  // namespace OHOS
611