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