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