1 /*
2 * Copyright (c) 2023-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 "napi_x509_cert_chain.h"
17
18 #include "cert_crl_common.h"
19 #include "cf_api.h"
20 #include "cf_log.h"
21 #include "cf_memory.h"
22 #include "cf_param.h"
23 #include "cf_result.h"
24 #include "napi/native_api.h"
25 #include "napi/native_common.h"
26 #include "napi_cert_crl_common.h"
27 #include "napi_cert_defines.h"
28 #include "napi_cert_utils.h"
29 #include "napi_common.h"
30 #include "napi_object.h"
31 #include "napi_x509_cert_chain_validate_params.h"
32 #include "napi_x509_cert_chain_validate_result.h"
33 #include "napi_x509_cert_match_parameters.h"
34 #include "napi_x509_trust_anchor.h"
35 #include "securec.h"
36 #include "x509_cert_chain.h"
37 #include "x509_cert_chain_validate_params.h"
38 #include "x509_certificate.h"
39
40 namespace OHOS {
41 namespace CertFramework {
42 thread_local napi_ref NapiX509CertChain::classRef_ = nullptr;
43 thread_local napi_ref NapiX509CertChainBulidResult::classRef_ = nullptr;
44
45 struct CfCtx {
46 AsyncCtx async;
47 napi_ref cfRef = nullptr;
48 napi_ref certChainValidateParamsRef = nullptr;
49 NapiX509CertChain *certChainClass = nullptr;
50 HcfCertChain *certChain = nullptr;
51 CfEncodingBlob *encodingBlob = nullptr;
52 HcfX509CertChainValidateParams params;
53 HcfX509CertChainValidateResult result;
54 HcfX509CertChainBuildParameters *buildParams = nullptr;
55 HcfX509CertChainBuildResult *buildResult = nullptr;
56 CfBlob *keyStore = nullptr;
57 CfBlob *pwd = nullptr;
58 HcfX509TrustAnchorArray *trustAnchorArray = nullptr;
59 };
60
NapiX509CertChain(HcfCertChain * certChain)61 NapiX509CertChain::NapiX509CertChain(HcfCertChain *certChain)
62 {
63 this->certChain_ = certChain;
64 }
65
~NapiX509CertChain()66 NapiX509CertChain::~NapiX509CertChain()
67 {
68 CfObjDestroy(this->certChain_);
69 }
70
NapiX509CertChainBulidResult(HcfX509CertChainBuildResult * buildResult)71 NapiX509CertChainBulidResult::NapiX509CertChainBulidResult(HcfX509CertChainBuildResult *buildResult)
72 {
73 this->buildResult_ = buildResult;
74 }
75
~NapiX509CertChainBulidResult()76 NapiX509CertChainBulidResult::~NapiX509CertChainBulidResult()
77 {
78 CfObjDestroy(this->buildResult_);
79 }
80
BuildCertChainContext()81 static CfCtx *BuildCertChainContext()
82 {
83 CfCtx *context = static_cast<CfCtx *>(CfMalloc(sizeof(CfCtx), 0));
84 if (context == nullptr) {
85 LOGE("malloc cf ctx failed!");
86 return nullptr;
87 }
88 context->async = static_cast<AsyncCtx>(CfMalloc(sizeof(AsyncContext), 0));
89 if (context->async == nullptr) {
90 LOGE("malloc async ctx failed!");
91 CfFree(context);
92 context = nullptr;
93 return nullptr;
94 }
95 return context;
96 }
97
DeleteCertChainContext(napi_env env,CfCtx * & context,bool freeCertFlag=false)98 static void DeleteCertChainContext(napi_env env, CfCtx *&context, bool freeCertFlag = false)
99 {
100 if (context == nullptr) {
101 return;
102 }
103
104 FreeAsyncContext(env, context->async);
105
106 if (context->cfRef != nullptr) {
107 napi_delete_reference(env, context->cfRef);
108 context->cfRef = nullptr;
109 }
110 if (context->certChainValidateParamsRef != nullptr) {
111 napi_delete_reference(env, context->certChainValidateParamsRef);
112 context->certChainValidateParamsRef = nullptr;
113 }
114
115 if (context->encodingBlob != nullptr) {
116 CfEncodingBlobDataFree(context->encodingBlob);
117 CF_FREE_PTR(context->encodingBlob);
118 }
119
120 FreeTrustAnchorArray(context->trustAnchorArray, freeCertFlag);
121 FreeX509CertChainValidateParams(context->params);
122 FreeX509CertChainValidateResult(context->result, freeCertFlag);
123
124 CfBlobFree(&(context->keyStore));
125 CfBlobDataClearAndFree(context->pwd);
126 CfFree(context->pwd);
127 context->pwd = nullptr;
128
129 CF_FREE_PTR(context);
130 }
131
CreateCertChainJSInstance(napi_env env)132 static napi_value CreateCertChainJSInstance(napi_env env)
133 {
134 napi_value constructor = nullptr;
135 napi_value instance = nullptr;
136 napi_get_reference_value(env, NapiX509CertChain::classRef_, &constructor);
137 napi_new_instance(env, constructor, 0, nullptr, &instance);
138 return instance;
139 }
140
CreateCallbackAndPromise(napi_env env,CfCtx * context,size_t argc,size_t maxCount,napi_value callbackValue)141 static bool CreateCallbackAndPromise(
142 napi_env env, CfCtx *context, size_t argc, size_t maxCount, napi_value callbackValue)
143 {
144 context->async->asyncType = GetAsyncType(env, argc, maxCount, callbackValue);
145 if (context->async->asyncType == ASYNC_TYPE_CALLBACK) {
146 if (!CertGetCallbackFromJSParams(env, callbackValue, &context->async->callback)) {
147 LOGE("x509 certificate: get callback failed!");
148 return false;
149 }
150 } else {
151 napi_create_promise(env, &context->async->deferred, &context->async->promise);
152 }
153 return true;
154 }
155
CreateCertChainExecute(napi_env env,void * data)156 static void CreateCertChainExecute(napi_env env, void *data)
157 {
158 CfCtx *context = static_cast<CfCtx *>(data);
159 context->async->errCode = HcfCertChainCreate(context->encodingBlob, nullptr, &context->certChain);
160 if (context->async->errCode != CF_SUCCESS) {
161 context->async->errMsg = "create cert chain failed";
162 }
163 }
164
BuildX509CertChainExecute(napi_env env,void * data)165 static void BuildX509CertChainExecute(napi_env env, void *data)
166 {
167 CfCtx *context = static_cast<CfCtx *>(data);
168 context->async->errCode = HcfCertChainBuildResultCreate(context->buildParams, &context->buildResult);
169 if (context->async->errCode != CF_SUCCESS) {
170 context->async->errMsg = "create cert chain failed";
171 return;
172 }
173 HcfCertChain *certChain = context->buildResult->certChain;
174 context->async->errCode = certChain->validate(
175 certChain, &(context->buildParams->validateParameters), &(context->buildResult->validateResult));
176 if (context->async->errCode != CF_SUCCESS) {
177 context->async->errMsg = "validate failed";
178 CfObjDestroy(context->buildResult->certChain);
179 context->buildResult->certChain = nullptr;
180 }
181 }
182
BuildCreateInstance(napi_env env,HcfCertChain * certChain)183 static napi_value BuildCreateInstance(napi_env env, HcfCertChain *certChain)
184 {
185 napi_value instance = CreateCertChainJSInstance(env);
186 NapiX509CertChain *napiObject = new (std::nothrow) NapiX509CertChain(certChain);
187 if (napiObject == nullptr) {
188 LOGE("new napi object failed.");
189 return nullptr;
190 }
191 napi_status status = napi_wrap(
192 env, instance, napiObject,
193 [](napi_env env, void *data, void *hint) {
194 NapiX509CertChain *certchain = static_cast<NapiX509CertChain *>(data);
195 delete certchain;
196 return;
197 },
198 nullptr, nullptr);
199 if (status != napi_ok) {
200 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_NAPI, "failed to wrap obj!"));
201 LOGE("failed to wrap obj!");
202 delete napiObject;
203 return nullptr;
204 }
205 return instance;
206 }
207
CreateCertChainComplete(napi_env env,napi_status status,void * data)208 static void CreateCertChainComplete(napi_env env, napi_status status, void *data)
209 {
210 CfCtx *context = static_cast<CfCtx *>(data);
211 if (context->async->errCode != CF_SUCCESS) {
212 ReturnJSResult(env, context->async, nullptr);
213 DeleteCertChainContext(env, context, false);
214 return;
215 }
216
217 napi_value instance = BuildCreateInstance(env, context->certChain);
218 if (instance == nullptr) {
219 context->async->errCode = CF_ERR_MALLOC;
220 context->async->errMsg = "Failed to create napi cert chain class";
221 LOGE("Failed to create napi cert chain class");
222 CfObjDestroy(context->certChain);
223 context->certChain = nullptr;
224 }
225 ReturnJSResult(env, context->async, instance);
226 DeleteCertChainContext(env, context);
227 }
228
BuildCreateInstanceByBulidRlt(napi_env env,CfCtx * ctx)229 static napi_value BuildCreateInstanceByBulidRlt(napi_env env, CfCtx *ctx)
230 {
231 napi_value returnValue = nullptr;
232 napi_create_object(env, &returnValue);
233 if (ctx->buildResult != nullptr) {
234 napi_value insCertChain = BuildCreateInstance(env, ctx->buildResult->certChain);
235 if (insCertChain == nullptr) {
236 LOGE("Build cert chain instance failed!");
237 return nullptr;
238 }
239 napi_set_named_property(env, returnValue, CERT_CHAIN_BUILD_RESULT_TAG_CERTCHAIN.c_str(), insCertChain);
240
241 napi_value insValitateRes = BuildX509CertChainValidateResultJS(env, &(ctx->buildResult->validateResult));
242 if (insValitateRes == nullptr) {
243 LOGE("Build cert validate result failed!");
244 return nullptr;
245 }
246 napi_set_named_property(env, returnValue, CERT_CHAIN_BUILD_RESULT_TAG_VALIDATERESULT.c_str(), insValitateRes);
247 }
248
249 return returnValue;
250 }
251
BuildX509CertChainComplete(napi_env env,napi_status status,void * data)252 static void BuildX509CertChainComplete(napi_env env, napi_status status, void *data)
253 {
254 CfCtx *context = static_cast<CfCtx *>(data);
255 if (context->async->errCode != CF_SUCCESS) {
256 ReturnJSResult(env, context->async, nullptr);
257 DeleteCertChainContext(env, context, false);
258 return;
259 }
260
261 napi_value instance = BuildCreateInstanceByBulidRlt(env, context);
262 if (instance == nullptr) {
263 context->async->errCode = CF_ERR_MALLOC;
264 context->async->errMsg = "Failed to create napi cert chain class";
265 LOGE("Failed to create napi cert chain class");
266 CfObjDestroy(context->buildResult->certChain);
267 context->certChain = nullptr;
268 }
269 ReturnJSResult(env, context->async, instance);
270 DeleteCertChainContext(env, context);
271 }
272
CreateCertChainAsyncWork(napi_env env,CfCtx * context)273 static napi_value CreateCertChainAsyncWork(napi_env env, CfCtx *context)
274 {
275 napi_create_async_work(env, nullptr, GetResourceName(env, "createX509CertChain"), CreateCertChainExecute,
276 CreateCertChainComplete, static_cast<void *>(context), &context->async->asyncWork);
277
278 napi_queue_async_work(env, context->async->asyncWork);
279 if (context->async->asyncType == ASYNC_TYPE_PROMISE) {
280 return context->async->promise;
281 } else {
282 return NapiGetNull(env);
283 }
284 }
285
CreateCertChainExtAsyncWork(napi_env env,CfCtx * context)286 static napi_value CreateCertChainExtAsyncWork(napi_env env, CfCtx *context)
287 {
288 napi_create_async_work(env, nullptr, GetResourceName(env, "buildX509CertChain"), BuildX509CertChainExecute,
289 BuildX509CertChainComplete, static_cast<void *>(context), &context->async->asyncWork);
290
291 napi_queue_async_work(env, context->async->asyncWork);
292 if (context->async->asyncType == ASYNC_TYPE_PROMISE) {
293 return context->async->promise;
294 } else {
295 return NapiGetNull(env);
296 }
297 }
298
ValidateExecute(napi_env env,void * data)299 static void ValidateExecute(napi_env env, void *data)
300 {
301 CfCtx *context = static_cast<CfCtx *>(data);
302 context->async->errCode = context->certChain->validate(context->certChain, &context->params, &context->result);
303 if (context->async->errCode != CF_SUCCESS) {
304 context->async->errMsg = "create cert chain failed";
305 }
306 }
307
ValidateComplete(napi_env env,napi_status status,void * data)308 static void ValidateComplete(napi_env env, napi_status status, void *data)
309 {
310 CfCtx *context = static_cast<CfCtx *>(data);
311 if (context->async->errCode != CF_SUCCESS) {
312 ReturnJSResult(env, context->async, nullptr);
313 DeleteCertChainContext(env, context, false);
314 return;
315 }
316 napi_value instance = BuildX509CertChainValidateResultJS(env, &context->result);
317 if (instance == nullptr) {
318 LOGE("validate ret failed");
319 context->async->errCode = CF_ERR_MALLOC;
320 context->async->errMsg = "build return obj failed!";
321 ReturnJSResult(env, context->async, nullptr);
322 DeleteCertChainContext(env, context, true);
323 return;
324 }
325
326 ReturnJSResult(env, context->async, instance);
327 DeleteCertChainContext(env, context);
328 }
329
ValidateAsyncWork(napi_env env,CfCtx * context)330 static napi_value ValidateAsyncWork(napi_env env, CfCtx *context)
331 {
332 napi_create_async_work(env, nullptr, GetResourceName(env, "Validate"), ValidateExecute, ValidateComplete,
333 static_cast<void *>(context), &context->async->asyncWork);
334
335 napi_queue_async_work(env, context->async->asyncWork);
336 if (context->async->asyncType == ASYNC_TYPE_PROMISE) {
337 return context->async->promise;
338 } else {
339 return NapiGetNull(env);
340 }
341 }
342
Validate(napi_env env,napi_callback_info info)343 napi_value NapiX509CertChain::Validate(napi_env env, napi_callback_info info)
344 {
345 size_t argc = ARGS_SIZE_TWO;
346 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
347 napi_value thisVar = nullptr;
348 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
349 if (!CertCheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) {
350 LOGE("check args count failed.");
351 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "check args count failed!"));
352 return nullptr;
353 }
354
355 CfCtx *context = BuildCertChainContext();
356 if (context == nullptr) {
357 LOGE("malloc context failed.");
358 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "malloc context failed!"));
359 return nullptr;
360 }
361
362 if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, argv[PARAM1])) {
363 DeleteCertChainContext(env, context);
364 LOGE("CreateCallbackAndPromise failed!");
365 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "CreateCallbackAndPromise failed!"));
366 return nullptr;
367 }
368 context->certChainClass = this;
369 context->certChain = GetCertChain();
370 if (!BuildX509CertChainValidateParams(env, argv[PARAM0], context->params)) {
371 LOGE("BuildX509CertChainValidateParams failed!");
372 DeleteCertChainContext(env, context);
373 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "BuildX509CertChainValidateParams failed!"));
374 return nullptr;
375 }
376
377 if (napi_create_reference(env, thisVar, 1, &context->cfRef) != napi_ok) {
378 LOGE("create reference failed!");
379 DeleteCertChainContext(env, context);
380 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create reference failed!"));
381 return nullptr;
382 }
383 if (napi_create_reference(env, argv[PARAM0], 1, &context->certChainValidateParamsRef) != napi_ok) {
384 LOGE("create param ref failed!");
385 DeleteCertChainContext(env, context);
386 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "create param ref failed!"));
387 return nullptr;
388 }
389
390 return ValidateAsyncWork(env, context);
391 }
392
ToString(napi_env env,napi_callback_info info)393 napi_value NapiX509CertChain::ToString(napi_env env, napi_callback_info info)
394 {
395 HcfCertChain *certChain = GetCertChain();
396 CfBlob blob = { 0, nullptr };
397 CfResult result = certChain->toString(certChain, &blob);
398 if (result != CF_SUCCESS) {
399 LOGE("toString failed!");
400 napi_throw(env, CertGenerateBusinessError(env, result, "toString failed"));
401 return nullptr;
402 }
403
404 napi_value returnBlob = nullptr;
405 napi_create_string_utf8(env, reinterpret_cast<char *>(blob.data), blob.size, &returnBlob);
406 CfBlobDataFree(&blob);
407 return returnBlob;
408 }
409
HashCode(napi_env env,napi_callback_info info)410 napi_value NapiX509CertChain::HashCode(napi_env env, napi_callback_info info)
411 {
412 HcfCertChain *certChain = GetCertChain();
413 CfBlob blob = { 0, nullptr };
414 CfResult result = certChain->hashCode(certChain, &blob);
415 if (result != CF_SUCCESS) {
416 LOGE("hashCode failed!");
417 napi_throw(env, CertGenerateBusinessError(env, result, "hashCode failed"));
418 return nullptr;
419 }
420 napi_value returnBlob = ConvertBlobToUint8ArrNapiValue(env, &blob);
421 CfBlobDataFree(&blob);
422 return returnBlob;
423 }
424
CreateX509CertChainByArray(napi_env env,napi_value param)425 static napi_value CreateX509CertChainByArray(napi_env env, napi_value param)
426 {
427 HcfX509CertificateArray certs = { nullptr, 0 };
428 if (param != nullptr && !GetArrayCertFromNapiValue(env, param, &certs, false)) {
429 LOGE("get array cert from data failed!");
430 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get cert arr failed!"));
431 return nullptr;
432 }
433
434 HcfCertChain *certChain = nullptr;
435 CfResult res = HcfCertChainCreate(nullptr, &certs, &certChain);
436 if (res != CF_SUCCESS) {
437 LOGE("HcfCertChainCreate failed!");
438 CF_FREE_PTR(certs.data);
439 napi_throw(env, CertGenerateBusinessError(env, res, "create cert chain by arr failed!"));
440 return nullptr;
441 }
442 napi_value instance = BuildCreateInstance(env, certChain);
443 if (instance == nullptr) {
444 LOGE("BuildCreateInstance failed!");
445 CfObjDestroy(certChain);
446 CF_FREE_PTR(certs.data);
447 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "build create instance failed!"));
448 return nullptr;
449 }
450 CF_FREE_PTR(certs.data);
451 return instance;
452 }
453
CreateX509CertChainByEncodingBlob(napi_env env,size_t argc,napi_value param1,napi_value param2)454 static napi_value CreateX509CertChainByEncodingBlob(napi_env env, size_t argc, napi_value param1, napi_value param2)
455 {
456 if (!CertCheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) {
457 LOGE("CertCheckArgsCount failed");
458 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "CertCheckArgsCount failed!"));
459 return nullptr;
460 }
461 CfCtx *context = BuildCertChainContext();
462 if (context == nullptr) {
463 LOGE("context is nullptr");
464 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "context is nullptr!"));
465 return nullptr;
466 }
467
468 if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, param2)) {
469 LOGE("Create Callback Promise failed");
470 DeleteCertChainContext(env, context);
471 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create Callback Promise failed!"));
472 return nullptr;
473 }
474 if (!GetEncodingBlobFromValue(env, param1, &context->encodingBlob)) {
475 LOGE("Get Encoding Blob failed");
476 DeleteCertChainContext(env, context);
477 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Get Encoding Blob failed!"));
478 return nullptr;
479 }
480
481 return CreateCertChainAsyncWork(env, context);
482 }
483
NapiCreateX509CertChain(napi_env env,napi_callback_info info)484 napi_value NapiCreateX509CertChain(napi_env env, napi_callback_info info)
485 {
486 size_t argc = ARGS_SIZE_TWO;
487 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
488 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
489
490 bool flag = false;
491 napi_is_array(env, argv[PARAM0], &flag);
492 napi_value instance = nullptr;
493 if (flag) {
494 if (argc != ARGS_SIZE_ONE) {
495 LOGE("arg size is not correct");
496 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "arg size is not correct!"));
497 return nullptr;
498 }
499 LOGI("NapiCreateX509CertChain : Array<X509Cert>!");
500 instance = CreateX509CertChainByArray(env, argv[PARAM0]);
501 } else {
502 LOGI("NapiCreateX509CertChain : inStream: EncodingBlob!");
503 instance = CreateX509CertChainByEncodingBlob(env, argc, argv[PARAM0], argv[PARAM1]);
504 }
505 return instance;
506 }
507
CreateTrustAnchorsWithKeyStoreExecute(napi_env env,void * data)508 static void CreateTrustAnchorsWithKeyStoreExecute(napi_env env, void *data)
509 {
510 CfCtx *context = static_cast<CfCtx *>(data);
511 if (context == nullptr) {
512 LOGE("context is nullptr");
513 return;
514 }
515 context->async->errCode =
516 HcfCreateTrustAnchorWithKeyStore(context->keyStore, context->pwd, &context->trustAnchorArray);
517 if (context->async->errCode != CF_SUCCESS) {
518 context->async->errMsg = "Failed to create trust anchor from p12!";
519 }
520 }
521
ConvertX509CertToNapiValue(napi_env env,HcfX509Certificate * cert)522 static napi_value ConvertX509CertToNapiValue(napi_env env, HcfX509Certificate *cert)
523 {
524 if (cert == nullptr) {
525 LOGE("ConvertX509CertToNapiValue:cert is nullptr.");
526 return nullptr;
527 }
528 CfObject *certObj = nullptr;
529 CfResult res = GetCertObject(cert, &certObj);
530 if (res != CF_SUCCESS) {
531 LOGE("GetCertObject failed.");
532 return nullptr;
533 }
534 NapiX509Certificate *x509Cert = new (std::nothrow) NapiX509Certificate(cert, certObj);
535 if (x509Cert == nullptr) {
536 LOGE("new x509Cert failed!");
537 certObj->destroy(&certObj);
538 certObj = nullptr;
539 return nullptr;
540 }
541 napi_value instance = NapiX509Certificate::CreateX509Cert(env);
542 napi_status status = napi_wrap(
543 env, instance, x509Cert,
544 [](napi_env env, void *data, void *hint) {
545 NapiX509Certificate *certClass = static_cast<NapiX509Certificate *>(data);
546 delete certClass;
547 return;
548 },
549 nullptr, nullptr);
550 if (status != napi_ok) {
551 LOGE("Failed to wrap x509Cert obj!");
552 delete x509Cert;
553 return nullptr;
554 }
555
556 return instance;
557 }
558
ConvertBlobToUint8ArrayNapiValue(napi_env env,CfBlob * blob)559 static napi_value ConvertBlobToUint8ArrayNapiValue(napi_env env, CfBlob *blob)
560 {
561 if (blob == nullptr) {
562 LOGE("ConvertCfBlobToNapiValue:blob is nullptr.");
563 return nullptr;
564 }
565 uint8_t *buffer = static_cast<uint8_t *>(CfMalloc(blob->size, 0));
566 if (buffer == nullptr) {
567 LOGE("malloc uint8 array buffer failed!");
568 return nullptr;
569 }
570
571 if (memcpy_s(buffer, blob->size, blob->data, blob->size) != EOK) {
572 LOGE("memcpy_s data to buffer failed!");
573 CfFree(buffer);
574 buffer = nullptr;
575 return nullptr;
576 }
577
578 napi_value outBuffer = nullptr;
579 napi_status status = napi_create_external_arraybuffer(
580 env, buffer, blob->size, [](napi_env env, void *data, void *hint) { CfFree(data); }, nullptr, &outBuffer);
581 if (status != napi_ok) {
582 LOGE("create uint8 array buffer failed!");
583 CfFree(buffer);
584 buffer = nullptr;
585 return nullptr;
586 }
587 buffer = nullptr;
588
589 napi_value outData = nullptr;
590 napi_create_typedarray(env, napi_uint8_array, blob->size, outBuffer, 0, &outData);
591 return outData;
592 }
593
BuildCreateInstanceByTrustAnchorArray(napi_env env,HcfX509TrustAnchorArray * trustAnchorArray)594 static napi_value BuildCreateInstanceByTrustAnchorArray(napi_env env, HcfX509TrustAnchorArray *trustAnchorArray)
595 {
596 if (trustAnchorArray == nullptr) {
597 LOGE("Input data is null!");
598 return nullptr;
599 }
600 napi_value instance;
601 napi_create_array(env, &instance);
602 if (instance == nullptr) {
603 LOGE("Create return instance failed!");
604 return nullptr;
605 }
606 int elementIdx = 0;
607 for (uint32_t i = 0; i < trustAnchorArray->count; ++i) {
608 napi_value element = NapiX509Certificate::CreateX509Cert(env);
609 if (element == nullptr) {
610 LOGE("Create x509Cert failed!");
611 return nullptr;
612 }
613 napi_value valueCACert = ConvertX509CertToNapiValue(env, trustAnchorArray->data[i]->CACert);
614 if (valueCACert == nullptr) {
615 LOGI("The CACert value is null, return to js is an enpty object!");
616 } else {
617 trustAnchorArray->data[i]->CACert = nullptr;
618 }
619 napi_set_named_property(env, element, CERT_CHAIN_TRUSTANCHOR_TAG_CACERT.c_str(), valueCACert);
620
621 napi_value valuePubKey = ConvertBlobToUint8ArrayNapiValue(env, trustAnchorArray->data[i]->CAPubKey);
622 if (valuePubKey == nullptr) {
623 LOGI("The PubKey value is null, return to js is an enpty object!");
624 }
625 napi_set_named_property(env, element, CERT_CHAIN_TRUSTANCHOR_TAG_CAPUBKEY.c_str(), valuePubKey);
626
627 napi_value valueSub = ConvertBlobToUint8ArrayNapiValue(env, trustAnchorArray->data[i]->CASubject);
628 if (valueSub == nullptr) {
629 LOGI("The CASubject value is null, return to js is an enpty object!");
630 }
631 napi_set_named_property(env, element, CERT_CHAIN_TRUSTANCHOR_TAG_CASUBJECT.c_str(), valueSub);
632
633 napi_value valueName = ConvertBlobToUint8ArrayNapiValue(env, trustAnchorArray->data[i]->nameConstraints);
634 if (valueName == nullptr) {
635 LOGI("The nameConsteaints value is null, return to js is an enpty object!");
636 }
637 napi_set_named_property(env, element, CERT_MATCH_TAG_NAME_CONSTRAINTS.c_str(), valueName);
638
639 if (element != nullptr) {
640 napi_set_element(env, instance, elementIdx++, element);
641 }
642 }
643 return instance;
644 }
645
CreateTrustAnchorsWithKeyStoreComplete(napi_env env,napi_status status,void * data)646 static void CreateTrustAnchorsWithKeyStoreComplete(napi_env env, napi_status status, void *data)
647 {
648 CfCtx *context = static_cast<CfCtx *>(data);
649 if (context->async->errCode != CF_SUCCESS) {
650 ReturnJSResult(env, context->async, nullptr);
651 DeleteCertChainContext(env, context, false);
652 return;
653 }
654 napi_value instance = BuildCreateInstanceByTrustAnchorArray(env, context->trustAnchorArray);
655 if (instance == nullptr) {
656 context->async->errCode = CF_ERR_MALLOC;
657 context->async->errMsg = "Failed to create trust anchor with KeyStore";
658 LOGE("Failed to create trust anchor with KeyStore");
659 }
660 ReturnJSResult(env, context->async, instance);
661 DeleteCertChainContext(env, context, true);
662 }
663
CreateTrustAnchorsWithKeyStoreAsyncWork(napi_env env,CfCtx * context)664 static napi_value CreateTrustAnchorsWithKeyStoreAsyncWork(napi_env env, CfCtx *context)
665 {
666 napi_create_async_work(env, nullptr, GetResourceName(env, "createTrustAnchorsWithKeyStore"),
667 CreateTrustAnchorsWithKeyStoreExecute, CreateTrustAnchorsWithKeyStoreComplete, static_cast<void *>(context),
668 &context->async->asyncWork);
669
670 napi_queue_async_work(env, context->async->asyncWork);
671 if (context->async->asyncType == ASYNC_TYPE_PROMISE) {
672 return context->async->promise;
673 } else {
674 return NapiGetNull(env);
675 }
676 }
677
CreateTrustAnchorsWithKeyStore(napi_env env,size_t argc,napi_value param1,napi_value param2)678 static napi_value CreateTrustAnchorsWithKeyStore(napi_env env, size_t argc, napi_value param1, napi_value param2)
679 {
680 if (!CertCheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) {
681 LOGE("CertCheckArgsCount failed");
682 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "CertCheckArgsCount failed!"));
683 return nullptr;
684 }
685 CfCtx *context = BuildCertChainContext();
686 if (context == nullptr) {
687 LOGE("context is nullptr");
688 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "context is nullptr!"));
689 return nullptr;
690 }
691
692 context->async->asyncType = GetAsyncType(env, argc, ARGS_SIZE_TWO, nullptr);
693 if (context->async->asyncType == ASYNC_TYPE_CALLBACK) {
694 LOGE("ASYNC_TYPE_CALLBACK is not supported.");
695 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "ASYNC_TYPE_CALLBACK is not supported."));
696 DeleteCertChainContext(env, context);
697 return nullptr;
698 }
699 napi_create_promise(env, &context->async->deferred, &context->async->promise);
700
701 context->keyStore = CertGetBlobFromUint8ArrJSParams(env, param1);
702 if (context->keyStore == nullptr) {
703 DeleteCertChainContext(env, context);
704 return nullptr;
705 }
706 context->pwd = CertGetBlobFromStringJSParams(env, param2);
707 if (context->pwd == nullptr) {
708 DeleteCertChainContext(env, context);
709 return nullptr;
710 }
711
712 return CreateTrustAnchorsWithKeyStoreAsyncWork(env, context);
713 }
714
NapiCreateTrustAnchorsWithKeyStore(napi_env env,napi_callback_info info)715 napi_value NapiCreateTrustAnchorsWithKeyStore(napi_env env, napi_callback_info info)
716 {
717 size_t argc = ARGS_SIZE_TWO;
718 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
719 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
720 napi_value instance = CreateTrustAnchorsWithKeyStore(env, argc, argv[PARAM0], argv[PARAM1]);
721 return instance;
722 }
723
GetP12ConfFromValue(napi_env env,napi_value arg,HcfParsePKCS12Conf * conf)724 static bool GetP12ConfFromValue(napi_env env, napi_value arg, HcfParsePKCS12Conf *conf)
725 {
726 conf->isPem = true;
727 conf->isGetPriKey = true;
728 conf->isGetCert = true;
729 conf->isGetOtherCerts = false;
730
731 if (!GetIsPemFromStringNapiValue(env, arg, conf->isPem, CERT_CHAIN_PKCS12_TAG_PRIKEY_FORMAT.c_str())) {
732 return false;
733 }
734 if (!GetBoolFromNapiValue(env, arg, conf->isGetPriKey, CERT_CHAIN_PKCS12_TAG_NEEDS_PRIVATE_KEY.c_str())) {
735 return false;
736 }
737 if (!GetBoolFromNapiValue(env, arg, conf->isGetCert, CERT_CHAIN_PKCS12_TAG_NEEDS_CERT.c_str())) {
738 return false;
739 }
740 if (!GetBoolFromNapiValue(env, arg, conf->isGetOtherCerts, CERT_CHAIN_PKCS12_TAG_NEEDS_OTHER_CERTS.c_str())) {
741 return false;
742 }
743
744 napi_value obj = GetProp(env, arg, CERT_CHAIN_PKCS12_TAG_PASSWORD.c_str());
745 if (obj == nullptr) {
746 LOGE("Failed to get p12 conf!");
747 return false;
748 }
749
750 conf->pwd = CertGetBlobFromStringJSParams(env, obj);
751 if (conf->pwd == nullptr) {
752 LOGE("Out is nullptr");
753 return false;
754 }
755
756 return true;
757 }
758
FreeP12Collection(HcfX509P12Collection * collection)759 static void FreeP12Collection(HcfX509P12Collection *collection)
760 {
761 if (collection == nullptr) {
762 return;
763 }
764 if (collection->otherCerts != nullptr && collection->otherCertsCount != 0) {
765 for (uint32_t i = 0; i < collection->otherCertsCount; i++) {
766 if (collection->otherCerts[i] != nullptr) {
767 CfFree(collection->otherCerts[i]);
768 collection->otherCerts[i] = nullptr;
769 }
770 }
771 CfFree(collection->otherCerts);
772 collection->otherCerts = nullptr;
773 }
774
775 if (collection->cert != nullptr) {
776 CfFree(collection->cert);
777 collection->cert = nullptr;
778 }
779
780 if (collection->prikey != nullptr && collection->prikey->data != nullptr) {
781 CfFree(collection->prikey->data);
782 collection->prikey->data = nullptr;
783 CfFree(collection->prikey);
784 collection->prikey = nullptr;
785 }
786
787 CfFree(collection);
788 }
789
FreeHcfParsePKCS12Conf(HcfParsePKCS12Conf * conf)790 static void FreeHcfParsePKCS12Conf(HcfParsePKCS12Conf *conf)
791 {
792 if (conf == nullptr) {
793 return;
794 }
795 CfBlobFree(&conf->pwd);
796 CfFree(conf);
797 }
798
ConvertBlobToStringNapiValue(napi_env env,CfBlob * blob)799 static napi_value ConvertBlobToStringNapiValue(napi_env env, CfBlob *blob)
800 {
801 uint32_t len = blob->size;
802 char *returnString = static_cast<char *>(CfMalloc(len, 0));
803 if (returnString == nullptr) {
804 LOGE("Failed to malloc return string.");
805 return nullptr;
806 }
807
808 (void)memcpy_s(returnString, len, blob->data, len);
809 napi_value instance = nullptr;
810 napi_create_string_utf8(env, returnString, len, &instance);
811 CfFree(returnString);
812 returnString = nullptr;
813 return instance;
814 }
815
ConvertPkeyToInstance(napi_env env,HcfX509P12Collection * p12Collection)816 static napi_value ConvertPkeyToInstance(napi_env env, HcfX509P12Collection *p12Collection)
817 {
818 if (p12Collection->isPem) {
819 return ConvertBlobToStringNapiValue(env, p12Collection->prikey);
820 }
821
822 return ConvertBlobToUint8ArrayNapiValue(env, p12Collection->prikey);
823 }
824
BuildCreateInstanceByP12Collection(napi_env env,HcfX509P12Collection * p12Collection)825 static napi_value BuildCreateInstanceByP12Collection(napi_env env, HcfX509P12Collection *p12Collection)
826 {
827 napi_value instance;
828 napi_create_array(env, &instance);
829 if (instance == nullptr) {
830 LOGE("Create return instance failed!");
831 return nullptr;
832 }
833
834 if (p12Collection->cert != nullptr) {
835 napi_value certInstance = ConvertCertToNapiValue(env, p12Collection->cert);
836 if (certInstance == nullptr) {
837 LOGE("certInstance is nullptr");
838 return nullptr;
839 }
840 napi_set_named_property(env, instance, CERT_CHAIN_PKCS12_TAG_CERT.c_str(), certInstance);
841 }
842
843 if (p12Collection->prikey != nullptr) {
844 napi_value pkeyInstance = ConvertPkeyToInstance(env, p12Collection);
845 if (pkeyInstance == nullptr) {
846 LOGE("pkeyInstance is nullptr");
847 return nullptr;
848 }
849 napi_set_named_property(env, instance, CERT_CHAIN_PKCS12_TAG_PRIKEY.c_str(), pkeyInstance);
850 }
851
852 if (p12Collection->otherCerts == nullptr || p12Collection->otherCertsCount <= 0) {
853 return instance;
854 }
855
856 HcfX509CertificateArray certs = { p12Collection->otherCerts, p12Collection->otherCertsCount };
857 napi_value otherCertsInstance = ConvertCertArrToNapiValue(env, &certs);
858 if (otherCertsInstance == nullptr) {
859 LOGE("convert other certs to instance failed!");
860 return nullptr;
861 }
862 napi_set_named_property(env, instance, CERT_CHAIN_PKCS12_TAG_OTHER_CERTS.c_str(), otherCertsInstance);
863
864 return instance;
865 }
866
ParsePKCS12WithKeyStore(napi_env env,size_t argc,napi_value param0,napi_value param1)867 static napi_value ParsePKCS12WithKeyStore(napi_env env, size_t argc, napi_value param0, napi_value param1)
868 {
869 CfBlob *keyStore = CertGetBlobFromUint8ArrJSParams(env, param0);
870 if (keyStore == nullptr) {
871 LOGE("Failed to get pkcs12!");
872 return nullptr;
873 }
874 HcfParsePKCS12Conf *conf = static_cast<HcfParsePKCS12Conf *>(CfMalloc(sizeof(HcfParsePKCS12Conf), 0));
875 if (conf == nullptr) {
876 CfBlobFree(&keyStore);
877 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "Failed to malloc conf"));
878 LOGE("Failed to malloc conf!");
879 return nullptr;
880 };
881
882 if (!GetP12ConfFromValue(env, param1, conf)) {
883 CfBlobFree(&keyStore);
884 FreeHcfParsePKCS12Conf(conf);
885 conf = nullptr;
886 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Failed to get conf"));
887 LOGE("Failed to get conf!");
888 return nullptr;
889 }
890
891 HcfX509P12Collection *p12Collection = nullptr;
892 CfResult ret = HcfParsePKCS12(keyStore, conf, &p12Collection);
893 if (ret != CF_SUCCESS) {
894 CfBlobFree(&keyStore);
895 FreeHcfParsePKCS12Conf(conf);
896 conf = nullptr;
897 napi_throw(env, CertGenerateBusinessError(env, ret, "Failed to parse pkcs12"));
898 LOGE("Failed to parse pkcs12!");
899 return nullptr;
900 }
901
902 napi_value instance = BuildCreateInstanceByP12Collection(env, p12Collection);
903 if (instance == nullptr) {
904 CfBlobFree(&keyStore);
905 FreeHcfParsePKCS12Conf(conf);
906 conf = nullptr;
907 FreeP12Collection(p12Collection);
908 p12Collection = nullptr;
909 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "Failed to build instance"));
910 LOGE("Failed to build instance!");
911 return nullptr;
912 }
913 CfBlobFree(&keyStore);
914 FreeHcfParsePKCS12Conf(conf);
915 conf = nullptr;
916 CfBlobFree(&p12Collection->prikey);
917 CfFree(p12Collection);
918 p12Collection = nullptr;
919 return instance;
920 }
921
NapiParsePKCS12(napi_env env,napi_callback_info info)922 napi_value NapiParsePKCS12(napi_env env, napi_callback_info info)
923 {
924 size_t argc = ARGS_SIZE_TWO;
925 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
926 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
927 if (argc != ARGS_SIZE_TWO) {
928 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "invalid params count"));
929 LOGE("invalid params count!");
930 return nullptr;
931 }
932 napi_value instance = ParsePKCS12WithKeyStore(env, argc, argv[PARAM0], argv[PARAM1]);
933 return instance;
934 }
935
GetCertMatchParameters(napi_env env,napi_value obj,HcfX509CertChainBuildParameters ** buildParams)936 bool GetCertMatchParameters(napi_env env, napi_value obj, HcfX509CertChainBuildParameters **buildParams)
937 {
938 napi_value data = nullptr;
939 napi_status status = napi_get_named_property(env, obj, CERT_TAG_CERT_MATCH_PARAMS.c_str(), &data);
940 if (status != napi_ok) {
941 LOGE("failed to get cert match params!");
942 return false;
943 }
944 HcfX509CertMatchParams *param = &((*buildParams)->certMatchParameters);
945 if (!BuildX509CertMatchParams(env, data, param)) {
946 LOGE("BuildX509CertMatchParams failed!");
947 return false;
948 }
949 return true;
950 }
951
GetMaxlength(napi_env env,napi_value obj,HcfX509CertChainBuildParameters ** buildParams)952 bool GetMaxlength(napi_env env, napi_value obj, HcfX509CertChainBuildParameters **buildParams)
953 {
954 napi_value data = nullptr;
955 napi_status status = napi_get_named_property(env, obj, CERT_TAG_MAX_LENGTH.c_str(), &data);
956 if (status != napi_ok) {
957 LOGE("failed to get max length!");
958 return false;
959 }
960 napi_valuetype valueType;
961 napi_typeof(env, data, &valueType);
962 if ((valueType != napi_number) && (valueType != napi_undefined) && (valueType != napi_null)) {
963 LOGE("%{public}s valueType is null or undefined.", CERT_TAG_MAX_LENGTH.c_str());
964 return false;
965 }
966 napi_get_value_uint32(env, data, reinterpret_cast<uint32_t *>(&((*buildParams)->maxlength)));
967 return true;
968 }
969
GetValidateParameters(napi_env env,napi_value obj,HcfX509CertChainBuildParameters ** buildParams)970 bool GetValidateParameters(napi_env env, napi_value obj, HcfX509CertChainBuildParameters **buildParams)
971 {
972 napi_value data = nullptr;
973 napi_status status = napi_get_named_property(env, obj, CERT_TAG_VALIDATE_PARAMS.c_str(), &data);
974 if (status != napi_ok) {
975 LOGE("failed to get cert validate params!");
976 return false;
977 }
978 if (!BuildX509CertChainValidateParams(env, data, (*buildParams)->validateParameters)) {
979 LOGE("BuildX509CertChainValidateParams failed!");
980 return false;
981 }
982 return true;
983 }
984
FreeHcfX509CertChainBuildParameters(HcfX509CertChainBuildParameters * param)985 static void FreeHcfX509CertChainBuildParameters(HcfX509CertChainBuildParameters *param)
986 {
987 if (param == nullptr) {
988 return;
989 }
990 FreeX509CertMatchParamsInner(¶m->certMatchParameters);
991 FreeX509CertChainValidateParams(param->validateParameters);
992 CfFree(param);
993 }
994
GetChainBuildParametersFromValue(napi_env env,napi_value obj,HcfX509CertChainBuildParameters ** buildParams)995 bool GetChainBuildParametersFromValue(napi_env env, napi_value obj, HcfX509CertChainBuildParameters **buildParams)
996 {
997 HcfX509CertChainBuildParameters *buildParam =
998 static_cast<HcfX509CertChainBuildParameters *>(CfMalloc(sizeof(HcfX509CertChainBuildParameters), 0));
999 if (buildParam == nullptr) {
1000 LOGE("malloc cert chain build parameters failed!");
1001 return false;
1002 }
1003 buildParam->maxlength = -1;
1004
1005 if (!GetCertMatchParameters(env, obj, &buildParam)) {
1006 LOGE("failed to get cert match parameters!");
1007 FreeHcfX509CertChainBuildParameters(buildParam);
1008 buildParam = nullptr;
1009 return false;
1010 }
1011 if (!GetMaxlength(env, obj, &buildParam)) {
1012 LOGE("failed to get max length!");
1013 FreeHcfX509CertChainBuildParameters(buildParam);
1014 buildParam = nullptr;
1015 return false;
1016 }
1017 if (!GetValidateParameters(env, obj, &buildParam)) {
1018 LOGE("failed to get validate parameters!");
1019 FreeHcfX509CertChainBuildParameters(buildParam);
1020 buildParam = nullptr;
1021 return false;
1022 }
1023
1024 *buildParams = buildParam;
1025 return true;
1026 }
1027
CreateX509CertChainExtReturn(napi_env env,size_t argc,napi_value param)1028 static napi_value CreateX509CertChainExtReturn(napi_env env, size_t argc, napi_value param)
1029 {
1030 if (!CertCheckArgsCount(env, argc, ARGS_SIZE_ONE, false)) {
1031 LOGE("CertCheckArgsCount failed");
1032 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "CertCheckArgsCount failed!"));
1033 return nullptr;
1034 }
1035 CfCtx *context = BuildCertChainContext();
1036 if (context == nullptr) {
1037 LOGE("context is nullptr");
1038 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "context is nullptr!"));
1039 return nullptr;
1040 }
1041
1042 if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_ONE, nullptr)) {
1043 LOGE("Create Callback Promise failed");
1044 DeleteCertChainContext(env, context);
1045 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create Callback Promise failed!"));
1046 return nullptr;
1047 }
1048 if (napi_create_reference(env, param, 1, &context->async->paramRef) != napi_ok) {
1049 LOGE("create param ref failed!");
1050 DeleteCertChainContext(env, context);
1051 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create param ref failed"));
1052 return nullptr;
1053 }
1054 if (!GetChainBuildParametersFromValue(env, param, &context->buildParams)) {
1055 LOGE("Get Cert Chain Build Parameters failed!");
1056 DeleteCertChainContext(env, context);
1057 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Get Cert Chain Build Parameters failed!"));
1058 return nullptr;
1059 }
1060
1061 return CreateCertChainExtAsyncWork(env, context);
1062 }
1063
NapiBuildX509CertChain(napi_env env,napi_callback_info info)1064 napi_value NapiBuildX509CertChain(napi_env env, napi_callback_info info)
1065 {
1066 size_t argc = ARGS_SIZE_ONE;
1067 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
1068 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1069
1070 napi_value instance = nullptr;
1071 instance = CreateX509CertChainExtReturn(env, argc, argv[PARAM0]);
1072 return instance;
1073 }
1074
NapiGetCertList(napi_env env,napi_callback_info info)1075 napi_value NapiGetCertList(napi_env env, napi_callback_info info)
1076 {
1077 napi_value thisVar = nullptr;
1078 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1079 NapiX509CertChain *napiCertChainObj = nullptr;
1080 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiCertChainObj));
1081 if (napiCertChainObj == nullptr) {
1082 LOGE("napi cert chain object is nullptr!");
1083 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "napi cert chain object is nullptr!"));
1084 return nullptr;
1085 }
1086 HcfCertChain *certChain = napiCertChainObj->GetCertChain();
1087 HcfX509CertificateArray certs = { nullptr, 0 };
1088 CfResult res = certChain->getCertList(certChain, &certs);
1089 if (res != CF_SUCCESS) {
1090 LOGE("napi getCertList failed!");
1091 napi_throw(env, CertGenerateBusinessError(env, res, "get cert list failed!"));
1092 return nullptr;
1093 }
1094 napi_value instance = ConvertCertArrToNapiValue(env, &certs);
1095 if (instance == nullptr) {
1096 LOGE("convert arr to instance failed!");
1097 FreeCertArrayData(&certs);
1098 napi_throw(env, CertGenerateBusinessError(env, res, "convert arr to instance failed!"));
1099 return nullptr;
1100 }
1101 CF_FREE_PTR(certs.data);
1102 return instance;
1103 }
1104
NapiValidate(napi_env env,napi_callback_info info)1105 napi_value NapiValidate(napi_env env, napi_callback_info info)
1106 {
1107 napi_value thisVar = nullptr;
1108 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1109 NapiX509CertChain *napiCertChainObj = nullptr;
1110 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiCertChainObj));
1111 if (napiCertChainObj == nullptr) {
1112 LOGE("napi cert chain object is nullptr!");
1113 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "napi cert chain object is nullptr!"));
1114 return nullptr;
1115 }
1116 return napiCertChainObj->Validate(env, info);
1117 }
1118
NapiToString(napi_env env,napi_callback_info info)1119 napi_value NapiToString(napi_env env, napi_callback_info info)
1120 {
1121 napi_value thisVar = nullptr;
1122 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1123 NapiX509CertChain *napiCertChainObj = nullptr;
1124 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiCertChainObj));
1125 if (napiCertChainObj == nullptr) {
1126 LOGE("napi cert chain object is nullptr!");
1127 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "napi cert chain object is nullptr!"));
1128 return nullptr;
1129 }
1130 return napiCertChainObj->ToString(env, info);
1131 }
1132
NapiHashCode(napi_env env,napi_callback_info info)1133 napi_value NapiHashCode(napi_env env, napi_callback_info info)
1134 {
1135 napi_value thisVar = nullptr;
1136 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1137 NapiX509CertChain *napiCertChainObj = nullptr;
1138 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiCertChainObj));
1139 if (napiCertChainObj == nullptr) {
1140 LOGE("napi cert chain object is nullptr!");
1141 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "napi cert chain object is nullptr!"));
1142 return nullptr;
1143 }
1144 return napiCertChainObj->HashCode(env, info);
1145 }
1146
CertChainConstructor(napi_env env,napi_callback_info info)1147 static napi_value CertChainConstructor(napi_env env, napi_callback_info info)
1148 {
1149 napi_value thisVar = nullptr;
1150 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1151 return thisVar;
1152 }
1153
Constructor(napi_env env,napi_callback_info info)1154 napi_value NapiX509CertChain::Constructor(napi_env env, napi_callback_info info)
1155 {
1156 return CertChainConstructor(env, info);
1157 }
1158
ConvertToJsCertChain(napi_env env)1159 napi_value NapiX509CertChain::ConvertToJsCertChain(napi_env env)
1160 {
1161 napi_value instance;
1162 napi_value constructor = nullptr;
1163 napi_get_reference_value(env, classRef_, &constructor);
1164 napi_new_instance(env, constructor, 0, nullptr, &instance);
1165
1166 return instance;
1167 }
1168
Constructor(napi_env env,napi_callback_info info)1169 napi_value NapiX509CertChainBulidResult::Constructor(napi_env env, napi_callback_info info)
1170 {
1171 return CertChainConstructor(env, info);
1172 }
1173
ConvertToJsBuildResult(napi_env env)1174 napi_value NapiX509CertChainBulidResult::ConvertToJsBuildResult(napi_env env)
1175 {
1176 napi_value instance;
1177 napi_value constructor = nullptr;
1178 napi_get_reference_value(env, classRef_, &constructor);
1179 napi_new_instance(env, constructor, 0, nullptr, &instance);
1180
1181 if (this->buildResult_ != nullptr && this->buildResult_->certChain != nullptr) {
1182 NapiX509CertChain *napiObject = new (std::nothrow) NapiX509CertChain(this->buildResult_->certChain);
1183 if (napiObject == nullptr) {
1184 LOGE("new napi object failed.");
1185 return nullptr;
1186 }
1187 napi_value certChain = napiObject->ConvertToJsCertChain(env);
1188 napi_status status = napi_wrap(
1189 env, certChain, napiObject,
1190 [](napi_env env, void *data, void *hint) {
1191 NapiX509CertChain *napiObject = static_cast<NapiX509CertChain *>(data);
1192 delete napiObject;
1193 return;
1194 },
1195 nullptr, nullptr);
1196 if (status != napi_ok) {
1197 LOGE("failed to wrap certChain obj!");
1198 delete napiObject;
1199 return nullptr;
1200 }
1201 napi_set_named_property(env, instance, "certChain", certChain);
1202 }
1203
1204 if (this->buildResult_ != nullptr) {
1205 napi_value validateResult = BuildX509CertChainValidateResultJS(env, &(this->buildResult_->validateResult));
1206 napi_set_named_property(env, instance, "validateResult", validateResult);
1207 }
1208 return instance;
1209 }
1210
DefineX509CertChainJsClass(napi_env env,napi_value exports)1211 void NapiX509CertChain::DefineX509CertChainJsClass(napi_env env, napi_value exports)
1212 {
1213 napi_property_descriptor desc[] = {
1214 DECLARE_NAPI_FUNCTION("createX509CertChain", NapiCreateX509CertChain),
1215 DECLARE_NAPI_FUNCTION("createTrustAnchorsWithKeyStore", NapiCreateTrustAnchorsWithKeyStore),
1216 DECLARE_NAPI_FUNCTION("parsePkcs12", NapiParsePKCS12),
1217 };
1218 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1219
1220 napi_property_descriptor CertChainDesc[] = {
1221 DECLARE_NAPI_FUNCTION("getCertList", NapiGetCertList),
1222 DECLARE_NAPI_FUNCTION("validate", NapiValidate),
1223 DECLARE_NAPI_FUNCTION("toString", NapiToString),
1224 DECLARE_NAPI_FUNCTION("hashCode", NapiHashCode),
1225 };
1226
1227 napi_value constructor = nullptr;
1228 napi_define_class(env, "X509CertChain", NAPI_AUTO_LENGTH, CertChainConstructor, nullptr,
1229 sizeof(CertChainDesc) / sizeof(CertChainDesc[0]), CertChainDesc, &constructor);
1230 napi_create_reference(env, constructor, 1, &classRef_);
1231 }
1232
DefineX509CertChainBuildResultJsClass(napi_env env,napi_value exports)1233 void NapiX509CertChainBulidResult::DefineX509CertChainBuildResultJsClass(napi_env env, napi_value exports)
1234 {
1235 napi_property_descriptor desc[] = { DECLARE_NAPI_FUNCTION("buildX509CertChain", NapiBuildX509CertChain) };
1236 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1237
1238 napi_property_descriptor CertChainBuildResultDesc[] = {};
1239 napi_value constructor = nullptr;
1240 napi_define_class(env, "CertChainBuildResult", NAPI_AUTO_LENGTH, NapiX509CertChainBulidResult::Constructor, nullptr,
1241 sizeof(CertChainBuildResultDesc) / sizeof(CertChainBuildResultDesc[0]), CertChainBuildResultDesc, &constructor);
1242 napi_create_reference(env, constructor, 1, &classRef_);
1243 }
1244 } // namespace CertFramework
1245 } // namespace OHOS
1246