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