• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_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