1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "napi_x509_certificate.h"
17 #include <string>
18 #include "napi/native_common.h"
19 #include "napi/native_api.h"
20 #include "cf_log.h"
21 #include "cf_memory.h"
22 #include "utils.h"
23 #include "cf_object_base.h"
24 #include "cf_result.h"
25 #include "napi_cert_defines.h"
26 #include "napi_pub_key.h"
27 #include "napi_cert_utils.h"
28
29 #include "cf_type.h"
30 #include "napi_object.h"
31 #include "napi_x509_cert_match_parameters.h"
32 #include "napi_x509_distinguished_name.h"
33 #include "napi_cert_extension.h"
34
35 #include "x509_csr.h"
36 #include "x509_certificate.h"
37 #include "securec.h"
38 #include "cf_blob.h"
39 #include "cf_param.h"
40
41 namespace OHOS {
42 namespace CertFramework {
43 thread_local napi_ref NapiX509Certificate::classRef_ = nullptr;
44
45 struct CfCtx {
46 AsyncType asyncType = ASYNC_TYPE_CALLBACK;
47 napi_value promise = nullptr;
48 napi_ref callback = nullptr;
49 napi_deferred deferred = nullptr;
50 napi_async_work asyncWork = nullptr;
51 napi_ref cfRef = nullptr;
52 napi_ref pubKeyParamsRef = nullptr;
53
54 CfEncodingBlob *encodingBlob = nullptr;
55 NapiX509Certificate *certClass = nullptr;
56 HcfPubKey *pubKey = nullptr;
57
58 int32_t errCode = 0;
59 const char *errMsg = nullptr;
60 HcfX509Certificate *cert = nullptr;
61 CfObject *object = nullptr;
62 CfEncodingBlob *encoded = nullptr;
63 };
64
NapiX509Certificate(HcfX509Certificate * x509Cert,CfObject * object)65 NapiX509Certificate::NapiX509Certificate(HcfX509Certificate *x509Cert, CfObject *object)
66 {
67 this->x509Cert_ = x509Cert;
68 this->certObject_ = object;
69 }
70
~NapiX509Certificate()71 NapiX509Certificate::~NapiX509Certificate()
72 {
73 CfObjDestroy(this->x509Cert_);
74 if (this->certObject_ != nullptr) {
75 this->certObject_->destroy(&(this->certObject_));
76 this->certObject_ = nullptr;
77 }
78 }
79
FreeCryptoFwkCtx(napi_env env,CfCtx * context)80 static void FreeCryptoFwkCtx(napi_env env, CfCtx *context)
81 {
82 if (context == nullptr) {
83 return;
84 }
85
86 if (context->asyncWork != nullptr) {
87 napi_delete_async_work(env, context->asyncWork);
88 }
89
90 if (context->callback != nullptr) {
91 napi_delete_reference(env, context->callback);
92 }
93
94 if (context->cfRef != nullptr) {
95 napi_delete_reference(env, context->cfRef);
96 context->cfRef = nullptr;
97 }
98 if (context->pubKeyParamsRef != nullptr) {
99 napi_delete_reference(env, context->pubKeyParamsRef);
100 context->pubKeyParamsRef = nullptr;
101 }
102
103 CfEncodingBlobDataFree(context->encodingBlob);
104 CfFree(context->encodingBlob);
105 context->encodingBlob = nullptr;
106
107 CfEncodingBlobDataFree(context->encoded);
108 CfFree(context->encoded);
109 context->encoded = nullptr;
110
111 CfFree(context);
112 }
113
ReturnCallbackResult(napi_env env,CfCtx * context,napi_value result)114 static void ReturnCallbackResult(napi_env env, CfCtx *context, napi_value result)
115 {
116 napi_value businessError = nullptr;
117 if (context->errCode != CF_SUCCESS) {
118 businessError = CertGenerateBusinessError(env, context->errCode, context->errMsg);
119 }
120 napi_value params[ARGS_SIZE_TWO] = { businessError, result };
121
122 napi_value func = nullptr;
123 napi_get_reference_value(env, context->callback, &func);
124
125 napi_value recv = nullptr;
126 napi_value callFuncRet = nullptr;
127 napi_get_undefined(env, &recv);
128 napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
129 }
130
ReturnPromiseResult(napi_env env,CfCtx * context,napi_value result)131 static void ReturnPromiseResult(napi_env env, CfCtx *context, napi_value result)
132 {
133 if (context->errCode == CF_SUCCESS) {
134 napi_resolve_deferred(env, context->deferred, result);
135 } else {
136 napi_reject_deferred(env, context->deferred,
137 CertGenerateBusinessError(env, context->errCode, context->errMsg));
138 }
139 }
140
ReturnResult(napi_env env,CfCtx * context,napi_value result)141 static void ReturnResult(napi_env env, CfCtx *context, napi_value result)
142 {
143 if (context->asyncType == ASYNC_TYPE_CALLBACK) {
144 ReturnCallbackResult(env, context, result);
145 } else {
146 ReturnPromiseResult(env, context, result);
147 }
148 }
149
CreateCallbackAndPromise(napi_env env,CfCtx * context,size_t argc,size_t maxCount,napi_value callbackValue)150 static bool CreateCallbackAndPromise(napi_env env, CfCtx *context, size_t argc,
151 size_t maxCount, napi_value callbackValue)
152 {
153 context->asyncType = GetAsyncType(env, argc, maxCount, callbackValue);
154 if (context->asyncType == ASYNC_TYPE_CALLBACK) {
155 if (!CertGetCallbackFromJSParams(env, callbackValue, &context->callback)) {
156 LOGE("x509 certificate: get callback failed!");
157 return false;
158 }
159 } else {
160 napi_create_promise(env, &context->deferred, &context->promise);
161 }
162 return true;
163 }
164
VerifyExecute(napi_env env,void * data)165 static void VerifyExecute(napi_env env, void *data)
166 {
167 CfCtx *context = static_cast<CfCtx *>(data);
168 HcfX509Certificate *cert = context->certClass->GetX509Cert();
169 context->errCode = cert->base.verify(&(cert->base), context->pubKey);
170 if (context->errCode != CF_SUCCESS) {
171 LOGE("verify cert failed!");
172 context->errMsg = "verify cert failed";
173 }
174 }
175
VerifyComplete(napi_env env,napi_status status,void * data)176 static void VerifyComplete(napi_env env, napi_status status, void *data)
177 {
178 CfCtx *context = static_cast<CfCtx *>(data);
179 ReturnResult(env, context, CertNapiGetNull(env));
180 FreeCryptoFwkCtx(env, context);
181 }
182
GetEncodedExecute(napi_env env,void * data)183 static void GetEncodedExecute(napi_env env, void *data)
184 {
185 CfCtx *context = static_cast<CfCtx *>(data);
186 HcfX509Certificate *cert = context->certClass->GetX509Cert();
187 CfEncodingBlob *encodingBlob = static_cast<CfEncodingBlob *>(CfMalloc(sizeof(CfEncodingBlob), 0));
188 if (encodingBlob == nullptr) {
189 LOGE("malloc encoding blob failed!");
190 context->errCode = CF_ERR_MALLOC;
191 context->errMsg = "malloc encoding blob failed";
192 return;
193 }
194 context->errCode = cert->base.getEncoded(&(cert->base), encodingBlob);
195 if (context->errCode != CF_SUCCESS) {
196 LOGE("get cert encoded failed!");
197 context->errMsg = "get cert encoded failed";
198 }
199 context->encoded = encodingBlob;
200 }
201
GetEncodedComplete(napi_env env,napi_status status,void * data)202 static void GetEncodedComplete(napi_env env, napi_status status, void *data)
203 {
204 CfCtx *context = static_cast<CfCtx *>(data);
205 if (context->errCode != CF_SUCCESS) {
206 ReturnResult(env, context, nullptr);
207 FreeCryptoFwkCtx(env, context);
208 return;
209 }
210 napi_value returnEncodingBlob = ConvertEncodingBlobToNapiValue(env, context->encoded);
211 ReturnResult(env, context, returnEncodingBlob);
212 FreeCryptoFwkCtx(env, context);
213 }
214
Verify(napi_env env,napi_callback_info info)215 napi_value NapiX509Certificate::Verify(napi_env env, napi_callback_info info)
216 {
217 size_t argc = ARGS_SIZE_TWO;
218 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
219 napi_value thisVar = nullptr;
220 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
221 if (!CertCheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) {
222 return nullptr;
223 }
224
225 CfCtx *context = static_cast<CfCtx *>(CfMalloc(sizeof(CfCtx), 0));
226 if (context == nullptr) {
227 LOGE("malloc context failed!");
228 return nullptr;
229 }
230 context->certClass = this;
231
232 NapiPubKey *pubKey = nullptr;
233 napi_unwrap(env, argv[PARAM0], (void**)&pubKey);
234 if (pubKey == nullptr) {
235 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "public key is null"));
236 LOGE("pubKey is null!");
237 FreeCryptoFwkCtx(env, context);
238 return nullptr;
239 }
240 context->pubKey = pubKey->GetPubKey();
241
242 if (napi_create_reference(env, thisVar, 1, &context->cfRef) != napi_ok) {
243 LOGE("create reference failed!");
244 FreeCryptoFwkCtx(env, context);
245 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create reference failed"));
246 return nullptr;
247 }
248 if (napi_create_reference(env, argv[PARAM0], 1, &context->pubKeyParamsRef) != napi_ok) {
249 LOGE("create param ref failed!");
250 FreeCryptoFwkCtx(env, context);
251 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create param ref failed"));
252 return nullptr;
253 }
254
255 if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, argv[PARAM1])) {
256 FreeCryptoFwkCtx(env, context);
257 return nullptr;
258 }
259
260 napi_create_async_work(env, nullptr, CertGetResourceName(env, "Verify"), VerifyExecute, VerifyComplete,
261 static_cast<void *>(context), &context->asyncWork);
262
263 napi_queue_async_work(env, context->asyncWork);
264 if (context->asyncType == ASYNC_TYPE_PROMISE) {
265 return context->promise;
266 }
267
268 return CertNapiGetNull(env);
269 }
270
GetEncoded(napi_env env,napi_callback_info info)271 napi_value NapiX509Certificate::GetEncoded(napi_env env, napi_callback_info info)
272 {
273 size_t argc = ARGS_SIZE_ONE;
274 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
275 napi_value thisVar = nullptr;
276 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
277 if (!CertCheckArgsCount(env, argc, ARGS_SIZE_ONE, false)) {
278 return nullptr;
279 }
280
281 CfCtx *context = static_cast<CfCtx *>(CfMalloc(sizeof(CfCtx), 0));
282 if (context == nullptr) {
283 LOGE("malloc context failed!");
284 return nullptr;
285 }
286 context->certClass = this;
287 if (napi_create_reference(env, thisVar, 1, &context->cfRef) != napi_ok) {
288 LOGE("create reference failed!");
289 FreeCryptoFwkCtx(env, context);
290 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create reference failed"));
291 return nullptr;
292 }
293
294 if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_ONE, argv[PARAM0])) {
295 FreeCryptoFwkCtx(env, context);
296 return nullptr;
297 }
298
299 napi_create_async_work(
300 env, nullptr, CertGetResourceName(env, "GetEncoded"),
301 GetEncodedExecute,
302 GetEncodedComplete,
303 static_cast<void *>(context),
304 &context->asyncWork);
305
306 napi_queue_async_work(env, context->asyncWork);
307 if (context->asyncType == ASYNC_TYPE_PROMISE) {
308 return context->promise;
309 } else {
310 return CertNapiGetNull(env);
311 }
312 }
313
GetPublicKey(napi_env env,napi_callback_info info)314 napi_value NapiX509Certificate::GetPublicKey(napi_env env, napi_callback_info info)
315 {
316 HcfX509Certificate *cert = GetX509Cert();
317 HcfPubKey *returnPubKey = nullptr;
318 CfResult ret = cert->base.getPublicKey(&(cert->base), (void **)&returnPubKey);
319 if (ret != CF_SUCCESS) {
320 napi_throw(env, CertGenerateBusinessError(env, ret, "get cert public key failed!"));
321 LOGE("get cert public key failed!");
322 return nullptr;
323 }
324
325 NapiPubKey *pubKeyClass = new (std::nothrow) NapiPubKey(returnPubKey);
326 if (pubKeyClass == nullptr) {
327 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "Failed to create a pubkey class"));
328 LOGE("create for x509 cert's public key obj failed");
329 CfObjDestroy(returnPubKey);
330 return nullptr;
331 }
332 napi_value instance = pubKeyClass->ConvertToJsPubKey(env);
333 napi_status status = napi_wrap(
334 env, instance, pubKeyClass,
335 [](napi_env env, void *data, void *hint) {
336 NapiPubKey *pubKeyClass = static_cast<NapiPubKey *>(data);
337 CfObjDestroy(pubKeyClass->GetPubKey());
338 delete pubKeyClass;
339 return;
340 },
341 nullptr, nullptr);
342 if (status != napi_ok) {
343 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_NAPI, "failed to wrap obj!"));
344 LOGE("failed to wrap obj!");
345 delete pubKeyClass;
346 return nullptr;
347 }
348 return instance;
349 }
350
CheckValidityWithDate(napi_env env,napi_callback_info info)351 napi_value NapiX509Certificate::CheckValidityWithDate(napi_env env, napi_callback_info info)
352 {
353 size_t argc = ARGS_SIZE_ONE;
354 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
355 napi_value thisVar = nullptr;
356 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
357 if (!CertCheckArgsCount(env, argc, ARGS_SIZE_ONE, true)) {
358 return nullptr;
359 }
360 std::string date;
361 if (!CertGetStringFromJSParams(env, argv[PARAM0], date)) {
362 LOGE("get date param failed!");
363 return nullptr;
364 }
365 HcfX509Certificate *cert = GetX509Cert();
366 CfResult ret = cert->checkValidityWithDate(cert, date.c_str());
367 if (ret != CF_SUCCESS) {
368 napi_throw(env, CertGenerateBusinessError(env, ret, "check cert validity failed!"));
369 LOGE("check cert validity failed!");
370 }
371 return nullptr;
372 }
373
GetVersion(napi_env env,napi_callback_info info)374 napi_value NapiX509Certificate::GetVersion(napi_env env, napi_callback_info info)
375 {
376 HcfX509Certificate *cert = GetX509Cert();
377 int version = cert->getVersion(cert);
378 napi_value result = nullptr;
379 napi_create_int32(env, version, &result);
380 return result;
381 }
382
GetSerialNumber(napi_env env,napi_callback_info info)383 napi_value NapiX509Certificate::GetSerialNumber(napi_env env, napi_callback_info info)
384 {
385 HcfX509Certificate *cert = GetX509Cert();
386 CfBlob blob = { 0, nullptr };
387 CfResult ret = cert->getSerialNumber(cert, &blob);
388 if (ret != CF_SUCCESS) {
389 napi_throw(env, CertGenerateBusinessError(env, ret, "cert get serial num failed"));
390 LOGE("cert get serial num failed!");
391 return nullptr;
392 }
393
394 napi_value result = ConvertBlobToInt64(env, blob);
395 CfBlobDataFree(&blob);
396 return result;
397 }
398
GetCertSerialNumber(napi_env env,napi_callback_info info)399 napi_value NapiX509Certificate::GetCertSerialNumber(napi_env env, napi_callback_info info)
400 {
401 HcfX509Certificate *cert = GetX509Cert();
402 CfBlob blob = { 0, nullptr };
403 CfResult ret = cert->getSerialNumber(cert, &blob);
404 if (ret != CF_SUCCESS) {
405 napi_throw(env, CertGenerateBusinessError(env, ret, "cert get serial num failed"));
406 LOGE("cert get serial num failed!");
407 return nullptr;
408 }
409
410 napi_value result = ConvertBlobToBigIntWords(env, blob);
411 CfBlobDataFree(&blob);
412 return result;
413 }
414
GetIssuerName(napi_env env,napi_callback_info info)415 napi_value NapiX509Certificate::GetIssuerName(napi_env env, napi_callback_info info)
416 {
417 CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
418 if (blob == nullptr) {
419 LOGE("malloc blob failed!");
420 return nullptr;
421 }
422 HcfX509Certificate *cert = GetX509Cert();
423 CfResult ret = cert->getIssuerName(cert, blob);
424 if (ret != CF_SUCCESS) {
425 napi_throw(env, CertGenerateBusinessError(env, ret, "get issuer name failed"));
426 LOGE("getIssuerName failed!");
427 CfFree(blob);
428 blob = nullptr;
429 return nullptr;
430 }
431 napi_value returnValue = CertConvertBlobToNapiValue(env, blob);
432 CfBlobDataFree(blob);
433 CfFree(blob);
434 blob = nullptr;
435 return returnValue;
436 }
437
GetIssuerNameEx(napi_env env,napi_callback_info info,CfEncodinigType encodingType)438 napi_value NapiX509Certificate::GetIssuerNameEx(napi_env env, napi_callback_info info, CfEncodinigType encodingType)
439 {
440 CfBlob blob = { 0, nullptr };
441 HcfX509Certificate *cert = GetX509Cert();
442 CfResult ret = cert->getIssuerNameEx(cert, encodingType, &blob);
443 if (ret != CF_SUCCESS) {
444 napi_throw(env, CertGenerateBusinessError(env, ret, "GetIssuerNameEx failed."));
445 LOGE("GetIssuerNameEx failed!");
446 return nullptr;
447 }
448 napi_value returnValue = nullptr;
449 napi_create_string_utf8(env, reinterpret_cast<char *>(blob.data), blob.size, &returnValue);
450 CfBlobDataFree(&blob);
451 return returnValue;
452 }
453
GetSubjectName(napi_env env,napi_callback_info info)454 napi_value NapiX509Certificate::GetSubjectName(napi_env env, napi_callback_info info)
455 {
456 CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
457 if (blob == nullptr) {
458 LOGE("malloc blob failed!");
459 return nullptr;
460 }
461 HcfX509Certificate *cert = GetX509Cert();
462 CfResult ret = cert->getSubjectName(cert, blob);
463 if (ret != CF_SUCCESS) {
464 napi_throw(env, CertGenerateBusinessError(env, ret, "get subject name failed"));
465 LOGE("getSubjectName failed!");
466 CfFree(blob);
467 blob = nullptr;
468 return nullptr;
469 }
470 napi_value returnValue = CertConvertBlobToNapiValue(env, blob);
471 CfBlobDataFree(blob);
472 CfFree(blob);
473 blob = nullptr;
474 return returnValue;
475 }
476
GetSubjectNameEx(napi_env env,napi_callback_info info,CfEncodinigType encodingType)477 napi_value NapiX509Certificate::GetSubjectNameEx(napi_env env, napi_callback_info info, CfEncodinigType encodingType)
478 {
479 CfBlob blob = { 0, nullptr };
480 HcfX509Certificate *cert = GetX509Cert();
481 CfResult ret = cert->getSubjectNameEx(cert, encodingType, &blob);
482 if (ret != CF_SUCCESS) {
483 napi_throw(env, CertGenerateBusinessError(env, ret, "GetSubjectNameEx failed."));
484 LOGE("GetSubjectNameEx failed!");
485 return nullptr;
486 }
487 napi_value returnValue = CertConvertBlobToNapiValue(env, &blob);
488 CfBlobDataFree(&blob);
489 return returnValue;
490 }
491
GetNotBeforeTime(napi_env env,napi_callback_info info)492 napi_value NapiX509Certificate::GetNotBeforeTime(napi_env env, napi_callback_info info)
493 {
494 CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
495 if (blob == nullptr) {
496 LOGE("malloc blob failed!");
497 return nullptr;
498 }
499 HcfX509Certificate *cert = GetX509Cert();
500 CfResult res = cert->getNotBeforeTime(cert, blob);
501 if (res != CF_SUCCESS) {
502 napi_throw(env, CertGenerateBusinessError(env, res, "get not before time failed"));
503 LOGE("getNotBeforeTime failed!");
504 CfFree(blob);
505 blob = nullptr;
506 return nullptr;
507 }
508 napi_value result = nullptr;
509 uint32_t size = blob->data[blob->size - 1] == '\0' ? blob->size - 1 : blob->size;
510 napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), size, &result);
511 CfBlobDataFree(blob);
512 CfFree(blob);
513 blob = nullptr;
514 return result;
515 }
516
GetNotAfterTime(napi_env env,napi_callback_info info)517 napi_value NapiX509Certificate::GetNotAfterTime(napi_env env, napi_callback_info info)
518 {
519 CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
520 if (blob == nullptr) {
521 LOGE("malloc blob failed!");
522 return nullptr;
523 }
524 HcfX509Certificate *cert = GetX509Cert();
525 CfResult res = cert->getNotAfterTime(cert, blob);
526 if (res != CF_SUCCESS) {
527 napi_throw(env, CertGenerateBusinessError(env, res, "get not after time failed"));
528 LOGE("getNotAfterTime failed!");
529 CfFree(blob);
530 blob = nullptr;
531 return nullptr;
532 }
533 napi_value result = nullptr;
534 uint32_t size = blob->data[blob->size - 1] == '\0' ? blob->size - 1 : blob->size;
535 napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), size, &result);
536 CfBlobDataFree(blob);
537 CfFree(blob);
538 blob = nullptr;
539 return result;
540 }
541
GetSignature(napi_env env,napi_callback_info info)542 napi_value NapiX509Certificate::GetSignature(napi_env env, napi_callback_info info)
543 {
544 CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
545 if (blob == nullptr) {
546 LOGE("malloc blob failed!");
547 return nullptr;
548 }
549 HcfX509Certificate *cert = GetX509Cert();
550 CfResult ret = cert->getSignature(cert, blob);
551 if (ret != CF_SUCCESS) {
552 napi_throw(env, CertGenerateBusinessError(env, ret, "get signature failed"));
553 LOGE("getSignature failed!");
554 CfFree(blob);
555 blob = nullptr;
556 return nullptr;
557 }
558 napi_value returnValue = CertConvertBlobToNapiValue(env, blob);
559 CfBlobDataFree(blob);
560 CfFree(blob);
561 blob = nullptr;
562 return returnValue;
563 }
564
GetSigAlgName(napi_env env,napi_callback_info info)565 napi_value NapiX509Certificate::GetSigAlgName(napi_env env, napi_callback_info info)
566 {
567 CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
568 if (blob == nullptr) {
569 LOGE("malloc blob failed!");
570 return nullptr;
571 }
572 HcfX509Certificate *cert = GetX509Cert();
573 CfResult res = cert->getSignatureAlgName(cert, blob);
574 if (res != CF_SUCCESS) {
575 napi_throw(env, CertGenerateBusinessError(env, res, "get signature alg name failed"));
576 LOGE("getSignatureAlgName failed!");
577 CfFree(blob);
578 blob = nullptr;
579 return nullptr;
580 }
581 napi_value result = nullptr;
582 uint32_t size = blob->data[blob->size - 1] == '\0' ? blob->size - 1 : blob->size;
583 napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), size, &result);
584 CfBlobDataFree(blob);
585 CfFree(blob);
586 blob = nullptr;
587 return result;
588 }
589
GetSigAlgOID(napi_env env,napi_callback_info info)590 napi_value NapiX509Certificate::GetSigAlgOID(napi_env env, napi_callback_info info)
591 {
592 CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
593 if (blob == nullptr) {
594 LOGE("malloc blob failed!");
595 return nullptr;
596 }
597 HcfX509Certificate *cert = GetX509Cert();
598 CfResult res = cert->getSignatureAlgOid(cert, blob);
599 if (res != CF_SUCCESS) {
600 napi_throw(env, CertGenerateBusinessError(env, res, "get signature alg oid failed"));
601 LOGE("getSignatureAlgOid failed!");
602 CfFree(blob);
603 blob = nullptr;
604 return nullptr;
605 }
606 napi_value result = nullptr;
607 uint32_t size = blob->data[blob->size - 1] == '\0' ? blob->size - 1 : blob->size;
608 napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), size, &result);
609 CfBlobDataFree(blob);
610 CfFree(blob);
611 blob = nullptr;
612 return result;
613 }
614
GetSigAlgParams(napi_env env,napi_callback_info info)615 napi_value NapiX509Certificate::GetSigAlgParams(napi_env env, napi_callback_info info)
616 {
617 CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
618 if (blob == nullptr) {
619 LOGE("malloc blob failed!");
620 return nullptr;
621 }
622 HcfX509Certificate *cert = GetX509Cert();
623 CfResult ret = cert->getSignatureAlgParams(cert, blob);
624 if (ret != CF_SUCCESS) {
625 napi_throw(env, CertGenerateBusinessError(env, ret, "get signature alg params failed"));
626 LOGE("getSignatureAlgParams failed!");
627 CfFree(blob);
628 blob = nullptr;
629 return nullptr;
630 }
631 napi_value returnValue = CertConvertBlobToNapiValue(env, blob);
632 CfBlobDataFree(blob);
633 CfFree(blob);
634 blob = nullptr;
635 return returnValue;
636 }
637
GetKeyUsage(napi_env env,napi_callback_info info)638 napi_value NapiX509Certificate::GetKeyUsage(napi_env env, napi_callback_info info)
639 {
640 CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
641 if (blob == nullptr) {
642 LOGE("malloc blob failed!");
643 return nullptr;
644 }
645 HcfX509Certificate *cert = GetX509Cert();
646 CfResult ret = cert->getKeyUsage(cert, blob);
647 if (ret != CF_SUCCESS) {
648 napi_throw(env, CertGenerateBusinessError(env, ret, "get key usage failed"));
649 LOGE("getKeyUsage failed!");
650 CfFree(blob);
651 blob = nullptr;
652 return nullptr;
653 }
654 napi_value returnValue = CertConvertBlobToNapiValue(env, blob);
655 CfBlobDataFree(blob);
656 CfFree(blob);
657 blob = nullptr;
658 return returnValue;
659 }
660
GetExtendedKeyUsage(napi_env env,napi_callback_info info)661 napi_value NapiX509Certificate::GetExtendedKeyUsage(napi_env env, napi_callback_info info)
662 {
663 CfArray *array = reinterpret_cast<CfArray *>(CfMalloc(sizeof(CfArray), 0));
664 if (array == nullptr) {
665 LOGE("malloc array failed!");
666 return nullptr;
667 }
668 HcfX509Certificate *cert = GetX509Cert();
669 CfResult ret = cert->getExtKeyUsage(cert, array);
670 if (ret != CF_SUCCESS) {
671 napi_throw(env, CertGenerateBusinessError(env, ret, "get ext key usage failed"));
672 LOGE("call getExtKeyUsage failed!");
673 CfFree(array);
674 array = nullptr;
675 return nullptr;
676 }
677 napi_value returnValue = ConvertArrayToNapiValue(env, array);
678 CfArrayDataClearAndFree(array);
679 CfFree(array);
680 array = nullptr;
681 return returnValue;
682 }
683
684
GetBasicConstraints(napi_env env,napi_callback_info info)685 napi_value NapiX509Certificate::GetBasicConstraints(napi_env env, napi_callback_info info)
686 {
687 HcfX509Certificate *cert = GetX509Cert();
688 int32_t constrains = cert->getBasicConstraints(cert);
689 napi_value result = nullptr;
690 napi_create_int32(env, constrains, &result);
691 return result;
692 }
693
GetSubjectAlternativeNames(napi_env env,napi_callback_info info)694 napi_value NapiX509Certificate::GetSubjectAlternativeNames(napi_env env, napi_callback_info info)
695 {
696 CfArray *array = reinterpret_cast<CfArray *>(CfMalloc(sizeof(CfArray), 0));
697 if (array == nullptr) {
698 LOGE("malloc array failed!");
699 return nullptr;
700 }
701 HcfX509Certificate *cert = GetX509Cert();
702 CfResult ret = cert->getSubjectAltNames(cert, array);
703 if (ret != CF_SUCCESS) {
704 napi_throw(env, CertGenerateBusinessError(env, ret, "get subject alt names failed"));
705 LOGE("call getSubjectAltNames failed!");
706 CfFree(array);
707 array = nullptr;
708 return nullptr;
709 }
710 napi_value returnValue = ConvertArrayToNapiValue(env, array);
711 CfArrayDataClearAndFree(array);
712 CfFree(array);
713 array = nullptr;
714 return returnValue;
715 }
716
GetIssuerAlternativeNames(napi_env env,napi_callback_info info)717 napi_value NapiX509Certificate::GetIssuerAlternativeNames(napi_env env, napi_callback_info info)
718 {
719 CfArray *array = reinterpret_cast<CfArray *>(CfMalloc(sizeof(CfArray), 0));
720 if (array == nullptr) {
721 LOGE("malloc array failed!");
722 return nullptr;
723 }
724 HcfX509Certificate *cert = GetX509Cert();
725 CfResult ret = cert->getIssuerAltNames(cert, array);
726 if (ret != CF_SUCCESS) {
727 napi_throw(env, CertGenerateBusinessError(env, ret, "get issuer alt names failed"));
728 LOGE("call getIssuerAltNames failed!");
729 CfFree(array);
730 array = nullptr;
731 return nullptr;
732 }
733 napi_value returnValue = ConvertArrayToNapiValue(env, array);
734 CfArrayDataClearAndFree(array);
735 CfFree(array);
736 array = nullptr;
737 return returnValue;
738 }
739
Match(napi_env env,napi_callback_info info)740 napi_value NapiX509Certificate::Match(napi_env env, napi_callback_info info)
741 {
742 size_t argc = ARGS_SIZE_ONE;
743 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
744 napi_value thisVar = nullptr;
745 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
746 if (!CertCheckArgsCount(env, argc, ARGS_SIZE_ONE, false)) {
747 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "CertCheckArgsCount failed"));
748 LOGE("CertCheckArgsCount failed!");
749 return nullptr;
750 }
751
752 HcfX509CertMatchParams *param = static_cast<HcfX509CertMatchParams *>(CfMalloc(sizeof(HcfX509CertMatchParams), 0));
753 if (param == nullptr) {
754 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "malloc param failed"));
755 LOGE("malloc matchParams failed!");
756 return nullptr;
757 }
758 if (!BuildX509CertMatchParams(env, argv[PARAM0], param)) {
759 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "BuildX509CertMatchParams failed"));
760 LOGE("BuildX509CertMatchParams failed!");
761 FreeX509CertMatchParams(param);
762 param = nullptr;
763 return nullptr;
764 }
765 bool boolFlag = false;
766 CfResult result = MatchProc(param, boolFlag);
767 if (result != CF_SUCCESS) {
768 napi_throw(env, CertGenerateBusinessError(env, result, "match failed"));
769 LOGE("call match failed!");
770 FreeX509CertMatchParams(param);
771 param = nullptr;
772 return nullptr;
773 }
774 FreeX509CertMatchParams(param);
775 param = nullptr;
776 napi_value ret = nullptr;
777 napi_get_boolean(env, boolFlag, &ret);
778 return ret;
779 }
780
ToString(napi_env env,napi_callback_info info)781 napi_value NapiX509Certificate::ToString(napi_env env, napi_callback_info info)
782 {
783 CfBlob blob = { 0, nullptr };
784 HcfX509Certificate *cert = GetX509Cert();
785 CfResult ret = cert->toString(cert, &blob);
786 if (ret != CF_SUCCESS) {
787 LOGE("toString failed!");
788 napi_throw(env, CertGenerateBusinessError(env, ret, "toString failed"));
789 return nullptr;
790 }
791
792 napi_value returnValue = nullptr;
793 napi_create_string_utf8(env, reinterpret_cast<char *>(blob.data), blob.size, &returnValue);
794 CfBlobDataFree(&blob);
795 return returnValue;
796 }
797
ToStringEx(napi_env env,napi_callback_info info,CfEncodinigType encodingType)798 napi_value NapiX509Certificate::ToStringEx(napi_env env, napi_callback_info info, CfEncodinigType encodingType)
799 {
800 CfBlob blob = { 0, nullptr };
801 HcfX509Certificate *cert = GetX509Cert();
802 CfResult ret = cert->toStringEx(cert, encodingType, &blob);
803 if (ret != CF_SUCCESS) {
804 LOGE("ToStringEx failed!");
805 napi_throw(env, CertGenerateBusinessError(env, ret, "ToStringEx failed"));
806 return nullptr;
807 }
808 napi_value returnValue = nullptr;
809 napi_create_string_utf8(env, reinterpret_cast<char *>(blob.data), blob.size, &returnValue);
810 CfBlobDataFree(&blob);
811 return returnValue;
812 }
813
HashCode(napi_env env,napi_callback_info info)814 napi_value NapiX509Certificate::HashCode(napi_env env, napi_callback_info info)
815 {
816 CfBlob blob = { 0, nullptr };
817 HcfX509Certificate *cert = GetX509Cert();
818 CfResult ret = cert->hashCode(cert, &blob);
819 if (ret != CF_SUCCESS) {
820 LOGE("Hashcode failed!");
821 napi_throw(env, CertGenerateBusinessError(env, ret, "Hashcode failed"));
822 return nullptr;
823 }
824 napi_value returnValue = ConvertBlobToUint8ArrNapiValue(env, &blob);
825 CfBlobDataFree(&blob);
826 return returnValue;
827 }
828
CreateCertExtsJSInstance(napi_env env)829 static napi_value CreateCertExtsJSInstance(napi_env env)
830 {
831 napi_value constructor = nullptr;
832 napi_value instance = nullptr;
833 napi_get_reference_value(env, NapiCertExtension::classRef_, &constructor);
834 napi_new_instance(env, constructor, 0, nullptr, &instance);
835 return instance;
836 }
837
BuildCertExtsObject(napi_env env,CfEncodingBlob * encodingBlob)838 static napi_value BuildCertExtsObject(napi_env env, CfEncodingBlob *encodingBlob)
839 {
840 CfObject *extsObj = nullptr;
841 int32_t res = CfCreate(CF_OBJ_TYPE_EXTENSION, encodingBlob, &extsObj);
842 if (res != CF_SUCCESS) {
843 LOGE("CfCreate error!");
844 return nullptr;
845 }
846 napi_value jsObject = CreateCertExtsJSInstance(env);
847 NapiCertExtension *napiObject = new (std::nothrow) NapiCertExtension(extsObj);
848 if (napiObject == nullptr) {
849 LOGE("Failed to create napi extension class");
850 if (extsObj != nullptr) {
851 extsObj->destroy(&(extsObj));
852 extsObj = nullptr;
853 }
854 return nullptr;
855 }
856 napi_status status = napi_wrap(
857 env, jsObject, napiObject,
858 [](napi_env env, void *data, void *hint) {
859 NapiCertExtension *certExts = static_cast<NapiCertExtension *>(data);
860 delete certExts;
861 return;
862 }, nullptr, nullptr);
863 if (status != napi_ok) {
864 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_NAPI, "failed to wrap obj!"));
865 LOGE("failed to wrap obj!");
866 delete napiObject;
867 return nullptr;
868 }
869 return jsObject;
870 }
871
GetExtensionsObject(napi_env env,napi_callback_info info)872 napi_value NapiX509Certificate::GetExtensionsObject(napi_env env, napi_callback_info info)
873 {
874 CfBlob blob = { 0, nullptr };
875 HcfX509Certificate *cert = GetX509Cert();
876 CfResult ret = cert->getExtensionsObject(cert, &blob);
877 if (ret != CF_SUCCESS) {
878 LOGE("get Extensions Object failed!");
879 napi_throw(env, CertGenerateBusinessError(env, ret, "get Extensions Object failed"));
880 return nullptr;
881 }
882
883 CfEncodingBlob *encodingBlob = static_cast<CfEncodingBlob *>(CfMalloc(sizeof(CfEncodingBlob), 0));
884 if (encodingBlob == nullptr) {
885 LOGE("malloc encoding blob failed!");
886 CfBlobDataFree(&blob);
887 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "CfMalloc failed"));
888 return nullptr;
889 }
890 if (!ConvertBlobToEncodingBlob(blob, encodingBlob)) {
891 LOGE("ConvertBlobToEncodingBlob failed!");
892 CfBlobDataFree(&blob);
893 CfFree(encodingBlob);
894 encodingBlob = nullptr;
895 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_CRYPTO_OPERATION, "ConvertBlobToEncodingBlob failed"));
896 return nullptr;
897 }
898 CfBlobDataFree(&blob);
899
900 napi_value object = BuildCertExtsObject(env, encodingBlob);
901 CfEncodingBlobDataFree(encodingBlob);
902 CfFree(encodingBlob);
903 encodingBlob = nullptr;
904 if (object == nullptr) {
905 LOGE("BuildCertExtsObject failed!");
906 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "BuildCertExtsObject failed"));
907 return nullptr;
908 }
909
910 return object;
911 }
912
GetIssuerX500DistinguishedName(napi_env env,napi_callback_info info)913 napi_value NapiX509Certificate::GetIssuerX500DistinguishedName(napi_env env, napi_callback_info info)
914 {
915 HcfX509Certificate *cert = GetX509Cert();
916 CfBlob blob = { 0, nullptr };
917 CfResult ret = cert->getIssuerName(cert, &blob);
918 if (ret != CF_SUCCESS) {
919 LOGE("getIssuerName failed!");
920 napi_throw(env, CertGenerateBusinessError(env, ret, "get issuer name failed"));
921 return nullptr;
922 }
923 HcfX509DistinguishedName *x509Name = nullptr;
924 ret = HcfX509DistinguishedNameCreate(&blob, true, &x509Name);
925 if (ret != CF_SUCCESS || x509Name == nullptr) {
926 LOGE("HcfX509DistinguishedNameCreate failed");
927 napi_throw(env, CertGenerateBusinessError(env, ret, "HcfX509DistinguishedNameCreate failed"));
928 CfBlobDataFree(&blob);
929 return nullptr;
930 }
931 CfBlobDataFree(&blob);
932
933 ret = cert->getIssuerNameDer(cert, &blob);
934 if (ret != CF_SUCCESS) {
935 LOGE("getIssuerNameDer failed!");
936 CfObjDestroy(x509Name);
937 napi_throw(env, CertGenerateBusinessError(env, ret, "get issuer name der failed."));
938 return nullptr;
939 }
940 HcfX509DistinguishedName *x509NameUtf8 = nullptr;
941 ret = HcfX509DistinguishedNameCreate(&blob, false, &x509NameUtf8);
942 if (ret != CF_SUCCESS || x509NameUtf8 == nullptr) {
943 LOGE("HcfX509DistinguishedNameCreate failed");
944 CfObjDestroy(x509Name);
945 napi_throw(env, CertGenerateBusinessError(env, ret, "HcfX509DistinguishedNameCreate failed"));
946 CfBlobDataFree(&blob);
947 return nullptr;
948 }
949 CfBlobDataFree(&blob);
950
951 napi_value instance = ConstructX509DistinguishedName(x509Name, x509NameUtf8, env);
952 return instance;
953 }
954
GetSubjectX500DistinguishedName(napi_env env,napi_callback_info info)955 napi_value NapiX509Certificate::GetSubjectX500DistinguishedName(napi_env env, napi_callback_info info)
956 {
957 HcfX509Certificate *cert = GetX509Cert();
958 CfBlob blob = { 0, nullptr };
959 CfResult ret = cert->getSubjectName(cert, &blob);
960 if (ret != CF_SUCCESS) {
961 LOGE("getSubjectName failed!");
962 napi_throw(env, CertGenerateBusinessError(env, ret, "get subject name failed"));
963 return nullptr;
964 }
965 HcfX509DistinguishedName *x509Name = nullptr;
966 ret = HcfX509DistinguishedNameCreate(&blob, true, &x509Name);
967 if (ret != CF_SUCCESS || x509Name == nullptr) {
968 LOGE("HcfX509DistinguishedNameCreate failed");
969 napi_throw(env, CertGenerateBusinessError(env, ret, "HcfX509DistinguishedNameCreate failed"));
970 CfBlobDataFree(&blob);
971 return nullptr;
972 }
973 CfBlobDataFree(&blob);
974
975 ret = cert->getSubjectNameDer(cert, &blob);
976 if (ret != CF_SUCCESS) {
977 CfObjDestroy(x509Name);
978 LOGE("getSubjectNameDer failed!");
979 napi_throw(env, CertGenerateBusinessError(env, ret, "get subject name der failed"));
980 return nullptr;
981 }
982 HcfX509DistinguishedName *x509NameUtf8 = nullptr;
983 ret = HcfX509DistinguishedNameCreate(&blob, false, &x509NameUtf8);
984 if (ret != CF_SUCCESS || x509NameUtf8 == nullptr) {
985 CfObjDestroy(x509Name);
986 LOGE("HcfX509DistinguishedNameCreate failed");
987 napi_throw(env, CertGenerateBusinessError(env, ret, "HcfX509DistinguishedNameCreate failed"));
988 CfBlobDataFree(&blob);
989 return nullptr;
990 }
991 CfBlobDataFree(&blob);
992
993 napi_value instance = ConstructX509DistinguishedName(x509Name, x509NameUtf8, env);
994 return instance;
995 }
996
GetCRLDistributionPointsURI(napi_env env,napi_callback_info info)997 napi_value NapiX509Certificate::GetCRLDistributionPointsURI(napi_env env, napi_callback_info info)
998 {
999 CfArray *array = reinterpret_cast<CfArray *>(CfMalloc(sizeof(CfArray), 0));
1000 if (array == nullptr) {
1001 LOGE("malloc array failed!");
1002 return nullptr;
1003 }
1004 HcfX509Certificate *cert = GetX509Cert();
1005 CfResult ret = cert->getCRLDistributionPointsURI(cert, array);
1006 if (ret != CF_SUCCESS) {
1007 napi_throw(env, CertGenerateBusinessError(env, ret, "get crl distribution points URI failed"));
1008 LOGE("call get crl distribution points URI failed!");
1009 CfFree(array);
1010 array = nullptr;
1011 return nullptr;
1012 }
1013 napi_value returnValue = ConvertArrayToNapiValue(env, array);
1014 CfArrayDataClearAndFree(array);
1015 CfFree(array);
1016 array = nullptr;
1017 return returnValue;
1018 }
1019
MatchProc(HcfX509CertMatchParams * param,bool & boolFlag)1020 CfResult NapiX509Certificate::MatchProc(HcfX509CertMatchParams *param, bool &boolFlag)
1021 {
1022 HcfX509Certificate *cert = GetX509Cert();
1023 return cert->match(cert, param, &boolFlag);
1024 }
1025
NapiVerify(napi_env env,napi_callback_info info)1026 static napi_value NapiVerify(napi_env env, napi_callback_info info)
1027 {
1028 napi_value thisVar = nullptr;
1029 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1030 NapiX509Certificate *x509Cert = nullptr;
1031 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1032 if (x509Cert == nullptr) {
1033 LOGE("x509Cert is nullptr!");
1034 return nullptr;
1035 }
1036 return x509Cert->Verify(env, info);
1037 }
1038
NapiGetEncoded(napi_env env,napi_callback_info info)1039 static napi_value NapiGetEncoded(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 NapiX509Certificate *x509Cert = nullptr;
1044 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1045 if (x509Cert == nullptr) {
1046 LOGE("x509Cert is nullptr!");
1047 return nullptr;
1048 }
1049 return x509Cert->GetEncoded(env, info);
1050 }
1051
NapiGetPublicKey(napi_env env,napi_callback_info info)1052 static napi_value NapiGetPublicKey(napi_env env, napi_callback_info info)
1053 {
1054 napi_value thisVar = nullptr;
1055 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1056 NapiX509Certificate *x509Cert = nullptr;
1057 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1058 if (x509Cert == nullptr) {
1059 LOGE("x509Cert is nullptr!");
1060 return nullptr;
1061 }
1062 return x509Cert->GetPublicKey(env, info);
1063 }
1064
NapiCheckValidityWithDate(napi_env env,napi_callback_info info)1065 static napi_value NapiCheckValidityWithDate(napi_env env, napi_callback_info info)
1066 {
1067 napi_value thisVar = nullptr;
1068 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1069 NapiX509Certificate *x509Cert = nullptr;
1070 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1071 if (x509Cert == nullptr) {
1072 LOGE("x509Cert is nullptr!");
1073 return nullptr;
1074 }
1075 return x509Cert->CheckValidityWithDate(env, info);
1076 }
1077
NapiGetVersion(napi_env env,napi_callback_info info)1078 static napi_value NapiGetVersion(napi_env env, napi_callback_info info)
1079 {
1080 napi_value thisVar = nullptr;
1081 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1082 NapiX509Certificate *x509Cert = nullptr;
1083 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1084 if (x509Cert == nullptr) {
1085 LOGE("x509Cert is nullptr!");
1086 return nullptr;
1087 }
1088 return x509Cert->GetVersion(env, info);
1089 }
1090
NapiGetSerialNumber(napi_env env,napi_callback_info info)1091 static napi_value NapiGetSerialNumber(napi_env env, napi_callback_info info)
1092 {
1093 napi_value thisVar = nullptr;
1094 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1095 NapiX509Certificate *x509Cert = nullptr;
1096 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1097 if (x509Cert == nullptr) {
1098 LOGE("x509Cert is nullptr!");
1099 return nullptr;
1100 }
1101 return x509Cert->GetSerialNumber(env, info);
1102 }
1103
NapiGetCertSerialNumber(napi_env env,napi_callback_info info)1104 static napi_value NapiGetCertSerialNumber(napi_env env, napi_callback_info info)
1105 {
1106 napi_value thisVar = nullptr;
1107 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1108 NapiX509Certificate *x509Cert = nullptr;
1109 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1110 if (x509Cert == nullptr) {
1111 LOGE("x509Cert is nullptr!");
1112 return nullptr;
1113 }
1114 return x509Cert->GetCertSerialNumber(env, info);
1115 }
1116
NapiGetIssuerName(napi_env env,napi_callback_info info)1117 static napi_value NapiGetIssuerName(napi_env env, napi_callback_info info)
1118 {
1119 size_t argc = ARGS_SIZE_ONE;
1120 napi_value thisVar = nullptr;
1121 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
1122 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1123 if (argc != 0 && argc != ARGS_SIZE_ONE) {
1124 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "wrong argument num!"));
1125 LOGE("wrong argument num!");
1126 return nullptr;
1127 }
1128 NapiX509Certificate *x509Cert = nullptr;
1129 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1130 if (x509Cert == nullptr) {
1131 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_NAPI, "x509Cert is nullptr!"));
1132 LOGE("x509Cert is nullptr!");
1133 return nullptr;
1134 }
1135
1136 if (argc == ARGS_SIZE_ONE) {
1137 napi_valuetype valueType;
1138 napi_typeof(env, argv[PARAM0], &valueType);
1139 if ((valueType != napi_number)) {
1140 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "wrong argument type!"));
1141 LOGE("wrong argument type!");
1142 return nullptr;
1143 }
1144 CfEncodinigType encodingType;
1145 if (napi_get_value_uint32(env, argv[PARAM0], reinterpret_cast<uint32_t *>(&encodingType)) != napi_ok) {
1146 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_NAPI, "napi_get_value_uint32 failed!"));
1147 LOGE("napi_get_value_uint32 failed!");
1148 return nullptr;
1149 }
1150 return x509Cert->GetIssuerNameEx(env, info, encodingType);
1151 }
1152 return x509Cert->GetIssuerName(env, info);
1153 }
1154
NapiGetSubjectName(napi_env env,napi_callback_info info)1155 static napi_value NapiGetSubjectName(napi_env env, napi_callback_info info)
1156 {
1157 size_t argc = ARGS_SIZE_ONE;
1158 napi_value thisVar = nullptr;
1159 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
1160 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1161 if (argc != 0 && argc != ARGS_SIZE_ONE) {
1162 LOGE("wrong argument num!");
1163 return nullptr;
1164 }
1165
1166 NapiX509Certificate *x509Cert = nullptr;
1167 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1168 if (x509Cert == nullptr) {
1169 LOGE("x509Cert is nullptr!");
1170 return nullptr;
1171 }
1172
1173 if (argc == ARGS_SIZE_ONE) {
1174 CfEncodinigType encodingType;
1175 if (napi_get_value_uint32(env, argv[PARAM0], reinterpret_cast<uint32_t *>(&encodingType)) != napi_ok) {
1176 LOGE("napi_get_value_uint32 failed!");
1177 return nullptr;
1178 }
1179 return x509Cert->GetSubjectNameEx(env, info, encodingType);
1180 }
1181 return x509Cert->GetSubjectName(env, info);
1182 }
1183
NapiGetNotBeforeTime(napi_env env,napi_callback_info info)1184 static napi_value NapiGetNotBeforeTime(napi_env env, napi_callback_info info)
1185 {
1186 napi_value thisVar = nullptr;
1187 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1188 NapiX509Certificate *x509Cert = nullptr;
1189 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1190 if (x509Cert == nullptr) {
1191 LOGE("x509Cert is nullptr!");
1192 return nullptr;
1193 }
1194 return x509Cert->GetNotBeforeTime(env, info);
1195 }
1196
NapiGetNotAfterTime(napi_env env,napi_callback_info info)1197 static napi_value NapiGetNotAfterTime(napi_env env, napi_callback_info info)
1198 {
1199 napi_value thisVar = nullptr;
1200 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1201 NapiX509Certificate *x509Cert = nullptr;
1202 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1203 if (x509Cert == nullptr) {
1204 LOGE("x509Cert is nullptr!");
1205 return nullptr;
1206 }
1207 return x509Cert->GetNotAfterTime(env, info);
1208 }
1209
NapiGetSignature(napi_env env,napi_callback_info info)1210 static napi_value NapiGetSignature(napi_env env, napi_callback_info info)
1211 {
1212 napi_value thisVar = nullptr;
1213 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1214 NapiX509Certificate *x509Cert = nullptr;
1215 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1216 if (x509Cert == nullptr) {
1217 LOGE("x509Cert is nullptr!");
1218 return nullptr;
1219 }
1220 return x509Cert->GetSignature(env, info);
1221 }
1222
NapiGetSigAlgName(napi_env env,napi_callback_info info)1223 static napi_value NapiGetSigAlgName(napi_env env, napi_callback_info info)
1224 {
1225 napi_value thisVar = nullptr;
1226 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1227 NapiX509Certificate *x509Cert = nullptr;
1228 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1229 if (x509Cert == nullptr) {
1230 LOGE("x509Cert is nullptr!");
1231 return nullptr;
1232 }
1233 return x509Cert->GetSigAlgName(env, info);
1234 }
1235
NapiGetSigAlgOID(napi_env env,napi_callback_info info)1236 static napi_value NapiGetSigAlgOID(napi_env env, napi_callback_info info)
1237 {
1238 napi_value thisVar = nullptr;
1239 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1240 NapiX509Certificate *x509Cert = nullptr;
1241 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1242 if (x509Cert == nullptr) {
1243 LOGE("x509Cert is nullptr!");
1244 return nullptr;
1245 }
1246 return x509Cert->GetSigAlgOID(env, info);
1247 }
1248
NapiGetSigAlgParams(napi_env env,napi_callback_info info)1249 static napi_value NapiGetSigAlgParams(napi_env env, napi_callback_info info)
1250 {
1251 napi_value thisVar = nullptr;
1252 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1253 NapiX509Certificate *x509Cert = nullptr;
1254 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1255 if (x509Cert == nullptr) {
1256 LOGE("x509Cert is nullptr!");
1257 return nullptr;
1258 }
1259 return x509Cert->GetSigAlgParams(env, info);
1260 }
1261
NapiGetKeyUsage(napi_env env,napi_callback_info info)1262 static napi_value NapiGetKeyUsage(napi_env env, napi_callback_info info)
1263 {
1264 napi_value thisVar = nullptr;
1265 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1266 NapiX509Certificate *x509Cert = nullptr;
1267 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1268 if (x509Cert == nullptr) {
1269 LOGE("x509Cert is nullptr!");
1270 return nullptr;
1271 }
1272 return x509Cert->GetKeyUsage(env, info);
1273 }
1274
NapiGetExtendedKeyUsage(napi_env env,napi_callback_info info)1275 static napi_value NapiGetExtendedKeyUsage(napi_env env, napi_callback_info info)
1276 {
1277 napi_value thisVar = nullptr;
1278 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1279 NapiX509Certificate *x509Cert = nullptr;
1280 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1281 if (x509Cert == nullptr) {
1282 LOGE("x509Cert is nullptr!");
1283 return nullptr;
1284 }
1285 return x509Cert->GetExtendedKeyUsage(env, info);
1286 }
1287
NapiGetBasicConstraints(napi_env env,napi_callback_info info)1288 static napi_value NapiGetBasicConstraints(napi_env env, napi_callback_info info)
1289 {
1290 napi_value thisVar = nullptr;
1291 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1292 NapiX509Certificate *x509Cert = nullptr;
1293 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1294 if (x509Cert == nullptr) {
1295 LOGE("x509Cert is nullptr!");
1296 return nullptr;
1297 }
1298 return x509Cert->GetBasicConstraints(env, info);
1299 }
1300
NapiGetSubjectAlternativeNames(napi_env env,napi_callback_info info)1301 static napi_value NapiGetSubjectAlternativeNames(napi_env env, napi_callback_info info)
1302 {
1303 napi_value thisVar = nullptr;
1304 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1305 NapiX509Certificate *x509Cert = nullptr;
1306 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1307 if (x509Cert == nullptr) {
1308 LOGE("x509Cert is nullptr!");
1309 return nullptr;
1310 }
1311 return x509Cert->GetSubjectAlternativeNames(env, info);
1312 }
1313
NapiGetIssuerAlternativeNames(napi_env env,napi_callback_info info)1314 static napi_value NapiGetIssuerAlternativeNames(napi_env env, napi_callback_info info)
1315 {
1316 napi_value thisVar = nullptr;
1317 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1318 NapiX509Certificate *x509Cert = nullptr;
1319 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1320 if (x509Cert == nullptr) {
1321 LOGE("x509Cert is nullptr!");
1322 return nullptr;
1323 }
1324 return x509Cert->GetIssuerAlternativeNames(env, info);
1325 }
1326
NapiGetItem(napi_env env,napi_callback_info info)1327 static napi_value NapiGetItem(napi_env env, napi_callback_info info)
1328 {
1329 napi_value thisVar = nullptr;
1330 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1331 NapiX509Certificate *x509Cert = nullptr;
1332 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1333 if (x509Cert == nullptr) {
1334 LOGE("x509Cert is nullptr!");
1335 return nullptr;
1336 }
1337 CfObject *obj = x509Cert->GetCertObject();
1338 if (obj == nullptr) {
1339 LOGE("object is nullptr!");
1340 return nullptr;
1341 }
1342
1343 return CommonOperation(env, info, obj, OPERATION_TYPE_GET, CF_GET_TYPE_CERT_ITEM);
1344 }
1345
NapiGetCRLDistributionPointsURI(napi_env env,napi_callback_info info)1346 static napi_value NapiGetCRLDistributionPointsURI(napi_env env, napi_callback_info info)
1347 {
1348 napi_value thisVar = nullptr;
1349 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1350 NapiX509Certificate *x509Cert = nullptr;
1351 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1352 if (x509Cert == nullptr) {
1353 LOGE("x509Cert is nullptr!");
1354 return nullptr;
1355 }
1356 return x509Cert->GetCRLDistributionPointsURI(env, info);
1357 }
1358
NapiMatch(napi_env env,napi_callback_info info)1359 static napi_value NapiMatch(napi_env env, napi_callback_info info)
1360 {
1361 napi_value thisVar = nullptr;
1362 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1363 NapiX509Certificate *x509Cert = nullptr;
1364 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1365 if (x509Cert == nullptr) {
1366 LOGE("x509Cert is nullptr!");
1367 return nullptr;
1368 }
1369 return x509Cert->Match(env, info);
1370 }
1371 // v3
NapiToString(napi_env env,napi_callback_info info)1372 static napi_value NapiToString(napi_env env, napi_callback_info info)
1373 {
1374 size_t argc = ARGS_SIZE_ONE;
1375 napi_value thisVar = nullptr;
1376 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
1377 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1378 if (argc != 0 && argc != ARGS_SIZE_ONE) {
1379 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "wrong argument num!"));
1380 LOGE("wrong argument num!");
1381 return nullptr;
1382 }
1383 NapiX509Certificate *x509Cert = nullptr;
1384 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1385 if (x509Cert == nullptr) {
1386 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_NAPI, "x509Cert is nullptr!"));
1387 LOGE("x509Cert is nullptr!");
1388 return nullptr;
1389 }
1390
1391 if (argc == ARGS_SIZE_ONE) {
1392 napi_valuetype valueType;
1393 napi_typeof(env, argv[PARAM0], &valueType);
1394 if ((valueType != napi_number)) {
1395 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "wrong argument type!"));
1396 LOGE("wrong argument type!");
1397 return nullptr;
1398 }
1399 CfEncodinigType encodingType;
1400 if (napi_get_value_uint32(env, argv[PARAM0], reinterpret_cast<uint32_t *>(&encodingType)) != napi_ok) {
1401 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_NAPI, "napi_get_value_uint32 failed!"));
1402 LOGE("napi_get_value_uint32 failed!");
1403 return nullptr;
1404 }
1405 return x509Cert->ToStringEx(env, info, encodingType);
1406 }
1407 return x509Cert->ToString(env, info);
1408 }
1409
NapiHashCode(napi_env env,napi_callback_info info)1410 static napi_value NapiHashCode(napi_env env, napi_callback_info info)
1411 {
1412 napi_value thisVar = nullptr;
1413 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1414 NapiX509Certificate *x509Cert = nullptr;
1415 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1416 if (x509Cert == nullptr) {
1417 LOGE("x509Cert is nullptr!");
1418 return nullptr;
1419 }
1420 return x509Cert->HashCode(env, info);
1421 }
1422
NapiGetExtensionsObject(napi_env env,napi_callback_info info)1423 static napi_value NapiGetExtensionsObject(napi_env env, napi_callback_info info)
1424 {
1425 napi_value thisVar = nullptr;
1426 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1427 NapiX509Certificate *x509Cert = nullptr;
1428 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1429 if (x509Cert == nullptr) {
1430 LOGE("x509Cert is nullptr!");
1431 return nullptr;
1432 }
1433 return x509Cert->GetExtensionsObject(env, info);
1434 }
1435
NapiGetIssuerX500DistinguishedName(napi_env env,napi_callback_info info)1436 static napi_value NapiGetIssuerX500DistinguishedName(napi_env env, napi_callback_info info)
1437 {
1438 napi_value thisVar = nullptr;
1439 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1440 NapiX509Certificate *x509Cert = nullptr;
1441 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1442 if (x509Cert == nullptr) {
1443 LOGE("x509Cert is nullptr!");
1444 return nullptr;
1445 }
1446 return x509Cert->GetIssuerX500DistinguishedName(env, info);
1447 }
1448
NapiGetSubjectX500DistinguishedName(napi_env env,napi_callback_info info)1449 static napi_value NapiGetSubjectX500DistinguishedName(napi_env env, napi_callback_info info)
1450 {
1451 napi_value thisVar = nullptr;
1452 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1453 NapiX509Certificate *x509Cert = nullptr;
1454 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1455 if (x509Cert == nullptr) {
1456 LOGE("x509Cert is nullptr!");
1457 return nullptr;
1458 }
1459 return x509Cert->GetSubjectX500DistinguishedName(env, info);
1460 }
1461
CreateX509CertExecute(napi_env env,void * data)1462 void NapiX509Certificate::CreateX509CertExecute(napi_env env, void *data)
1463 {
1464 CfCtx *context = static_cast<CfCtx *>(data);
1465 context->errCode = HcfX509CertificateCreate(context->encodingBlob, &context->cert);
1466 if (context->errCode != CF_SUCCESS) {
1467 context->errMsg = "create X509Cert failed";
1468 return;
1469 }
1470
1471 context->errCode = CfCreate(CF_OBJ_TYPE_CERT, context->encodingBlob, &context->object);
1472 if (context->errCode != CF_SUCCESS) {
1473 context->errMsg = "create certObj failed";
1474 }
1475 }
1476
CreateX509CertComplete(napi_env env,napi_status status,void * data)1477 void NapiX509Certificate::CreateX509CertComplete(napi_env env, napi_status status, void *data)
1478 {
1479 CfCtx *context = static_cast<CfCtx *>(data);
1480 if (context->errCode != CF_SUCCESS) {
1481 LOGE("call create X509Cert failed!");
1482 ReturnResult(env, context, nullptr);
1483 FreeCryptoFwkCtx(env, context);
1484 return;
1485 }
1486 napi_value instance = CreateX509Cert(env);
1487 if (instance == nullptr) {
1488 LOGE("Create x509Cert failed!");
1489 ReturnResult(env, context, nullptr);
1490 FreeCryptoFwkCtx(env, context);
1491 return;
1492 }
1493 NapiX509Certificate *x509CertClass = new (std::nothrow) NapiX509Certificate(context->cert, context->object);
1494 if (x509CertClass == nullptr) {
1495 context->errCode = CF_ERR_MALLOC;
1496 context->errMsg = "Failed to create x509Cert class";
1497 LOGE("Failed to create x509Cert class");
1498 CfObjDestroy(context->cert);
1499 if (context->object != nullptr) {
1500 context->object->destroy(&(context->object));
1501 }
1502 ReturnResult(env, context, nullptr);
1503 FreeCryptoFwkCtx(env, context);
1504 return;
1505 }
1506 status = napi_wrap(
1507 env, instance, x509CertClass,
1508 [](napi_env env, void *data, void *hint) {
1509 NapiX509Certificate *certClass = static_cast<NapiX509Certificate *>(data);
1510 delete certClass;
1511 return;
1512 },
1513 nullptr, nullptr);
1514 if (status != napi_ok) {
1515 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_NAPI, "failed to wrap obj!"));
1516 LOGE("failed to wrap obj!");
1517 delete x509CertClass;
1518 return;
1519 }
1520 ReturnResult(env, context, instance);
1521 FreeCryptoFwkCtx(env, context);
1522 }
1523
NapiCreateX509Cert(napi_env env,napi_callback_info info)1524 napi_value NapiX509Certificate::NapiCreateX509Cert(napi_env env, napi_callback_info info)
1525 {
1526 size_t argc = ARGS_SIZE_TWO;
1527 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
1528 napi_value thisVar = nullptr;
1529 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1530 if (!CertCheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) {
1531 return nullptr;
1532 }
1533
1534 CfCtx *context = static_cast<CfCtx *>(CfMalloc(sizeof(CfCtx), 0));
1535 if (context == nullptr) {
1536 LOGE("malloc context failed!");
1537 return nullptr;
1538 }
1539 if (!GetEncodingBlobFromValue(env, argv[PARAM0], &context->encodingBlob)) {
1540 LOGE("get encoding blob from data failed!");
1541 FreeCryptoFwkCtx(env, context);
1542 return nullptr;
1543 }
1544
1545 if (napi_create_reference(env, thisVar, 1, &context->cfRef) != napi_ok) {
1546 LOGE("create reference failed!");
1547 FreeCryptoFwkCtx(env, context);
1548 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create reference failed"));
1549 return nullptr;
1550 }
1551
1552 if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, argv[PARAM1])) {
1553 FreeCryptoFwkCtx(env, context);
1554 return nullptr;
1555 }
1556
1557 napi_create_async_work(
1558 env, nullptr, CertGetResourceName(env, "CreateX509Cert"),
1559 CreateX509CertExecute,
1560 CreateX509CertComplete,
1561 static_cast<void *>(context),
1562 &context->asyncWork);
1563
1564 napi_queue_async_work(env, context->asyncWork);
1565 if (context->asyncType == ASYNC_TYPE_PROMISE) {
1566 return context->promise;
1567 } else {
1568 return CertNapiGetNull(env);
1569 }
1570 }
1571
X509CertConstructor(napi_env env,napi_callback_info info)1572 static napi_value X509CertConstructor(napi_env env, napi_callback_info info)
1573 {
1574 napi_value thisVar = nullptr;
1575 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1576 return thisVar;
1577 }
1578
FreeCsrCfBlobArray(HcfAttributes * array,uint32_t arrayLen)1579 static void FreeCsrCfBlobArray(HcfAttributes *array, uint32_t arrayLen)
1580 {
1581 if (array == NULL) {
1582 return;
1583 }
1584
1585 for (uint32_t i = 0; i < arrayLen; ++i) {
1586 CfFree(array[i].attributeName);
1587 array[i].attributeName = nullptr;
1588 CfFree(array[i].attributeValue);
1589 array[i].attributeValue = nullptr;
1590 }
1591
1592 CfFree(array);
1593 }
1594
FreeGenCsrConf(HcfGenCsrConf * conf)1595 static void FreeGenCsrConf(HcfGenCsrConf *conf)
1596 {
1597 if (conf == nullptr) {
1598 return;
1599 }
1600 if (conf->attribute.array != NULL) {
1601 FreeCsrCfBlobArray(conf->attribute.array, conf->attribute.attributeSize);
1602 conf->attribute.array = nullptr;
1603 }
1604
1605 if (conf->mdName != nullptr) {
1606 CfFree(conf->mdName);
1607 conf->mdName = nullptr;
1608 }
1609
1610 CfFree(conf);
1611 }
1612
AllocateAndCopyString(napi_env env,napi_value strValue,const std::string & fieldName)1613 static char* AllocateAndCopyString(napi_env env, napi_value strValue, const std::string& fieldName)
1614 {
1615 size_t strLen = 0;
1616 if (napi_get_value_string_utf8(env, strValue, nullptr, 0, &strLen) != napi_ok) {
1617 LOGE("get string length failed for %{public}s", fieldName.c_str());
1618 return nullptr;
1619 }
1620 if (strLen == 0) {
1621 LOGE("invalid string length for %{public}s", fieldName.c_str());
1622 return nullptr;
1623 }
1624
1625 char *buffer = static_cast<char *>(CfMalloc(strLen + 1, 0));
1626 if (buffer == nullptr) {
1627 LOGE("malloc failed for %{public}s", fieldName.c_str());
1628 return nullptr;
1629 }
1630
1631 if (napi_get_value_string_utf8(env, strValue, buffer, strLen + 1, &strLen) != napi_ok) {
1632 LOGE("get string value failed for %{public}s", fieldName.c_str());
1633 free(buffer);
1634 return nullptr;
1635 }
1636
1637 return buffer;
1638 }
1639
GetX509CsrSubject(napi_env env,napi_value arg,HcfX509DistinguishedName ** subject)1640 static bool GetX509CsrSubject(napi_env env, napi_value arg, HcfX509DistinguishedName **subject)
1641 {
1642 napi_value value = nullptr;
1643 if (napi_get_named_property(env, arg, CERT_CSR_CONF_SUBJECT.c_str(), &value) != napi_ok) {
1644 LOGE("get subject property failed");
1645 return false;
1646 }
1647 NapiX509DistinguishedName *x509NameClass = nullptr;
1648 HcfX509DistinguishedName *distinguishedName = nullptr;
1649 napi_unwrap(env, value, reinterpret_cast<void **>(&x509NameClass));
1650 if (x509NameClass == nullptr) {
1651 LOGE("x509NameClass is nullptr!");
1652 return false;
1653 }
1654 distinguishedName = x509NameClass->GetX509DistinguishedName();
1655 if (distinguishedName == nullptr) {
1656 LOGE("distinguishedName is nullptr!");
1657 return false;
1658 }
1659 *subject = distinguishedName;
1660 return true;
1661 }
1662
ValidateArrayInput(napi_env env,napi_value object,uint32_t * length)1663 static bool ValidateArrayInput(napi_env env, napi_value object, uint32_t *length)
1664 {
1665 bool isArray = false;
1666 if (napi_is_array(env, object, &isArray) != napi_ok || !isArray) {
1667 LOGE("not array!");
1668 return false;
1669 }
1670
1671 if (napi_get_array_length(env, object, length) != napi_ok || *length == 0) {
1672 LOGE("array length is invalid!");
1673 return false;
1674 }
1675
1676 if (*length > MAX_LEN_OF_ARRAY) {
1677 LOGE("array length is invalid!");
1678 return false;
1679 }
1680 return true;
1681 }
1682
GetStringFromValue(napi_env env,napi_value value,char ** outStr)1683 static bool GetStringFromValue(napi_env env, napi_value value, char **outStr)
1684 {
1685 size_t strLen;
1686 if (napi_get_value_string_utf8(env, value, nullptr, 0, &strLen) != napi_ok) {
1687 LOGE("get string length failed");
1688 return false;
1689 }
1690
1691 if (strLen >= CF_PARAM_SET_MAX_SIZE) {
1692 LOGE("string length would cause overflow");
1693 return false;
1694 }
1695 *outStr = static_cast<char *>(CfMalloc(strLen + 1, 0));
1696 if (*outStr == nullptr ||
1697 napi_get_value_string_utf8(env, value, *outStr, strLen + 1, nullptr) != napi_ok) {
1698 LOGE("get string value failed");
1699 CfFree(*outStr);
1700 *outStr = nullptr;
1701 return false;
1702 }
1703 return true;
1704 }
1705
ProcessArrayElement(napi_env env,napi_value value,HcfAttributesArray * attributeArray,uint32_t length)1706 static bool ProcessArrayElement(napi_env env, napi_value value, HcfAttributesArray *attributeArray, uint32_t length)
1707 {
1708 HcfAttributes *array = static_cast<HcfAttributes *>(CfMalloc(length * sizeof(HcfAttributes), 0));
1709 if (array == nullptr) {
1710 LOGE("malloc failed");
1711 return false;
1712 }
1713 for (uint32_t i = 0; i < length; i++) {
1714 napi_value element;
1715 if (napi_get_element(env, value, i, &element) == napi_ok) {
1716 napi_value obj = GetProp(env, element, CERT_ATTRIBUTE_TYPE.c_str());
1717 if (obj == nullptr || !GetStringFromValue(env, obj, &array[i].attributeName)) {
1718 LOGE("Failed to get type!");
1719 FreeCsrCfBlobArray(array, length);
1720 return false;
1721 }
1722 obj = GetProp(env, element, CERT_ATTRIBUTE_VALUE.c_str());
1723 if (obj == nullptr || !GetStringFromValue(env, obj, &array[i].attributeValue)) {
1724 LOGE("Failed to get value!");
1725 FreeCsrCfBlobArray(array, length);
1726 return false;
1727 }
1728 }
1729 }
1730 attributeArray->array = array;
1731 attributeArray->attributeSize = length;
1732 return true;
1733 }
1734
GetX509CsrAttributeArray(napi_env env,napi_value object,HcfAttributesArray * attributeArray)1735 static bool GetX509CsrAttributeArray(napi_env env, napi_value object, HcfAttributesArray *attributeArray)
1736 {
1737 napi_value value = nullptr;
1738 bool hasProperty = false;
1739
1740 napi_status status = napi_has_named_property(env, object, CERT_CSR_CONF_ATTRIBUTES.c_str(), &hasProperty);
1741 if (status != napi_ok) {
1742 LOGE("check attributes property failed");
1743 return false;
1744 }
1745
1746 if (!hasProperty) {
1747 LOGD("attributes property not found, it's optional");
1748 attributeArray->attributeSize = 0;
1749 attributeArray->array = nullptr;
1750 return true;
1751 }
1752 if (napi_get_named_property(env, object, CERT_CSR_CONF_ATTRIBUTES.c_str(), &value) != napi_ok) {
1753 LOGE("get attributes property failed");
1754 return false;
1755 }
1756 uint32_t length;
1757 if (!ValidateArrayInput(env, value, &length)) {
1758 LOGE("validate array input failed");
1759 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "validate array input failed"));
1760 return false;
1761 }
1762 if (!ProcessArrayElement(env, value, attributeArray, length)) {
1763 LOGE("get attributeArray failed.");
1764 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get attribute array failed"));
1765 return false;
1766 }
1767 return true;
1768 }
1769
IsValidMdName(const char * mdName)1770 static bool IsValidMdName(const char *mdName)
1771 {
1772 const char* validNames[] = {"SHA1", "SHA256", "SHA384", "SHA512"};
1773 const int validNamesCount = sizeof(validNames) / sizeof(validNames[0]);
1774
1775 for (int i = 0; i < validNamesCount; i++) {
1776 if (strcasecmp(mdName, validNames[i]) == 0) {
1777 return true;
1778 }
1779 }
1780 return false;
1781 }
1782
GetX509CsrMdName(napi_env env,napi_value arg,char ** mdName)1783 static bool GetX509CsrMdName(napi_env env, napi_value arg, char **mdName)
1784 {
1785 napi_value value = nullptr;
1786 if (napi_get_named_property(env, arg, CERT_MDNAME.c_str(), &value) != napi_ok) {
1787 LOGE("get mdName property failed");
1788 return false;
1789 }
1790 char *tmpMdName = AllocateAndCopyString(env, value, CERT_MDNAME);
1791 if (tmpMdName == nullptr) {
1792 return false;
1793 }
1794 if (!IsValidMdName(tmpMdName)) {
1795 CfFree(tmpMdName);
1796 tmpMdName = nullptr;
1797 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "invalid mdName"));
1798 return false;
1799 }
1800 *mdName = tmpMdName;
1801 return true;
1802 }
1803
GetX509CsrIsPem(napi_env env,napi_value arg,bool * isPem)1804 static bool GetX509CsrIsPem(napi_env env, napi_value arg, bool *isPem)
1805 {
1806 napi_value value = nullptr;
1807 bool hasProperty = false;
1808 napi_status status = napi_has_named_property(env, arg, CERT_CSR_CONF_OUT_FORMAT.c_str(), &hasProperty);
1809 if (status != napi_ok) {
1810 LOGE("check outFormat property failed");
1811 return false;
1812 }
1813
1814 if (!hasProperty) {
1815 LOGD("outFormat property not found, use default PEM format");
1816 *isPem = true;
1817 return true;
1818 }
1819 if (napi_get_named_property(env, arg, CERT_CSR_CONF_OUT_FORMAT.c_str(), &value) != napi_ok) {
1820 LOGE("get outFormat property failed");
1821 return false;
1822 }
1823 uint32_t format = 0;
1824 if (napi_get_value_uint32(env, value, &format) != napi_ok) {
1825 LOGE("get format value failed");
1826 return false;
1827 }
1828 switch (format) {
1829 case 0:
1830 *isPem = true;
1831 break;
1832 case 1:
1833 *isPem = false;
1834 break;
1835 default:
1836 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "invalid format value"));
1837 return false;
1838 }
1839 return true;
1840 }
1841
BuildX509CsrConf(napi_env env,napi_value arg,HcfGenCsrConf ** conf)1842 static bool BuildX509CsrConf(napi_env env, napi_value arg, HcfGenCsrConf **conf)
1843 {
1844 napi_valuetype valueType;
1845 napi_typeof(env, arg, &valueType);
1846 if (valueType != napi_object) {
1847 LOGE("wrong argument type. expect object type. [Type]: %{public}d", valueType);
1848 return false;
1849 }
1850 HcfGenCsrConf *tmpConf = static_cast<HcfGenCsrConf *>(CfMalloc(sizeof(HcfGenCsrConf), 0));
1851 if (tmpConf == nullptr) {
1852 LOGE("malloc conf failed");
1853 return false;
1854 }
1855
1856 if (!GetX509CsrSubject(env, arg, &tmpConf->subject)) {
1857 CfFree(tmpConf);
1858 tmpConf = nullptr;
1859 return false;
1860 }
1861 if (!GetX509CsrAttributeArray(env, arg, &tmpConf->attribute)) {
1862 FreeGenCsrConf(tmpConf);
1863 tmpConf = nullptr;
1864 return false;
1865 }
1866 if (!GetX509CsrMdName(env, arg, &tmpConf->mdName)) {
1867 FreeGenCsrConf(tmpConf);
1868 tmpConf = nullptr;
1869 return false;
1870 }
1871 if (!GetX509CsrIsPem(env, arg, &tmpConf->isPem)) {
1872 FreeGenCsrConf(tmpConf);
1873 tmpConf = nullptr;
1874 return false;
1875 }
1876 *conf = tmpConf;
1877 return true;
1878 }
1879
CreatePemResult(napi_env env,const CfBlob & csrBlob)1880 static napi_value CreatePemResult(napi_env env, const CfBlob &csrBlob)
1881 {
1882 napi_value result = nullptr;
1883 napi_status status = napi_create_string_utf8(env, reinterpret_cast<char *>(csrBlob.data), csrBlob.size, &result);
1884 if (status != napi_ok) {
1885 LOGE("create string failed");
1886 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_CRYPTO_OPERATION, "create string failed!"));
1887 return nullptr;
1888 }
1889 return result;
1890 }
1891
CreateDerResult(napi_env env,const CfBlob & csrBlob)1892 static napi_value CreateDerResult(napi_env env, const CfBlob &csrBlob)
1893 {
1894 napi_value result = nullptr;
1895 napi_value arrayBuffer;
1896 void* bufferData;
1897
1898 napi_create_arraybuffer(env, csrBlob.size, &bufferData, &arrayBuffer);
1899 if (memcpy_s(bufferData, csrBlob.size, csrBlob.data, csrBlob.size) != EOK) {
1900 LOGE("memcpy_s csrString to buffer failed!");
1901 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_COPY, "copy memory failed!"));
1902 return nullptr;
1903 }
1904
1905 napi_status status = napi_create_typedarray(env, napi_uint8_array, csrBlob.size, arrayBuffer, 0, &result);
1906 if (status != napi_ok) {
1907 LOGE("create uint8 array failed");
1908 napi_throw(env, CertGenerateBusinessError(env, CF_ERR_CRYPTO_OPERATION, "create array failed!"));
1909 return nullptr;
1910 }
1911 return result;
1912 }
1913
GenerateCsr(napi_env env,size_t argc,napi_value param1,napi_value param2)1914 static napi_value GenerateCsr(napi_env env, size_t argc, napi_value param1, napi_value param2)
1915 {
1916 if (!CertCheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) {
1917 LOGE("check args count failed");
1918 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "check args count failed!"));
1919 return nullptr;
1920 }
1921 PrivateKeyInfo *privateKey = nullptr;
1922 if (!GetPrivateKeyInfoFromValue(env, param1, &privateKey)) {
1923 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get private key info from data failed!"));
1924 LOGE("get private key info from data failed!");
1925 return nullptr;
1926 }
1927 HcfGenCsrConf *conf = nullptr;
1928 if (!BuildX509CsrConf(env, param2, &conf)) {
1929 napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "get csr conf failed"));
1930 LOGE("get csr conf failed");
1931 FreePrivateKeyInfo(privateKey);
1932 return nullptr;
1933 }
1934 CfBlob csrBlob = {0};
1935 CfResult ret = HcfX509CertificateGenCsr(privateKey, conf, &csrBlob);
1936 if (ret != CF_SUCCESS) {
1937 LOGE("generate csr failed, ret: %{public}d", ret);
1938 FreeGenCsrConf(conf);
1939 conf = nullptr;
1940 FreePrivateKeyInfo(privateKey);
1941 napi_throw(env, CertGenerateBusinessError(env, ret, "generate csr failed!"));
1942 return nullptr;
1943 }
1944 napi_value result = conf->isPem ? CreatePemResult(env, csrBlob) : CreateDerResult(env, csrBlob);
1945 FreePrivateKeyInfo(privateKey);
1946 FreeGenCsrConf(conf);
1947 conf = nullptr;
1948 CfBlobDataFree(&csrBlob);
1949 return result;
1950 }
1951
NapiGenerateCsr(napi_env env,napi_callback_info info)1952 napi_value NapiX509Certificate::NapiGenerateCsr(napi_env env, napi_callback_info info)
1953 {
1954 size_t argc = ARGS_SIZE_TWO;
1955 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
1956 napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
1957 napi_value instance = GenerateCsr(env, argc, argv[PARAM0], argv[PARAM1]);
1958 return instance;
1959 }
1960
DefineX509CertJSClass(napi_env env,napi_value exports)1961 void NapiX509Certificate::DefineX509CertJSClass(napi_env env, napi_value exports)
1962 {
1963 napi_property_descriptor desc[] = {
1964 DECLARE_NAPI_FUNCTION("createX509Cert", NapiCreateX509Cert),
1965 DECLARE_NAPI_FUNCTION("generateCsr", NapiGenerateCsr),
1966 };
1967 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1968
1969 napi_property_descriptor x509CertDesc[] = {
1970 DECLARE_NAPI_FUNCTION("verify", NapiVerify),
1971 DECLARE_NAPI_FUNCTION("getEncoded", NapiGetEncoded),
1972 DECLARE_NAPI_FUNCTION("getPublicKey", NapiGetPublicKey),
1973 DECLARE_NAPI_FUNCTION("checkValidityWithDate", NapiCheckValidityWithDate),
1974 DECLARE_NAPI_FUNCTION("getVersion", NapiGetVersion),
1975 DECLARE_NAPI_FUNCTION("getSerialNumber", NapiGetSerialNumber),
1976 DECLARE_NAPI_FUNCTION("getCertSerialNumber", NapiGetCertSerialNumber),
1977 DECLARE_NAPI_FUNCTION("getIssuerName", NapiGetIssuerName),
1978 DECLARE_NAPI_FUNCTION("getSubjectName", NapiGetSubjectName),
1979 DECLARE_NAPI_FUNCTION("getNotBeforeTime", NapiGetNotBeforeTime),
1980 DECLARE_NAPI_FUNCTION("getNotAfterTime", NapiGetNotAfterTime),
1981 DECLARE_NAPI_FUNCTION("getSignature", NapiGetSignature),
1982 DECLARE_NAPI_FUNCTION("getSignatureAlgName", NapiGetSigAlgName),
1983 DECLARE_NAPI_FUNCTION("getSignatureAlgOid", NapiGetSigAlgOID),
1984 DECLARE_NAPI_FUNCTION("getSignatureAlgParams", NapiGetSigAlgParams),
1985 DECLARE_NAPI_FUNCTION("getKeyUsage", NapiGetKeyUsage),
1986 DECLARE_NAPI_FUNCTION("getExtKeyUsage", NapiGetExtendedKeyUsage),
1987 DECLARE_NAPI_FUNCTION("getBasicConstraints", NapiGetBasicConstraints),
1988 DECLARE_NAPI_FUNCTION("getSubjectAltNames", NapiGetSubjectAlternativeNames),
1989 DECLARE_NAPI_FUNCTION("getIssuerAltNames", NapiGetIssuerAlternativeNames),
1990 DECLARE_NAPI_FUNCTION("getItem", NapiGetItem),
1991 DECLARE_NAPI_FUNCTION("match", NapiMatch),
1992 DECLARE_NAPI_FUNCTION("toString", NapiToString),
1993 DECLARE_NAPI_FUNCTION("hashCode", NapiHashCode),
1994 DECLARE_NAPI_FUNCTION("getExtensionsObject", NapiGetExtensionsObject),
1995 DECLARE_NAPI_FUNCTION("getIssuerX500DistinguishedName", NapiGetIssuerX500DistinguishedName),
1996 DECLARE_NAPI_FUNCTION("getSubjectX500DistinguishedName", NapiGetSubjectX500DistinguishedName),
1997 DECLARE_NAPI_FUNCTION("getCRLDistributionPoint", NapiGetCRLDistributionPointsURI),
1998 };
1999 napi_value constructor = nullptr;
2000 napi_define_class(env, "X509Cert", NAPI_AUTO_LENGTH, X509CertConstructor, nullptr,
2001 sizeof(x509CertDesc) / sizeof(x509CertDesc[0]), x509CertDesc, &constructor);
2002 napi_create_reference(env, constructor, 1, &classRef_);
2003 }
2004
CreateX509Cert(napi_env env)2005 napi_value NapiX509Certificate::CreateX509Cert(napi_env env)
2006 {
2007 napi_value constructor = nullptr;
2008 napi_value instance = nullptr;
2009 napi_get_reference_value(env, classRef_, &constructor);
2010 napi_new_instance(env, constructor, 0, nullptr, &instance);
2011 return instance;
2012 }
2013 } // namespace CertFramework
2014 } // namespace OHOS
2015