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 namespace OHOS {
36 namespace CertFramework {
37 thread_local napi_ref NapiX509Certificate::classRef_ = nullptr;
38 
39 struct CfCtx {
40     AsyncType asyncType = ASYNC_TYPE_CALLBACK;
41     napi_value promise = nullptr;
42     napi_ref callback = nullptr;
43     napi_deferred deferred = nullptr;
44     napi_async_work asyncWork = nullptr;
45     napi_ref cfRef = nullptr;
46     napi_ref pubKeyParamsRef = nullptr;
47 
48     CfEncodingBlob *encodingBlob = nullptr;
49     NapiX509Certificate *certClass = nullptr;
50     HcfPubKey *pubKey = nullptr;
51 
52     int32_t errCode = 0;
53     const char *errMsg = nullptr;
54     HcfX509Certificate *cert = nullptr;
55     CfObject *object = nullptr;
56     CfEncodingBlob *encoded = nullptr;
57 };
58 
NapiX509Certificate(HcfX509Certificate * x509Cert,CfObject * object)59 NapiX509Certificate::NapiX509Certificate(HcfX509Certificate *x509Cert, CfObject *object)
60 {
61     this->x509Cert_ = x509Cert;
62     this->certObject_ = object;
63 }
64 
~NapiX509Certificate()65 NapiX509Certificate::~NapiX509Certificate()
66 {
67     CfObjDestroy(this->x509Cert_);
68     if (this->certObject_ != nullptr) {
69         this->certObject_->destroy(&(this->certObject_));
70     }
71 }
72 
FreeCryptoFwkCtx(napi_env env,CfCtx * context)73 static void FreeCryptoFwkCtx(napi_env env, CfCtx *context)
74 {
75     if (context == nullptr) {
76         return;
77     }
78 
79     if (context->asyncWork != nullptr) {
80         napi_delete_async_work(env, context->asyncWork);
81     }
82 
83     if (context->callback != nullptr) {
84         napi_delete_reference(env, context->callback);
85     }
86 
87     if (context->cfRef != nullptr) {
88         napi_delete_reference(env, context->cfRef);
89         context->cfRef = nullptr;
90     }
91     if (context->pubKeyParamsRef != nullptr) {
92         napi_delete_reference(env, context->pubKeyParamsRef);
93         context->pubKeyParamsRef = nullptr;
94     }
95 
96     CfEncodingBlobDataFree(context->encodingBlob);
97     CfFree(context->encodingBlob);
98     context->encodingBlob = nullptr;
99 
100     CfEncodingBlobDataFree(context->encoded);
101     CfFree(context->encoded);
102     context->encoded = nullptr;
103 
104     CfFree(context);
105 }
106 
ReturnCallbackResult(napi_env env,CfCtx * context,napi_value result)107 static void ReturnCallbackResult(napi_env env, CfCtx *context, napi_value result)
108 {
109     napi_value businessError = nullptr;
110     if (context->errCode != CF_SUCCESS) {
111         businessError = CertGenerateBusinessError(env, context->errCode, context->errMsg);
112     }
113     napi_value params[ARGS_SIZE_TWO] = { businessError, result };
114 
115     napi_value func = nullptr;
116     napi_get_reference_value(env, context->callback, &func);
117 
118     napi_value recv = nullptr;
119     napi_value callFuncRet = nullptr;
120     napi_get_undefined(env, &recv);
121     napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
122 }
123 
ReturnPromiseResult(napi_env env,CfCtx * context,napi_value result)124 static void ReturnPromiseResult(napi_env env, CfCtx *context, napi_value result)
125 {
126     if (context->errCode == CF_SUCCESS) {
127         napi_resolve_deferred(env, context->deferred, result);
128     } else {
129         napi_reject_deferred(env, context->deferred,
130             CertGenerateBusinessError(env, context->errCode, context->errMsg));
131     }
132 }
133 
ReturnResult(napi_env env,CfCtx * context,napi_value result)134 static void ReturnResult(napi_env env, CfCtx *context, napi_value result)
135 {
136     if (context->asyncType == ASYNC_TYPE_CALLBACK) {
137         ReturnCallbackResult(env, context, result);
138     } else {
139         ReturnPromiseResult(env, context, result);
140     }
141 }
142 
CreateCallbackAndPromise(napi_env env,CfCtx * context,size_t argc,size_t maxCount,napi_value callbackValue)143 static bool CreateCallbackAndPromise(napi_env env, CfCtx *context, size_t argc,
144     size_t maxCount, napi_value callbackValue)
145 {
146     context->asyncType = GetAsyncType(env, argc, maxCount, callbackValue);
147     if (context->asyncType == ASYNC_TYPE_CALLBACK) {
148         if (!CertGetCallbackFromJSParams(env, callbackValue, &context->callback)) {
149             LOGE("x509 certificate: get callback failed!");
150             return false;
151         }
152     } else {
153         napi_create_promise(env, &context->deferred, &context->promise);
154     }
155     return true;
156 }
157 
VerifyExecute(napi_env env,void * data)158 static void VerifyExecute(napi_env env, void *data)
159 {
160     CfCtx *context = static_cast<CfCtx *>(data);
161     HcfX509Certificate *cert = context->certClass->GetX509Cert();
162     context->errCode = cert->base.verify(&(cert->base), context->pubKey);
163     if (context->errCode != CF_SUCCESS) {
164         LOGE("verify cert failed!");
165         context->errMsg = "verify cert failed";
166     }
167 }
168 
VerifyComplete(napi_env env,napi_status status,void * data)169 static void VerifyComplete(napi_env env, napi_status status, void *data)
170 {
171     CfCtx *context = static_cast<CfCtx *>(data);
172     ReturnResult(env, context, CertNapiGetNull(env));
173     FreeCryptoFwkCtx(env, context);
174 }
175 
GetEncodedExecute(napi_env env,void * data)176 static void GetEncodedExecute(napi_env env, void *data)
177 {
178     CfCtx *context = static_cast<CfCtx *>(data);
179     HcfX509Certificate *cert = context->certClass->GetX509Cert();
180     CfEncodingBlob *encodingBlob = static_cast<CfEncodingBlob *>(CfMalloc(sizeof(CfEncodingBlob), 0));
181     if (encodingBlob == nullptr) {
182         LOGE("malloc encoding blob failed!");
183         context->errCode = CF_ERR_MALLOC;
184         context->errMsg = "malloc encoding blob failed";
185         return;
186     }
187     context->errCode = cert->base.getEncoded(&(cert->base), encodingBlob);
188     if (context->errCode != CF_SUCCESS) {
189         LOGE("get cert encoded failed!");
190         context->errMsg = "get cert encoded failed";
191     }
192     context->encoded = encodingBlob;
193 }
194 
GetEncodedComplete(napi_env env,napi_status status,void * data)195 static void GetEncodedComplete(napi_env env, napi_status status, void *data)
196 {
197     CfCtx *context = static_cast<CfCtx *>(data);
198     if (context->errCode != CF_SUCCESS) {
199         ReturnResult(env, context, nullptr);
200         FreeCryptoFwkCtx(env, context);
201         return;
202     }
203     napi_value returnEncodingBlob = ConvertEncodingBlobToNapiValue(env, context->encoded);
204     ReturnResult(env, context, returnEncodingBlob);
205     FreeCryptoFwkCtx(env, context);
206 }
207 
Verify(napi_env env,napi_callback_info info)208 napi_value NapiX509Certificate::Verify(napi_env env, napi_callback_info info)
209 {
210     size_t argc = ARGS_SIZE_TWO;
211     napi_value argv[ARGS_SIZE_TWO] = { nullptr };
212     napi_value thisVar = nullptr;
213     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
214     if (!CertCheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) {
215         return nullptr;
216     }
217 
218     CfCtx *context = static_cast<CfCtx *>(CfMalloc(sizeof(CfCtx), 0));
219     if (context == nullptr) {
220         LOGE("malloc context failed!");
221         return nullptr;
222     }
223     context->certClass = this;
224 
225     NapiPubKey *pubKey = nullptr;
226     napi_unwrap(env, argv[PARAM0], (void**)&pubKey);
227     if (pubKey == nullptr) {
228         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "public key is null"));
229         LOGE("pubKey is null!");
230         FreeCryptoFwkCtx(env, context);
231         return nullptr;
232     }
233     context->pubKey = pubKey->GetPubKey();
234 
235     if (napi_create_reference(env, thisVar, 1, &context->cfRef) != napi_ok) {
236         LOGE("create reference failed!");
237         FreeCryptoFwkCtx(env, context);
238         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create reference failed"));
239         return nullptr;
240     }
241     if (napi_create_reference(env, argv[PARAM0], 1, &context->pubKeyParamsRef) != napi_ok) {
242         LOGE("create param ref failed!");
243         FreeCryptoFwkCtx(env, context);
244         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create param ref failed"));
245         return nullptr;
246     }
247 
248     if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, argv[PARAM1])) {
249         FreeCryptoFwkCtx(env, context);
250         return nullptr;
251     }
252 
253     napi_create_async_work(env, nullptr, CertGetResourceName(env, "Verify"), VerifyExecute, VerifyComplete,
254         static_cast<void *>(context), &context->asyncWork);
255 
256     napi_queue_async_work(env, context->asyncWork);
257     if (context->asyncType == ASYNC_TYPE_PROMISE) {
258         return context->promise;
259     }
260 
261     return CertNapiGetNull(env);
262 }
263 
GetEncoded(napi_env env,napi_callback_info info)264 napi_value NapiX509Certificate::GetEncoded(napi_env env, napi_callback_info info)
265 {
266     size_t argc = ARGS_SIZE_ONE;
267     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
268     napi_value thisVar = nullptr;
269     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
270     if (!CertCheckArgsCount(env, argc, ARGS_SIZE_ONE, false)) {
271         return nullptr;
272     }
273 
274     CfCtx *context = static_cast<CfCtx *>(CfMalloc(sizeof(CfCtx), 0));
275     if (context == nullptr) {
276         LOGE("malloc context failed!");
277         return nullptr;
278     }
279     context->certClass = this;
280     if (napi_create_reference(env, thisVar, 1, &context->cfRef) != napi_ok) {
281         LOGE("create reference failed!");
282         FreeCryptoFwkCtx(env, context);
283         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create reference failed"));
284         return nullptr;
285     }
286 
287     if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_ONE, argv[PARAM0])) {
288         FreeCryptoFwkCtx(env, context);
289         return nullptr;
290     }
291 
292     napi_create_async_work(
293         env, nullptr, CertGetResourceName(env, "GetEncoded"),
294         GetEncodedExecute,
295         GetEncodedComplete,
296         static_cast<void *>(context),
297         &context->asyncWork);
298 
299     napi_queue_async_work(env, context->asyncWork);
300     if (context->asyncType == ASYNC_TYPE_PROMISE) {
301         return context->promise;
302     } else {
303         return CertNapiGetNull(env);
304     }
305 }
306 
GetPublicKey(napi_env env,napi_callback_info info)307 napi_value NapiX509Certificate::GetPublicKey(napi_env env, napi_callback_info info)
308 {
309     HcfX509Certificate *cert = GetX509Cert();
310     HcfPubKey *returnPubKey = nullptr;
311     CfResult ret = cert->base.getPublicKey(&(cert->base), (void **)&returnPubKey);
312     if (ret != CF_SUCCESS) {
313         napi_throw(env, CertGenerateBusinessError(env, ret, "get cert public key failed!"));
314         LOGE("get cert public key failed!");
315         return nullptr;
316     }
317 
318     NapiPubKey *pubKeyClass = new (std::nothrow) NapiPubKey(returnPubKey);
319     if (pubKeyClass == nullptr) {
320         napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "Failed to create a pubkey class"));
321         LOGE("create for x509 cert's public key obj failed");
322         CfObjDestroy(returnPubKey);
323         return nullptr;
324     }
325     napi_value instance = pubKeyClass->ConvertToJsPubKey(env);
326     napi_wrap(
327         env, instance, pubKeyClass,
328         [](napi_env env, void *data, void *hint) {
329             NapiPubKey *pubKeyClass = static_cast<NapiPubKey *>(data);
330             CfObjDestroy(pubKeyClass->GetPubKey());
331             delete pubKeyClass;
332             return;
333         },
334         nullptr, nullptr);
335     return instance;
336 }
337 
CheckValidityWithDate(napi_env env,napi_callback_info info)338 napi_value NapiX509Certificate::CheckValidityWithDate(napi_env env, napi_callback_info info)
339 {
340     size_t argc = ARGS_SIZE_ONE;
341     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
342     napi_value thisVar = nullptr;
343     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
344     if (!CertCheckArgsCount(env, argc, ARGS_SIZE_ONE, true)) {
345         return nullptr;
346     }
347     std::string date;
348     if (!CertGetStringFromJSParams(env, argv[PARAM0], date)) {
349         LOGE("get date param failed!");
350         return nullptr;
351     }
352     HcfX509Certificate *cert = GetX509Cert();
353     CfResult ret = cert->checkValidityWithDate(cert, date.c_str());
354     if (ret != CF_SUCCESS) {
355         napi_throw(env, CertGenerateBusinessError(env, ret, "check cert validity failed!"));
356         LOGE("check cert validity failed!");
357     }
358     return nullptr;
359 }
360 
GetVersion(napi_env env,napi_callback_info info)361 napi_value NapiX509Certificate::GetVersion(napi_env env, napi_callback_info info)
362 {
363     HcfX509Certificate *cert = GetX509Cert();
364     int version = cert->getVersion(cert);
365     napi_value result = nullptr;
366     napi_create_int32(env, version, &result);
367     return result;
368 }
369 
GetSerialNumber(napi_env env,napi_callback_info info)370 napi_value NapiX509Certificate::GetSerialNumber(napi_env env, napi_callback_info info)
371 {
372     HcfX509Certificate *cert = GetX509Cert();
373     CfBlob blob = { 0, nullptr };
374     CfResult ret = cert->getSerialNumber(cert, &blob);
375     if (ret != CF_SUCCESS) {
376         napi_throw(env, CertGenerateBusinessError(env, ret, "cert get serial num failed"));
377         LOGE("cert get serial num failed!");
378         return nullptr;
379     }
380 
381     napi_value result = ConvertBlobToInt64(env, blob);
382     CfBlobDataFree(&blob);
383     return result;
384 }
385 
GetCertSerialNumber(napi_env env,napi_callback_info info)386 napi_value NapiX509Certificate::GetCertSerialNumber(napi_env env, napi_callback_info info)
387 {
388     HcfX509Certificate *cert = GetX509Cert();
389     CfBlob blob = { 0, nullptr };
390     CfResult ret = cert->getSerialNumber(cert, &blob);
391     if (ret != CF_SUCCESS) {
392         napi_throw(env, CertGenerateBusinessError(env, ret, "cert get serial num failed"));
393         LOGE("cert get serial num failed!");
394         return nullptr;
395     }
396 
397     napi_value result = ConvertBlobToBigIntWords(env, blob);
398     CfBlobDataFree(&blob);
399     return result;
400 }
401 
GetIssuerName(napi_env env,napi_callback_info info)402 napi_value NapiX509Certificate::GetIssuerName(napi_env env, napi_callback_info info)
403 {
404     CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
405     if (blob == nullptr) {
406         LOGE("malloc blob failed!");
407         return nullptr;
408     }
409     HcfX509Certificate *cert = GetX509Cert();
410     CfResult ret = cert->getIssuerName(cert, blob);
411     if (ret != CF_SUCCESS) {
412         napi_throw(env, CertGenerateBusinessError(env, ret, "get issuer name failed"));
413         LOGE("getIssuerName failed!");
414         CfFree(blob);
415         blob = nullptr;
416         return nullptr;
417     }
418     napi_value returnValue = CertConvertBlobToNapiValue(env, blob);
419     CfBlobDataFree(blob);
420     CfFree(blob);
421     blob = nullptr;
422     return returnValue;
423 }
424 
GetSubjectName(napi_env env,napi_callback_info info)425 napi_value NapiX509Certificate::GetSubjectName(napi_env env, napi_callback_info info)
426 {
427     CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
428     if (blob == nullptr) {
429         LOGE("malloc blob failed!");
430         return nullptr;
431     }
432     HcfX509Certificate *cert = GetX509Cert();
433     CfResult ret = cert->getSubjectName(cert, blob);
434     if (ret != CF_SUCCESS) {
435         napi_throw(env, CertGenerateBusinessError(env, ret, "get subject name failed"));
436         LOGE("getSubjectName failed!");
437         CfFree(blob);
438         blob = nullptr;
439         return nullptr;
440     }
441     napi_value returnValue = CertConvertBlobToNapiValue(env, blob);
442     CfBlobDataFree(blob);
443     CfFree(blob);
444     blob = nullptr;
445     return returnValue;
446 }
447 
GetSubjectNameEx(napi_env env,napi_callback_info info,CfEncodinigType encodingType)448 napi_value NapiX509Certificate::GetSubjectNameEx(napi_env env, napi_callback_info info, CfEncodinigType encodingType)
449 {
450     CfBlob blob = { 0, nullptr };
451     HcfX509Certificate *cert = GetX509Cert();
452     CfResult ret = cert->getSubjectNameEx(cert, encodingType, &blob);
453     if (ret != CF_SUCCESS) {
454         napi_throw(env, CertGenerateBusinessError(env, ret, "GetSubjectNameEx failed."));
455         LOGE("GetSubjectNameEx failed!");
456         return nullptr;
457     }
458     napi_value returnValue = CertConvertBlobToNapiValue(env, &blob);
459     CfBlobDataFree(&blob);
460     return returnValue;
461 }
462 
GetNotBeforeTime(napi_env env,napi_callback_info info)463 napi_value NapiX509Certificate::GetNotBeforeTime(napi_env env, napi_callback_info info)
464 {
465     CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
466     if (blob == nullptr) {
467         LOGE("malloc blob failed!");
468         return nullptr;
469     }
470     HcfX509Certificate *cert = GetX509Cert();
471     CfResult res = cert->getNotBeforeTime(cert, blob);
472     if (res != CF_SUCCESS) {
473         napi_throw(env, CertGenerateBusinessError(env, res, "get not before time failed"));
474         LOGE("getNotBeforeTime failed!");
475         CfFree(blob);
476         blob = nullptr;
477         return nullptr;
478     }
479     napi_value result = nullptr;
480     uint32_t size = blob->data[blob->size - 1] == '\0' ? blob->size - 1 : blob->size;
481     napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), size, &result);
482     CfBlobDataFree(blob);
483     CfFree(blob);
484     blob = nullptr;
485     return result;
486 }
487 
GetNotAfterTime(napi_env env,napi_callback_info info)488 napi_value NapiX509Certificate::GetNotAfterTime(napi_env env, napi_callback_info info)
489 {
490     CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
491     if (blob == nullptr) {
492         LOGE("malloc blob failed!");
493         return nullptr;
494     }
495     HcfX509Certificate *cert = GetX509Cert();
496     CfResult res = cert->getNotAfterTime(cert, blob);
497     if (res != CF_SUCCESS) {
498         napi_throw(env, CertGenerateBusinessError(env, res, "get not after time failed"));
499         LOGE("getNotAfterTime failed!");
500         CfFree(blob);
501         blob = nullptr;
502         return nullptr;
503     }
504     napi_value result = nullptr;
505     uint32_t size = blob->data[blob->size - 1] == '\0' ? blob->size - 1 : blob->size;
506     napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), size, &result);
507     CfBlobDataFree(blob);
508     CfFree(blob);
509     blob = nullptr;
510     return result;
511 }
512 
GetSignature(napi_env env,napi_callback_info info)513 napi_value NapiX509Certificate::GetSignature(napi_env env, napi_callback_info info)
514 {
515     CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
516     if (blob == nullptr) {
517         LOGE("malloc blob failed!");
518         return nullptr;
519     }
520     HcfX509Certificate *cert = GetX509Cert();
521     CfResult ret = cert->getSignature(cert, blob);
522     if (ret != CF_SUCCESS) {
523         napi_throw(env, CertGenerateBusinessError(env, ret, "get signature failed"));
524         LOGE("getSignature failed!");
525         CfFree(blob);
526         blob = nullptr;
527         return nullptr;
528     }
529     napi_value returnValue = CertConvertBlobToNapiValue(env, blob);
530     CfBlobDataFree(blob);
531     CfFree(blob);
532     blob = nullptr;
533     return returnValue;
534 }
535 
GetSigAlgName(napi_env env,napi_callback_info info)536 napi_value NapiX509Certificate::GetSigAlgName(napi_env env, napi_callback_info info)
537 {
538     CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
539     if (blob == nullptr) {
540         LOGE("malloc blob failed!");
541         return nullptr;
542     }
543     HcfX509Certificate *cert = GetX509Cert();
544     CfResult res = cert->getSignatureAlgName(cert, blob);
545     if (res != CF_SUCCESS) {
546         napi_throw(env, CertGenerateBusinessError(env, res, "get signature alg name failed"));
547         LOGE("getSignatureAlgName failed!");
548         CfFree(blob);
549         blob = nullptr;
550         return nullptr;
551     }
552     napi_value result = nullptr;
553     uint32_t size = blob->data[blob->size - 1] == '\0' ? blob->size - 1 : blob->size;
554     napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), size, &result);
555     CfBlobDataFree(blob);
556     CfFree(blob);
557     blob = nullptr;
558     return result;
559 }
560 
GetSigAlgOID(napi_env env,napi_callback_info info)561 napi_value NapiX509Certificate::GetSigAlgOID(napi_env env, napi_callback_info info)
562 {
563     CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
564     if (blob == nullptr) {
565         LOGE("malloc blob failed!");
566         return nullptr;
567     }
568     HcfX509Certificate *cert = GetX509Cert();
569     CfResult res = cert->getSignatureAlgOid(cert, blob);
570     if (res != CF_SUCCESS) {
571         napi_throw(env, CertGenerateBusinessError(env, res, "get signature alg oid failed"));
572         LOGE("getSignatureAlgOid failed!");
573         CfFree(blob);
574         blob = nullptr;
575         return nullptr;
576     }
577     napi_value result = nullptr;
578     uint32_t size = blob->data[blob->size - 1] == '\0' ? blob->size - 1 : blob->size;
579     napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), size, &result);
580     CfBlobDataFree(blob);
581     CfFree(blob);
582     blob = nullptr;
583     return result;
584 }
585 
GetSigAlgParams(napi_env env,napi_callback_info info)586 napi_value NapiX509Certificate::GetSigAlgParams(napi_env env, napi_callback_info info)
587 {
588     CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
589     if (blob == nullptr) {
590         LOGE("malloc blob failed!");
591         return nullptr;
592     }
593     HcfX509Certificate *cert = GetX509Cert();
594     CfResult ret = cert->getSignatureAlgParams(cert, blob);
595     if (ret != CF_SUCCESS) {
596         napi_throw(env, CertGenerateBusinessError(env, ret, "get signature alg params failed"));
597         LOGE("getSignatureAlgParams failed!");
598         CfFree(blob);
599         blob = nullptr;
600         return nullptr;
601     }
602     napi_value returnValue = CertConvertBlobToNapiValue(env, blob);
603     CfBlobDataFree(blob);
604     CfFree(blob);
605     blob = nullptr;
606     return returnValue;
607 }
608 
GetKeyUsage(napi_env env,napi_callback_info info)609 napi_value NapiX509Certificate::GetKeyUsage(napi_env env, napi_callback_info info)
610 {
611     CfBlob *blob = reinterpret_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
612     if (blob == nullptr) {
613         LOGE("malloc blob failed!");
614         return nullptr;
615     }
616     HcfX509Certificate *cert = GetX509Cert();
617     CfResult ret = cert->getKeyUsage(cert, blob);
618     if (ret != CF_SUCCESS) {
619         napi_throw(env, CertGenerateBusinessError(env, ret, "get key usage failed"));
620         LOGE("getKeyUsage failed!");
621         CfFree(blob);
622         blob = nullptr;
623         return nullptr;
624     }
625     napi_value returnValue = CertConvertBlobToNapiValue(env, blob);
626     CfBlobDataFree(blob);
627     CfFree(blob);
628     blob = nullptr;
629     return returnValue;
630 }
631 
GetExtendedKeyUsage(napi_env env,napi_callback_info info)632 napi_value NapiX509Certificate::GetExtendedKeyUsage(napi_env env, napi_callback_info info)
633 {
634     CfArray *array = reinterpret_cast<CfArray *>(CfMalloc(sizeof(CfArray), 0));
635     if (array == nullptr) {
636         LOGE("malloc array failed!");
637         return nullptr;
638     }
639     HcfX509Certificate *cert = GetX509Cert();
640     CfResult ret = cert->getExtKeyUsage(cert, array);
641     if (ret != CF_SUCCESS) {
642         napi_throw(env, CertGenerateBusinessError(env, ret, "get ext key usage failed"));
643         LOGE("call getExtKeyUsage failed!");
644         CfFree(array);
645         array = nullptr;
646         return nullptr;
647     }
648     napi_value returnValue = ConvertArrayToNapiValue(env, array);
649     CfArrayDataClearAndFree(array);
650     CfFree(array);
651     array = nullptr;
652     return returnValue;
653 }
654 
655 
GetBasicConstraints(napi_env env,napi_callback_info info)656 napi_value NapiX509Certificate::GetBasicConstraints(napi_env env, napi_callback_info info)
657 {
658     HcfX509Certificate *cert = GetX509Cert();
659     int32_t constrains = cert->getBasicConstraints(cert);
660     napi_value result = nullptr;
661     napi_create_int32(env, constrains, &result);
662     return result;
663 }
664 
GetSubjectAlternativeNames(napi_env env,napi_callback_info info)665 napi_value NapiX509Certificate::GetSubjectAlternativeNames(napi_env env, napi_callback_info info)
666 {
667     CfArray *array = reinterpret_cast<CfArray *>(CfMalloc(sizeof(CfArray), 0));
668     if (array == nullptr) {
669         LOGE("malloc array failed!");
670         return nullptr;
671     }
672     HcfX509Certificate *cert = GetX509Cert();
673     CfResult ret = cert->getSubjectAltNames(cert, array);
674     if (ret != CF_SUCCESS) {
675         napi_throw(env, CertGenerateBusinessError(env, ret, "get subject alt names failed"));
676         LOGE("call getSubjectAltNames failed!");
677         CfFree(array);
678         array = nullptr;
679         return nullptr;
680     }
681     napi_value returnValue = ConvertArrayToNapiValue(env, array);
682     CfArrayDataClearAndFree(array);
683     CfFree(array);
684     array = nullptr;
685     return returnValue;
686 }
687 
GetIssuerAlternativeNames(napi_env env,napi_callback_info info)688 napi_value NapiX509Certificate::GetIssuerAlternativeNames(napi_env env, napi_callback_info info)
689 {
690     CfArray *array = reinterpret_cast<CfArray *>(CfMalloc(sizeof(CfArray), 0));
691     if (array == nullptr) {
692         LOGE("malloc array failed!");
693         return nullptr;
694     }
695     HcfX509Certificate *cert = GetX509Cert();
696     CfResult ret = cert->getIssuerAltNames(cert, array);
697     if (ret != CF_SUCCESS) {
698         napi_throw(env, CertGenerateBusinessError(env, ret, "get issuer alt names failed"));
699         LOGE("call getIssuerAltNames failed!");
700         CfFree(array);
701         array = nullptr;
702         return nullptr;
703     }
704     napi_value returnValue = ConvertArrayToNapiValue(env, array);
705     CfArrayDataClearAndFree(array);
706     CfFree(array);
707     array = nullptr;
708     return returnValue;
709 }
710 
Match(napi_env env,napi_callback_info info)711 napi_value NapiX509Certificate::Match(napi_env env, napi_callback_info info)
712 {
713     size_t argc = ARGS_SIZE_ONE;
714     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
715     napi_value thisVar = nullptr;
716     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
717     if (!CertCheckArgsCount(env, argc, ARGS_SIZE_ONE, false)) {
718         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "CertCheckArgsCount failed"));
719         LOGE("CertCheckArgsCount failed!");
720         return nullptr;
721     }
722 
723     HcfX509CertMatchParams *param = static_cast<HcfX509CertMatchParams *>(CfMalloc(sizeof(HcfX509CertMatchParams), 0));
724     if (param == nullptr) {
725         napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "malloc param failed"));
726         LOGE("malloc matchParams failed!");
727         return nullptr;
728     }
729     if (!BuildX509CertMatchParams(env, argv[PARAM0], param)) {
730         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "BuildX509CertMatchParams failed"));
731         LOGE("BuildX509CertMatchParams failed!");
732         FreeX509CertMatchParams(param);
733         return nullptr;
734     }
735     bool boolFlag = false;
736     CfResult result = MatchProc(param, boolFlag);
737     if (result != CF_SUCCESS) {
738         napi_throw(env, CertGenerateBusinessError(env, result, "match failed"));
739         LOGE("call match failed!");
740         FreeX509CertMatchParams(param);
741         return nullptr;
742     }
743     FreeX509CertMatchParams(param);
744     napi_value ret = nullptr;
745     napi_get_boolean(env, boolFlag, &ret);
746     return ret;
747 }
748 
ToString(napi_env env,napi_callback_info info)749 napi_value NapiX509Certificate::ToString(napi_env env, napi_callback_info info)
750 {
751     CfBlob blob = { 0, nullptr };
752     HcfX509Certificate *cert = GetX509Cert();
753     CfResult ret = cert->toString(cert, &blob);
754     if (ret != CF_SUCCESS) {
755         LOGE("toString failed!");
756         napi_throw(env, CertGenerateBusinessError(env, ret, "toString failed"));
757         return nullptr;
758     }
759 
760     napi_value returnValue = nullptr;
761     napi_create_string_utf8(env, reinterpret_cast<char *>(blob.data), blob.size, &returnValue);
762     CfBlobDataFree(&blob);
763     return returnValue;
764 }
765 
HashCode(napi_env env,napi_callback_info info)766 napi_value NapiX509Certificate::HashCode(napi_env env, napi_callback_info info)
767 {
768     CfBlob blob = { 0, nullptr };
769     HcfX509Certificate *cert = GetX509Cert();
770     CfResult ret = cert->hashCode(cert, &blob);
771     if (ret != CF_SUCCESS) {
772         LOGE("Hashcode failed!");
773         napi_throw(env, CertGenerateBusinessError(env, ret, "Hashcode failed"));
774         return nullptr;
775     }
776     napi_value returnValue = ConvertBlobToUint8ArrNapiValue(env, &blob);
777     CfBlobDataFree(&blob);
778     return returnValue;
779 }
780 
CreateCertExtsJSInstance(napi_env env)781 static napi_value CreateCertExtsJSInstance(napi_env env)
782 {
783     napi_value constructor = nullptr;
784     napi_value instance = nullptr;
785     napi_get_reference_value(env, NapiCertExtension::classRef_, &constructor);
786     napi_new_instance(env, constructor, 0, nullptr, &instance);
787     return instance;
788 }
789 
BuildCertExtsObject(napi_env env,CfEncodingBlob * encodingBlob)790 static napi_value BuildCertExtsObject(napi_env env, CfEncodingBlob *encodingBlob)
791 {
792     CfObject *extsObj = nullptr;
793     int32_t res = CfCreate(CF_OBJ_TYPE_EXTENSION, encodingBlob, &extsObj);
794     if (res != CF_SUCCESS) {
795         LOGE("CfCreate error!");
796         return nullptr;
797     }
798     napi_value jsObject = CreateCertExtsJSInstance(env);
799     NapiCertExtension *napiObject = new (std::nothrow) NapiCertExtension(extsObj);
800     if (napiObject == nullptr) {
801         LOGE("Failed to create napi extension class");
802         if (extsObj != nullptr) {
803             extsObj->destroy(&(extsObj));
804         }
805         return nullptr;
806     }
807     napi_wrap(
808         env, jsObject, napiObject,
809         [](napi_env env, void *data, void *hint) {
810             NapiCertExtension *certExts = static_cast<NapiCertExtension *>(data);
811             delete certExts;
812             return;
813         }, nullptr, nullptr);
814     return jsObject;
815 }
816 
GetExtensionsObject(napi_env env,napi_callback_info info)817 napi_value NapiX509Certificate::GetExtensionsObject(napi_env env, napi_callback_info info)
818 {
819     CfBlob blob = { 0, nullptr };
820     HcfX509Certificate *cert = GetX509Cert();
821     CfResult ret = cert->getExtensionsObject(cert, &blob);
822     if (ret != CF_SUCCESS) {
823         LOGE("get Extensions Object  failed!");
824         napi_throw(env, CertGenerateBusinessError(env, ret, "get Extensions Object failed"));
825         return nullptr;
826     }
827 
828     CfEncodingBlob *encodingBlob = static_cast<CfEncodingBlob *>(CfMalloc(sizeof(CfEncodingBlob), 0));
829     if (encodingBlob == nullptr) {
830         LOGE("malloc encoding blob failed!");
831         CfBlobDataFree(&blob);
832         napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "CfMalloc failed"));
833         return nullptr;
834     }
835     if (!ConvertBlobToEncodingBlob(blob, encodingBlob)) {
836         LOGE("ConvertBlobToEncodingBlob failed!");
837         CfBlobDataFree(&blob);
838         CfFree(encodingBlob);
839         encodingBlob = nullptr;
840         napi_throw(env, CertGenerateBusinessError(env, CF_ERR_CRYPTO_OPERATION, "ConvertBlobToEncodingBlob failed"));
841         return nullptr;
842     }
843     CfBlobDataFree(&blob);
844 
845     napi_value object = BuildCertExtsObject(env, encodingBlob);
846     CfEncodingBlobDataFree(encodingBlob);
847     CfFree(encodingBlob);
848     encodingBlob = nullptr;
849     if (object == nullptr) {
850         LOGE("BuildCertExtsObject failed!");
851         napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "BuildCertExtsObject failed"));
852         return nullptr;
853     }
854 
855     return object;
856 }
857 
GetIssuerX500DistinguishedName(napi_env env,napi_callback_info info)858 napi_value NapiX509Certificate::GetIssuerX500DistinguishedName(napi_env env, napi_callback_info info)
859 {
860     HcfX509Certificate *cert = GetX509Cert();
861     CfBlob blob = { 0, nullptr };
862     CfResult ret = cert->getIssuerName(cert, &blob);
863     if (ret != CF_SUCCESS) {
864         LOGE("getIssuerName failed!");
865         napi_throw(env, CertGenerateBusinessError(env, ret, "get issuer name failed"));
866         return nullptr;
867     }
868     HcfX509DistinguishedName *x509Name = nullptr;
869     ret = HcfX509DistinguishedNameCreate(&blob, true, &x509Name);
870     if (ret != CF_SUCCESS || x509Name == nullptr) {
871         LOGE("HcfX509DistinguishedNameCreate failed");
872         napi_throw(env, CertGenerateBusinessError(env, ret, "HcfX509DistinguishedNameCreate failed"));
873         CfBlobDataFree(&blob);
874         return nullptr;
875     }
876     CfBlobDataFree(&blob);
877     napi_value instance = NapiX509DistinguishedName::CreateX509DistinguishedName(env);
878     NapiX509DistinguishedName *x509NameClass = new (std::nothrow) NapiX509DistinguishedName(x509Name);
879     if (x509NameClass == nullptr) {
880         LOGE("Failed to create a NapiX509DistinguishedName class");
881         CfObjDestroy(x509Name);
882         napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "NapiX509DistinguishedName new failed"));
883         return nullptr;
884     }
885     napi_wrap(
886         env, instance, x509NameClass,
887         [](napi_env env, void *data, void *hint) {
888             NapiX509DistinguishedName *nameClass = static_cast<NapiX509DistinguishedName *>(data);
889             delete nameClass;
890             return;
891         }, nullptr, nullptr);
892     return instance;
893 }
894 
GetSubjectX500DistinguishedName(napi_env env,napi_callback_info info)895 napi_value NapiX509Certificate::GetSubjectX500DistinguishedName(napi_env env, napi_callback_info info)
896 {
897     HcfX509Certificate *cert = GetX509Cert();
898     CfBlob blob = { 0, nullptr };
899     CfResult ret = cert->getSubjectName(cert, &blob);
900     if (ret != CF_SUCCESS) {
901         LOGE("getSubjectName failed!");
902         napi_throw(env, CertGenerateBusinessError(env, ret, "get subject name failed"));
903         return nullptr;
904     }
905     HcfX509DistinguishedName *x509Name = nullptr;
906     ret = HcfX509DistinguishedNameCreate(&blob, true, &x509Name);
907     if (ret != CF_SUCCESS || x509Name == nullptr) {
908         LOGE("HcfX509DistinguishedNameCreate failed");
909         napi_throw(env, CertGenerateBusinessError(env, ret, "HcfX509DistinguishedNameCreate failed"));
910         CfBlobDataFree(&blob);
911         return nullptr;
912     }
913     CfBlobDataFree(&blob);
914     napi_value instance = NapiX509DistinguishedName::CreateX509DistinguishedName(env);
915     NapiX509DistinguishedName *x509NameClass = new (std::nothrow) NapiX509DistinguishedName(x509Name);
916     if (x509NameClass == nullptr) {
917         LOGE("Failed to create a NapiX509DistinguishedName class");
918         CfObjDestroy(x509Name);
919         napi_throw(env, CertGenerateBusinessError(env, CF_ERR_MALLOC, "NapiX509DistinguishedName new failed"));
920         return nullptr;
921     }
922     napi_wrap(
923         env, instance, x509NameClass,
924         [](napi_env env, void *data, void *hint) {
925             NapiX509DistinguishedName *nameClass = static_cast<NapiX509DistinguishedName *>(data);
926             delete nameClass;
927             return;
928         }, nullptr, nullptr);
929     return instance;
930 }
931 
GetCRLDistributionPointsURI(napi_env env,napi_callback_info info)932 napi_value NapiX509Certificate::GetCRLDistributionPointsURI(napi_env env, napi_callback_info info)
933 {
934     CfArray *array = reinterpret_cast<CfArray *>(CfMalloc(sizeof(CfArray), 0));
935     if (array == nullptr) {
936         LOGE("malloc array failed!");
937         return nullptr;
938     }
939     HcfX509Certificate *cert = GetX509Cert();
940     CfResult ret = cert->getCRLDistributionPointsURI(cert, array);
941     if (ret != CF_SUCCESS) {
942         napi_throw(env, CertGenerateBusinessError(env, ret, "get crl distribution points URI failed"));
943         LOGE("call get crl distribution points URI  failed!");
944         CfFree(array);
945         array = nullptr;
946         return nullptr;
947     }
948     napi_value returnValue = ConvertArrayToNapiValue(env, array);
949     CfArrayDataClearAndFree(array);
950     CfFree(array);
951     array = nullptr;
952     return returnValue;
953 }
954 
MatchProc(HcfX509CertMatchParams * param,bool & boolFlag)955 CfResult NapiX509Certificate::MatchProc(HcfX509CertMatchParams *param, bool &boolFlag)
956 {
957     HcfX509Certificate *cert = GetX509Cert();
958     return cert->match(cert, param, &boolFlag);
959 }
960 
NapiVerify(napi_env env,napi_callback_info info)961 static napi_value NapiVerify(napi_env env, napi_callback_info info)
962 {
963     napi_value thisVar = nullptr;
964     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
965     NapiX509Certificate *x509Cert = nullptr;
966     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
967     if (x509Cert == nullptr) {
968         LOGE("x509Cert is nullptr!");
969         return nullptr;
970     }
971     return x509Cert->Verify(env, info);
972 }
973 
NapiGetEncoded(napi_env env,napi_callback_info info)974 static napi_value NapiGetEncoded(napi_env env, napi_callback_info info)
975 {
976     napi_value thisVar = nullptr;
977     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
978     NapiX509Certificate *x509Cert = nullptr;
979     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
980     if (x509Cert == nullptr) {
981         LOGE("x509Cert is nullptr!");
982         return nullptr;
983     }
984     return x509Cert->GetEncoded(env, info);
985 }
986 
NapiGetPublicKey(napi_env env,napi_callback_info info)987 static napi_value NapiGetPublicKey(napi_env env, napi_callback_info info)
988 {
989     napi_value thisVar = nullptr;
990     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
991     NapiX509Certificate *x509Cert = nullptr;
992     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
993     if (x509Cert == nullptr) {
994         LOGE("x509Cert is nullptr!");
995         return nullptr;
996     }
997     return x509Cert->GetPublicKey(env, info);
998 }
999 
NapiCheckValidityWithDate(napi_env env,napi_callback_info info)1000 static napi_value NapiCheckValidityWithDate(napi_env env, napi_callback_info info)
1001 {
1002     napi_value thisVar = nullptr;
1003     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1004     NapiX509Certificate *x509Cert = nullptr;
1005     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1006     if (x509Cert == nullptr) {
1007         LOGE("x509Cert is nullptr!");
1008         return nullptr;
1009     }
1010     return x509Cert->CheckValidityWithDate(env, info);
1011 }
1012 
NapiGetVersion(napi_env env,napi_callback_info info)1013 static napi_value NapiGetVersion(napi_env env, napi_callback_info info)
1014 {
1015     napi_value thisVar = nullptr;
1016     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1017     NapiX509Certificate *x509Cert = nullptr;
1018     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1019     if (x509Cert == nullptr) {
1020         LOGE("x509Cert is nullptr!");
1021         return nullptr;
1022     }
1023     return x509Cert->GetVersion(env, info);
1024 }
1025 
NapiGetSerialNumber(napi_env env,napi_callback_info info)1026 static napi_value NapiGetSerialNumber(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->GetSerialNumber(env, info);
1037 }
1038 
NapiGetCertSerialNumber(napi_env env,napi_callback_info info)1039 static napi_value NapiGetCertSerialNumber(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->GetCertSerialNumber(env, info);
1050 }
1051 
NapiGetIssuerName(napi_env env,napi_callback_info info)1052 static napi_value NapiGetIssuerName(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->GetIssuerName(env, info);
1063 }
1064 
NapiGetSubjectName(napi_env env,napi_callback_info info)1065 static napi_value NapiGetSubjectName(napi_env env, napi_callback_info info)
1066 {
1067     size_t argc = ARGS_SIZE_ONE;
1068     napi_value thisVar = nullptr;
1069     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
1070     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1071     if (argc != 0 && argc != ARGS_SIZE_ONE) {
1072         LOGE("wrong argument num!");
1073         return nullptr;
1074     }
1075 
1076     NapiX509Certificate *x509Cert = nullptr;
1077     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1078     if (x509Cert == nullptr) {
1079         LOGE("x509Cert is nullptr!");
1080         return nullptr;
1081     }
1082 
1083     if (argc == ARGS_SIZE_ONE) {
1084         CfEncodinigType encodingType;
1085         if (napi_get_value_uint32(env, argv[PARAM0], reinterpret_cast<uint32_t *>(&encodingType)) != napi_ok) {
1086             LOGE("napi_get_value_uint32 failed!");
1087             return nullptr;
1088         }
1089         return x509Cert->GetSubjectNameEx(env, info, encodingType);
1090     }
1091     return x509Cert->GetSubjectName(env, info);
1092 }
1093 
NapiGetNotBeforeTime(napi_env env,napi_callback_info info)1094 static napi_value NapiGetNotBeforeTime(napi_env env, napi_callback_info info)
1095 {
1096     napi_value thisVar = nullptr;
1097     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1098     NapiX509Certificate *x509Cert = nullptr;
1099     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1100     if (x509Cert == nullptr) {
1101         LOGE("x509Cert is nullptr!");
1102         return nullptr;
1103     }
1104     return x509Cert->GetNotBeforeTime(env, info);
1105 }
1106 
NapiGetNotAfterTime(napi_env env,napi_callback_info info)1107 static napi_value NapiGetNotAfterTime(napi_env env, napi_callback_info info)
1108 {
1109     napi_value thisVar = nullptr;
1110     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1111     NapiX509Certificate *x509Cert = nullptr;
1112     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1113     if (x509Cert == nullptr) {
1114         LOGE("x509Cert is nullptr!");
1115         return nullptr;
1116     }
1117     return x509Cert->GetNotAfterTime(env, info);
1118 }
1119 
NapiGetSignature(napi_env env,napi_callback_info info)1120 static napi_value NapiGetSignature(napi_env env, napi_callback_info info)
1121 {
1122     napi_value thisVar = nullptr;
1123     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1124     NapiX509Certificate *x509Cert = nullptr;
1125     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1126     if (x509Cert == nullptr) {
1127         LOGE("x509Cert is nullptr!");
1128         return nullptr;
1129     }
1130     return x509Cert->GetSignature(env, info);
1131 }
1132 
NapiGetSigAlgName(napi_env env,napi_callback_info info)1133 static napi_value NapiGetSigAlgName(napi_env env, napi_callback_info info)
1134 {
1135     napi_value thisVar = nullptr;
1136     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1137     NapiX509Certificate *x509Cert = nullptr;
1138     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1139     if (x509Cert == nullptr) {
1140         LOGE("x509Cert is nullptr!");
1141         return nullptr;
1142     }
1143     return x509Cert->GetSigAlgName(env, info);
1144 }
1145 
NapiGetSigAlgOID(napi_env env,napi_callback_info info)1146 static napi_value NapiGetSigAlgOID(napi_env env, napi_callback_info info)
1147 {
1148     napi_value thisVar = nullptr;
1149     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1150     NapiX509Certificate *x509Cert = nullptr;
1151     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1152     if (x509Cert == nullptr) {
1153         LOGE("x509Cert is nullptr!");
1154         return nullptr;
1155     }
1156     return x509Cert->GetSigAlgOID(env, info);
1157 }
1158 
NapiGetSigAlgParams(napi_env env,napi_callback_info info)1159 static napi_value NapiGetSigAlgParams(napi_env env, napi_callback_info info)
1160 {
1161     napi_value thisVar = nullptr;
1162     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1163     NapiX509Certificate *x509Cert = nullptr;
1164     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1165     if (x509Cert == nullptr) {
1166         LOGE("x509Cert is nullptr!");
1167         return nullptr;
1168     }
1169     return x509Cert->GetSigAlgParams(env, info);
1170 }
1171 
NapiGetKeyUsage(napi_env env,napi_callback_info info)1172 static napi_value NapiGetKeyUsage(napi_env env, napi_callback_info info)
1173 {
1174     napi_value thisVar = nullptr;
1175     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1176     NapiX509Certificate *x509Cert = nullptr;
1177     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1178     if (x509Cert == nullptr) {
1179         LOGE("x509Cert is nullptr!");
1180         return nullptr;
1181     }
1182     return x509Cert->GetKeyUsage(env, info);
1183 }
1184 
NapiGetExtendedKeyUsage(napi_env env,napi_callback_info info)1185 static napi_value NapiGetExtendedKeyUsage(napi_env env, napi_callback_info info)
1186 {
1187     napi_value thisVar = nullptr;
1188     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1189     NapiX509Certificate *x509Cert = nullptr;
1190     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1191     if (x509Cert == nullptr) {
1192         LOGE("x509Cert is nullptr!");
1193         return nullptr;
1194     }
1195     return x509Cert->GetExtendedKeyUsage(env, info);
1196 }
1197 
NapiGetBasicConstraints(napi_env env,napi_callback_info info)1198 static napi_value NapiGetBasicConstraints(napi_env env, napi_callback_info info)
1199 {
1200     napi_value thisVar = nullptr;
1201     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1202     NapiX509Certificate *x509Cert = nullptr;
1203     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1204     if (x509Cert == nullptr) {
1205         LOGE("x509Cert is nullptr!");
1206         return nullptr;
1207     }
1208     return x509Cert->GetBasicConstraints(env, info);
1209 }
1210 
NapiGetSubjectAlternativeNames(napi_env env,napi_callback_info info)1211 static napi_value NapiGetSubjectAlternativeNames(napi_env env, napi_callback_info info)
1212 {
1213     napi_value thisVar = nullptr;
1214     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1215     NapiX509Certificate *x509Cert = nullptr;
1216     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1217     if (x509Cert == nullptr) {
1218         LOGE("x509Cert is nullptr!");
1219         return nullptr;
1220     }
1221     return x509Cert->GetSubjectAlternativeNames(env, info);
1222 }
1223 
NapiGetIssuerAlternativeNames(napi_env env,napi_callback_info info)1224 static napi_value NapiGetIssuerAlternativeNames(napi_env env, napi_callback_info info)
1225 {
1226     napi_value thisVar = nullptr;
1227     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1228     NapiX509Certificate *x509Cert = nullptr;
1229     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1230     if (x509Cert == nullptr) {
1231         LOGE("x509Cert is nullptr!");
1232         return nullptr;
1233     }
1234     return x509Cert->GetIssuerAlternativeNames(env, info);
1235 }
1236 
NapiGetItem(napi_env env,napi_callback_info info)1237 static napi_value NapiGetItem(napi_env env, napi_callback_info info)
1238 {
1239     napi_value thisVar = nullptr;
1240     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1241     NapiX509Certificate *x509Cert = nullptr;
1242     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1243     if (x509Cert == nullptr) {
1244         LOGE("x509Cert is nullptr!");
1245         return nullptr;
1246     }
1247     CfObject *obj = x509Cert->GetCertObject();
1248     if (obj == nullptr) {
1249         LOGE("object is nullptr!");
1250         return nullptr;
1251     }
1252 
1253     return CommonOperation(env, info, obj, OPERATION_TYPE_GET, CF_GET_TYPE_CERT_ITEM);
1254 }
1255 
NapiGetCRLDistributionPointsURI(napi_env env,napi_callback_info info)1256 static napi_value NapiGetCRLDistributionPointsURI(napi_env env, napi_callback_info info)
1257 {
1258     napi_value thisVar = nullptr;
1259     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1260     NapiX509Certificate *x509Cert = nullptr;
1261     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1262     if (x509Cert == nullptr) {
1263         LOGE("x509Cert is nullptr!");
1264         return nullptr;
1265     }
1266     return x509Cert->GetCRLDistributionPointsURI(env, info);
1267 }
1268 
NapiMatch(napi_env env,napi_callback_info info)1269 static napi_value NapiMatch(napi_env env, napi_callback_info info)
1270 {
1271     napi_value thisVar = nullptr;
1272     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1273     NapiX509Certificate *x509Cert = nullptr;
1274     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1275     if (x509Cert == nullptr) {
1276         LOGE("x509Cert is nullptr!");
1277         return nullptr;
1278     }
1279     return x509Cert->Match(env, info);
1280 }
1281 // v3
NapiToString(napi_env env,napi_callback_info info)1282 static napi_value NapiToString(napi_env env, napi_callback_info info)
1283 {
1284     napi_value thisVar = nullptr;
1285     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1286     NapiX509Certificate *x509Cert = nullptr;
1287     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1288     if (x509Cert == nullptr) {
1289         LOGE("x509Cert is nullptr!");
1290         return nullptr;
1291     }
1292     return x509Cert->ToString(env, info);
1293 }
1294 
NapiHashCode(napi_env env,napi_callback_info info)1295 static napi_value NapiHashCode(napi_env env, napi_callback_info info)
1296 {
1297     napi_value thisVar = nullptr;
1298     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1299     NapiX509Certificate *x509Cert = nullptr;
1300     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1301     if (x509Cert == nullptr) {
1302         LOGE("x509Cert is nullptr!");
1303         return nullptr;
1304     }
1305     return x509Cert->HashCode(env, info);
1306 }
1307 
NapiGetExtensionsObject(napi_env env,napi_callback_info info)1308 static napi_value NapiGetExtensionsObject(napi_env env, napi_callback_info info)
1309 {
1310     napi_value thisVar = nullptr;
1311     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1312     NapiX509Certificate *x509Cert = nullptr;
1313     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1314     if (x509Cert == nullptr) {
1315         LOGE("x509Cert is nullptr!");
1316         return nullptr;
1317     }
1318     return x509Cert->GetExtensionsObject(env, info);
1319 }
1320 
NapiGetIssuerX500DistinguishedName(napi_env env,napi_callback_info info)1321 static napi_value NapiGetIssuerX500DistinguishedName(napi_env env, napi_callback_info info)
1322 {
1323     napi_value thisVar = nullptr;
1324     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1325     NapiX509Certificate *x509Cert = nullptr;
1326     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1327     if (x509Cert == nullptr) {
1328         LOGE("x509Cert is nullptr!");
1329         return nullptr;
1330     }
1331     return x509Cert->GetIssuerX500DistinguishedName(env, info);
1332 }
1333 
NapiGetSubjectX500DistinguishedName(napi_env env,napi_callback_info info)1334 static napi_value NapiGetSubjectX500DistinguishedName(napi_env env, napi_callback_info info)
1335 {
1336     napi_value thisVar = nullptr;
1337     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1338     NapiX509Certificate *x509Cert = nullptr;
1339     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
1340     if (x509Cert == nullptr) {
1341         LOGE("x509Cert is nullptr!");
1342         return nullptr;
1343     }
1344     return x509Cert->GetSubjectX500DistinguishedName(env, info);
1345 }
1346 
CreateX509CertExecute(napi_env env,void * data)1347 void NapiX509Certificate::CreateX509CertExecute(napi_env env, void *data)
1348 {
1349     CfCtx *context = static_cast<CfCtx *>(data);
1350     context->errCode = HcfX509CertificateCreate(context->encodingBlob, &context->cert);
1351     if (context->errCode != CF_SUCCESS) {
1352         context->errMsg = "create X509Cert failed";
1353         return;
1354     }
1355 
1356     context->errCode = CfCreate(CF_OBJ_TYPE_CERT, context->encodingBlob, &context->object);
1357     if (context->errCode != CF_SUCCESS) {
1358         context->errMsg = "create certObj failed";
1359     }
1360 }
1361 
CreateX509CertComplete(napi_env env,napi_status status,void * data)1362 void NapiX509Certificate::CreateX509CertComplete(napi_env env, napi_status status, void *data)
1363 {
1364     CfCtx *context = static_cast<CfCtx *>(data);
1365     if (context->errCode != CF_SUCCESS) {
1366         LOGE("call create X509Cert failed!");
1367         ReturnResult(env, context, nullptr);
1368         FreeCryptoFwkCtx(env, context);
1369         return;
1370     }
1371     napi_value instance = CreateX509Cert(env);
1372     if (instance == nullptr) {
1373         LOGE("Create x509Cert failed!");
1374         ReturnResult(env, context, nullptr);
1375         FreeCryptoFwkCtx(env, context);
1376         return;
1377     }
1378     NapiX509Certificate *x509CertClass = new (std::nothrow) NapiX509Certificate(context->cert, context->object);
1379     if (x509CertClass == nullptr) {
1380         context->errCode = CF_ERR_MALLOC;
1381         context->errMsg = "Failed to create x509Cert class";
1382         LOGE("Failed to create x509Cert class");
1383         CfObjDestroy(context->cert);
1384         if (context->object != nullptr) {
1385             context->object->destroy(&(context->object));
1386         }
1387         ReturnResult(env, context, nullptr);
1388         FreeCryptoFwkCtx(env, context);
1389         return;
1390     }
1391     napi_wrap(
1392         env, instance, x509CertClass,
1393         [](napi_env env, void *data, void *hint) {
1394             NapiX509Certificate *certClass = static_cast<NapiX509Certificate *>(data);
1395             delete certClass;
1396             return;
1397         },
1398         nullptr, nullptr);
1399     ReturnResult(env, context, instance);
1400     FreeCryptoFwkCtx(env, context);
1401 }
1402 
NapiCreateX509Cert(napi_env env,napi_callback_info info)1403 napi_value NapiX509Certificate::NapiCreateX509Cert(napi_env env, napi_callback_info info)
1404 {
1405     size_t argc = ARGS_SIZE_TWO;
1406     napi_value argv[ARGS_SIZE_TWO] = { nullptr };
1407     napi_value thisVar = nullptr;
1408     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1409     if (!CertCheckArgsCount(env, argc, ARGS_SIZE_TWO, false)) {
1410         return nullptr;
1411     }
1412 
1413     CfCtx *context = static_cast<CfCtx *>(CfMalloc(sizeof(CfCtx), 0));
1414     if (context == nullptr) {
1415         LOGE("malloc context failed!");
1416         return nullptr;
1417     }
1418     if (!GetEncodingBlobFromValue(env, argv[PARAM0], &context->encodingBlob)) {
1419         LOGE("get encoding blob from data failed!");
1420         FreeCryptoFwkCtx(env, context);
1421         return nullptr;
1422     }
1423 
1424     if (napi_create_reference(env, thisVar, 1, &context->cfRef) != napi_ok) {
1425         LOGE("create reference failed!");
1426         FreeCryptoFwkCtx(env, context);
1427         napi_throw(env, CertGenerateBusinessError(env, CF_INVALID_PARAMS, "Create reference failed"));
1428         return nullptr;
1429     }
1430 
1431     if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, argv[PARAM1])) {
1432         FreeCryptoFwkCtx(env, context);
1433         return nullptr;
1434     }
1435 
1436     napi_create_async_work(
1437         env, nullptr, CertGetResourceName(env, "CreateX509Cert"),
1438         CreateX509CertExecute,
1439         CreateX509CertComplete,
1440         static_cast<void *>(context),
1441         &context->asyncWork);
1442 
1443     napi_queue_async_work(env, context->asyncWork);
1444     if (context->asyncType == ASYNC_TYPE_PROMISE) {
1445         return context->promise;
1446     } else {
1447         return CertNapiGetNull(env);
1448     }
1449 }
1450 
X509CertConstructor(napi_env env,napi_callback_info info)1451 static napi_value X509CertConstructor(napi_env env, napi_callback_info info)
1452 {
1453     napi_value thisVar = nullptr;
1454     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
1455     return thisVar;
1456 }
1457 
DefineX509CertJSClass(napi_env env,napi_value exports)1458 void NapiX509Certificate::DefineX509CertJSClass(napi_env env, napi_value exports)
1459 {
1460     napi_property_descriptor desc[] = {
1461         DECLARE_NAPI_FUNCTION("createX509Cert", NapiCreateX509Cert),
1462     };
1463     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
1464 
1465     napi_property_descriptor x509CertDesc[] = {
1466         DECLARE_NAPI_FUNCTION("verify", NapiVerify),
1467         DECLARE_NAPI_FUNCTION("getEncoded", NapiGetEncoded),
1468         DECLARE_NAPI_FUNCTION("getPublicKey", NapiGetPublicKey),
1469         DECLARE_NAPI_FUNCTION("checkValidityWithDate", NapiCheckValidityWithDate),
1470         DECLARE_NAPI_FUNCTION("getVersion", NapiGetVersion),
1471         DECLARE_NAPI_FUNCTION("getSerialNumber", NapiGetSerialNumber),
1472         DECLARE_NAPI_FUNCTION("getCertSerialNumber", NapiGetCertSerialNumber),
1473         DECLARE_NAPI_FUNCTION("getIssuerName", NapiGetIssuerName),
1474         DECLARE_NAPI_FUNCTION("getSubjectName", NapiGetSubjectName),
1475         DECLARE_NAPI_FUNCTION("getNotBeforeTime", NapiGetNotBeforeTime),
1476         DECLARE_NAPI_FUNCTION("getNotAfterTime", NapiGetNotAfterTime),
1477         DECLARE_NAPI_FUNCTION("getSignature", NapiGetSignature),
1478         DECLARE_NAPI_FUNCTION("getSignatureAlgName", NapiGetSigAlgName),
1479         DECLARE_NAPI_FUNCTION("getSignatureAlgOid", NapiGetSigAlgOID),
1480         DECLARE_NAPI_FUNCTION("getSignatureAlgParams", NapiGetSigAlgParams),
1481         DECLARE_NAPI_FUNCTION("getKeyUsage", NapiGetKeyUsage),
1482         DECLARE_NAPI_FUNCTION("getExtKeyUsage", NapiGetExtendedKeyUsage),
1483         DECLARE_NAPI_FUNCTION("getBasicConstraints", NapiGetBasicConstraints),
1484         DECLARE_NAPI_FUNCTION("getSubjectAltNames", NapiGetSubjectAlternativeNames),
1485         DECLARE_NAPI_FUNCTION("getIssuerAltNames", NapiGetIssuerAlternativeNames),
1486         DECLARE_NAPI_FUNCTION("getItem", NapiGetItem),
1487         DECLARE_NAPI_FUNCTION("match", NapiMatch),
1488         DECLARE_NAPI_FUNCTION("toString", NapiToString),
1489         DECLARE_NAPI_FUNCTION("hashCode", NapiHashCode),
1490         DECLARE_NAPI_FUNCTION("getExtensionsObject", NapiGetExtensionsObject),
1491         DECLARE_NAPI_FUNCTION("getIssuerX500DistinguishedName", NapiGetIssuerX500DistinguishedName),
1492         DECLARE_NAPI_FUNCTION("getSubjectX500DistinguishedName", NapiGetSubjectX500DistinguishedName),
1493         DECLARE_NAPI_FUNCTION("getCRLDistributionPoint", NapiGetCRLDistributionPointsURI),
1494     };
1495     napi_value constructor = nullptr;
1496     napi_define_class(env, "X509Cert", NAPI_AUTO_LENGTH, X509CertConstructor, nullptr,
1497         sizeof(x509CertDesc) / sizeof(x509CertDesc[0]), x509CertDesc, &constructor);
1498     napi_create_reference(env, constructor, 1, &classRef_);
1499 }
1500 
CreateX509Cert(napi_env env)1501 napi_value NapiX509Certificate::CreateX509Cert(napi_env env)
1502 {
1503     napi_value constructor = nullptr;
1504     napi_value instance = nullptr;
1505     napi_get_reference_value(env, classRef_, &constructor);
1506     napi_new_instance(env, constructor, 0, nullptr, &instance);
1507     return instance;
1508 }
1509 } // namespace CertFramework
1510 } // namespace OHOS
1511