• 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_crl_entry.h"
17 
18 #include "cf_log.h"
19 #include "cf_memory.h"
20 #include "cf_object_base.h"
21 #include "cf_result.h"
22 #include "napi/native_api.h"
23 #include "napi/native_node_api.h"
24 #include "napi_cert_defines.h"
25 #include "napi_cert_utils.h"
26 #include "utils.h"
27 
28 namespace OHOS {
29 namespace CertFramework {
30 thread_local napi_ref NapiX509CrlEntry::classCrlRef_ = nullptr;
31 thread_local napi_ref NapiX509CrlEntry::classCRLRef_ = nullptr;
32 
33 struct CfCtx {
34     AsyncType asyncType = ASYNC_TYPE_CALLBACK;
35     napi_value promise = nullptr;
36     napi_ref callback = nullptr;
37     napi_deferred deferred = nullptr;
38     napi_async_work asyncWork = nullptr;
39 
40     NapiX509CrlEntry *crlEntryClass = nullptr;
41 
42     int32_t errCode = 0;
43     const char *errMsg = nullptr;
44     CfEncodingBlob *encoded = nullptr;
45     CfBlob *blob = nullptr;
46 };
47 
FreeCryptoFwkCtx(napi_env env,CfCtx * context)48 static void FreeCryptoFwkCtx(napi_env env, CfCtx *context)
49 {
50     if (context == nullptr) {
51         return;
52     }
53 
54     if (context->asyncWork != nullptr) {
55         napi_delete_async_work(env, context->asyncWork);
56     }
57 
58     if (context->callback != nullptr) {
59         napi_delete_reference(env, context->callback);
60     }
61 
62     CfEncodingBlobDataFree(context->encoded);
63     CfFree(context->encoded);
64     context->encoded = nullptr;
65 
66     CfBlobDataFree(context->blob);
67     CfFree(context->blob);
68     context->blob = nullptr;
69 
70     CfFree(context);
71 }
72 
ReturnCallbackResult(napi_env env,CfCtx * context,napi_value result)73 static void ReturnCallbackResult(napi_env env, CfCtx *context, napi_value result)
74 {
75     napi_value businessError = nullptr;
76     if (context->errCode != CF_SUCCESS) {
77         businessError = CertGenerateBusinessError(env, context->errCode, context->errMsg);
78     }
79     napi_value params[ARGS_SIZE_TWO] = { businessError, result };
80 
81     napi_value func = nullptr;
82     napi_get_reference_value(env, context->callback, &func);
83 
84     napi_value recv = nullptr;
85     napi_value callFuncRet = nullptr;
86     napi_get_undefined(env, &recv);
87     napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
88 }
89 
ReturnPromiseResult(napi_env env,CfCtx * context,napi_value result)90 static void ReturnPromiseResult(napi_env env, CfCtx *context, napi_value result)
91 {
92     if (context->errCode == CF_SUCCESS) {
93         napi_resolve_deferred(env, context->deferred, result);
94     } else {
95         napi_reject_deferred(env, context->deferred, CertGenerateBusinessError(env, context->errCode, context->errMsg));
96     }
97 }
98 
ReturnResult(napi_env env,CfCtx * context,napi_value result)99 static void ReturnResult(napi_env env, CfCtx *context, napi_value result)
100 {
101     if (context->asyncType == ASYNC_TYPE_CALLBACK) {
102         ReturnCallbackResult(env, context, result);
103     } else {
104         ReturnPromiseResult(env, context, result);
105     }
106 }
107 
CreateCallbackAndPromise(napi_env env,CfCtx * context,size_t argc,size_t maxCount,napi_value callbackValue)108 static bool CreateCallbackAndPromise(
109     napi_env env, CfCtx *context, size_t argc, size_t maxCount, napi_value callbackValue)
110 {
111     context->asyncType = GetAsyncType(env, argc, maxCount, callbackValue);
112     if (context->asyncType == ASYNC_TYPE_CALLBACK) {
113         if (!CertGetCallbackFromJSParams(env, callbackValue, &context->callback)) {
114             LOGE("x509 crl entry: get callback failed!");
115             return false;
116         }
117     } else {
118         napi_create_promise(env, &context->deferred, &context->promise);
119     }
120     return true;
121 }
122 
NapiX509CrlEntry(HcfX509CrlEntry * x509CrlEntry)123 NapiX509CrlEntry::NapiX509CrlEntry(HcfX509CrlEntry *x509CrlEntry)
124 {
125     this->x509CrlEntry_ = x509CrlEntry;
126 }
127 
~NapiX509CrlEntry()128 NapiX509CrlEntry::~NapiX509CrlEntry()
129 {
130     CfObjDestroy(this->x509CrlEntry_);
131 }
132 
GetEncodedExecute(napi_env env,void * data)133 static void GetEncodedExecute(napi_env env, void *data)
134 {
135     CfCtx *context = static_cast<CfCtx *>(data);
136     HcfX509CrlEntry *x509CrlEntry = context->crlEntryClass->GetX509CrlEntry();
137     CfEncodingBlob *encodingBlob = static_cast<CfEncodingBlob *>(HcfMalloc(sizeof(CfEncodingBlob), 0));
138     if (encodingBlob == nullptr) {
139         LOGE("malloc encoding blob failed!");
140         context->errCode = CF_ERR_MALLOC;
141         context->errMsg = "malloc encoding blob failed";
142         return;
143     }
144 
145     context->errCode = x509CrlEntry->getEncoded(x509CrlEntry, encodingBlob);
146     if (context->errCode != CF_SUCCESS) {
147         LOGE("get encoded failed!");
148         context->errMsg = "get encoded failed";
149     }
150     context->encoded = encodingBlob;
151 }
152 
GetEncodedComplete(napi_env env,napi_status status,void * data)153 static void GetEncodedComplete(napi_env env, napi_status status, void *data)
154 {
155     CfCtx *context = static_cast<CfCtx *>(data);
156     if (context->errCode != CF_SUCCESS) {
157         ReturnResult(env, context, nullptr);
158         FreeCryptoFwkCtx(env, context);
159         return;
160     }
161     napi_value returnEncodingBlob = ConvertEncodingBlobToNapiValue(env, context->encoded);
162     ReturnResult(env, context, returnEncodingBlob);
163     FreeCryptoFwkCtx(env, context);
164 }
165 
GetEncoded(napi_env env,napi_callback_info info)166 napi_value NapiX509CrlEntry::GetEncoded(napi_env env, napi_callback_info info)
167 {
168     size_t argc = ARGS_SIZE_ONE;
169     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
170     napi_value thisVar = nullptr;
171     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
172     if (!CertCheckArgsCount(env, argc, ARGS_SIZE_ONE, false)) {
173         return nullptr;
174     }
175 
176     CfCtx *context = static_cast<CfCtx *>(HcfMalloc(sizeof(CfCtx), 0));
177     if (context == nullptr) {
178         LOGE("malloc context failed!");
179         return nullptr;
180     }
181     context->crlEntryClass = this;
182 
183     if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_ONE, argv[PARAM0])) {
184         FreeCryptoFwkCtx(env, context);
185         return nullptr;
186     }
187 
188     napi_create_async_work(env, nullptr, CertGetResourceName(env, "GetEncoded"), GetEncodedExecute, GetEncodedComplete,
189         static_cast<void *>(context), &context->asyncWork);
190 
191     napi_queue_async_work(env, context->asyncWork);
192     if (context->asyncType == ASYNC_TYPE_PROMISE) {
193         return context->promise;
194     } else {
195         return CertNapiGetNull(env);
196     }
197 }
198 
GetCrlEntrySerialNumber(napi_env env,napi_callback_info info)199 napi_value NapiX509CrlEntry::GetCrlEntrySerialNumber(napi_env env, napi_callback_info info)
200 {
201     HcfX509CrlEntry *x509CrlEntry = GetX509CrlEntry();
202     CfBlob blob = { 0, nullptr };
203     CfResult ret = x509CrlEntry->getSerialNumber(x509CrlEntry, &blob);
204     if (ret != CF_SUCCESS) {
205         napi_throw(env, CertGenerateBusinessError(env, ret, "crl entry get serial num failed"));
206         LOGE("crl entry get serial num failed!");
207         return nullptr;
208     }
209 
210     napi_value result = ConvertBlobToInt64(env, blob);
211     CfBlobDataFree(&blob);
212     return result;
213 }
214 
GetCRLEntrySerialNumber(napi_env env,napi_callback_info info)215 napi_value NapiX509CrlEntry::GetCRLEntrySerialNumber(napi_env env, napi_callback_info info)
216 {
217     HcfX509CrlEntry *x509CrlEntry = GetX509CrlEntry();
218     CfBlob blob = { 0, nullptr };
219     CfResult ret = x509CrlEntry->getSerialNumber(x509CrlEntry, &blob);
220     if (ret != CF_SUCCESS) {
221         napi_throw(env, CertGenerateBusinessError(env, ret, "crl entry get serial num failed"));
222         LOGE("crl entry get serial num failed!");
223         return nullptr;
224     }
225 
226     napi_value result = ConvertBlobToBigIntWords(env, blob);
227     CfBlobDataFree(&blob);
228     return result;
229 }
230 
GetCertificateIssuer(napi_env env,napi_callback_info info)231 napi_value NapiX509CrlEntry::GetCertificateIssuer(napi_env env, napi_callback_info info)
232 {
233     CfBlob *blob = reinterpret_cast<CfBlob *>(HcfMalloc(sizeof(CfBlob), 0));
234     if (blob == nullptr) {
235         LOGE("malloc blob failed!");
236         return nullptr;
237     }
238 
239     HcfX509CrlEntry *x509CrlEntry = GetX509CrlEntry();
240     CfResult ret = x509CrlEntry->getCertIssuer(x509CrlEntry, blob);
241     if (ret != CF_SUCCESS) {
242         napi_throw(env, CertGenerateBusinessError(env, ret, "get subject name failed"));
243         LOGE("get cert issuer failed!");
244         CfFree(blob);
245         blob = nullptr;
246         return nullptr;
247     }
248     napi_value returnValue = CertConvertBlobToNapiValue(env, blob);
249     CfBlobDataFree(blob);
250     CfFree(blob);
251     blob = nullptr;
252     return returnValue;
253 }
254 
GetRevocationDate(napi_env env,napi_callback_info info)255 napi_value NapiX509CrlEntry::GetRevocationDate(napi_env env, napi_callback_info info)
256 {
257     HcfX509CrlEntry *x509CrlEntry = GetX509CrlEntry();
258     CfBlob *blob = reinterpret_cast<CfBlob *>(HcfMalloc(sizeof(CfBlob), 0));
259     if (blob == nullptr) {
260         LOGE("malloc blob failed!");
261         return nullptr;
262     }
263     CfResult ret = x509CrlEntry->getRevocationDate(x509CrlEntry, blob);
264     if (ret != CF_SUCCESS) {
265         napi_throw(env, CertGenerateBusinessError(env, ret, "get revocation date failed"));
266         LOGE("get revocation date failed!");
267         CfFree(blob);
268         blob = nullptr;
269         return nullptr;
270     }
271     napi_value returnDate = nullptr;
272     napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), blob->size, &returnDate);
273     CfBlobDataFree(blob);
274     CfFree(blob);
275     blob = nullptr;
276     return returnDate;
277 }
278 
GetExtensions(napi_env env,napi_callback_info info)279 napi_value NapiX509CrlEntry::GetExtensions(napi_env env, napi_callback_info info)
280 {
281     HcfX509CrlEntry *x509CrlEntry = GetX509CrlEntry();
282     CfBlob *blob = reinterpret_cast<CfBlob *>(HcfMalloc(sizeof(CfBlob), 0));
283     if (blob == nullptr) {
284         LOGE("malloc blob failed!");
285         return nullptr;
286     }
287     CfResult result = x509CrlEntry->getExtensions(x509CrlEntry, blob);
288     if (result != CF_SUCCESS) {
289         napi_throw(env, CertGenerateBusinessError(env, result, "get extensions failed"));
290         LOGE("getExtensions failed!");
291         CfFree(blob);
292         blob = nullptr;
293         return nullptr;
294     }
295     napi_value returnBlob = CertConvertBlobToNapiValue(env, blob);
296     CfBlobDataFree(blob);
297     CfFree(blob);
298     blob = nullptr;
299     return returnBlob;
300 }
301 
HasExtensions(napi_env env,napi_callback_info info)302 napi_value NapiX509CrlEntry::HasExtensions(napi_env env, napi_callback_info info)
303 {
304     HcfX509CrlEntry *x509CrlEntry = GetX509CrlEntry();
305     bool boolResult = false;
306     CfResult result = x509CrlEntry->hasExtensions(x509CrlEntry, &boolResult);
307     if (result != CF_SUCCESS) {
308         napi_throw(env, CertGenerateBusinessError(env, result, "has extensions failed"));
309         LOGE("hasExtensions failed!");
310         return nullptr;
311     }
312     napi_value ret = nullptr;
313     napi_get_boolean(env, boolResult, &ret);
314     return ret;
315 }
316 
NapiGetEncoded(napi_env env,napi_callback_info info)317 static napi_value NapiGetEncoded(napi_env env, napi_callback_info info)
318 {
319     napi_value thisVar = nullptr;
320     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
321     NapiX509CrlEntry *x509CrlEntry = nullptr;
322     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509CrlEntry));
323     if (x509CrlEntry == nullptr) {
324         LOGE("x509CrlEntry is nullptr!");
325         return nullptr;
326     }
327     return x509CrlEntry->GetEncoded(env, info);
328 }
329 
NapiCrlEntryGetSerialNumber(napi_env env,napi_callback_info info)330 static napi_value NapiCrlEntryGetSerialNumber(napi_env env, napi_callback_info info)
331 {
332     napi_value thisVar = nullptr;
333     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
334     NapiX509CrlEntry *x509CrlEntry = nullptr;
335     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509CrlEntry));
336     if (x509CrlEntry == nullptr) {
337         LOGE("x509CrlEntry is nullptr!");
338         return nullptr;
339     }
340     return x509CrlEntry->GetCrlEntrySerialNumber(env, info);
341 }
342 
NapiCRLEntryGetSerialNumber(napi_env env,napi_callback_info info)343 static napi_value NapiCRLEntryGetSerialNumber(napi_env env, napi_callback_info info)
344 {
345     napi_value thisVar = nullptr;
346     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
347     NapiX509CrlEntry *x509CrlEntry = nullptr;
348     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509CrlEntry));
349     if (x509CrlEntry == nullptr) {
350         LOGE("x509CrlEntry is nullptr!");
351         return nullptr;
352     }
353     return x509CrlEntry->GetCRLEntrySerialNumber(env, info);
354 }
355 
NapiGetCertificateIssuer(napi_env env,napi_callback_info info)356 static napi_value NapiGetCertificateIssuer(napi_env env, napi_callback_info info)
357 {
358     napi_value thisVar = nullptr;
359     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
360     NapiX509CrlEntry *x509CrlEntry = nullptr;
361     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509CrlEntry));
362     if (x509CrlEntry == nullptr) {
363         LOGE("x509CrlEntry is nullptr!");
364         return nullptr;
365     }
366     return x509CrlEntry->GetCertificateIssuer(env, info);
367 }
368 
NapiGetRevocationDate(napi_env env,napi_callback_info info)369 static napi_value NapiGetRevocationDate(napi_env env, napi_callback_info info)
370 {
371     napi_value thisVar = nullptr;
372     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
373     NapiX509CrlEntry *x509CrlEntry = nullptr;
374     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509CrlEntry));
375     if (x509CrlEntry == nullptr) {
376         LOGE("x509CrlEntry is nullptr!");
377         return nullptr;
378     }
379     return x509CrlEntry->GetRevocationDate(env, info);
380 }
381 
NapiGetExtensions(napi_env env,napi_callback_info info)382 static napi_value NapiGetExtensions(napi_env env, napi_callback_info info)
383 {
384     napi_value thisVar = nullptr;
385     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
386     NapiX509CrlEntry *x509CrlEntry = nullptr;
387     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509CrlEntry));
388     if (x509CrlEntry == nullptr) {
389         LOGE("x509CrlEntry is nullptr!");
390         return nullptr;
391     }
392     return x509CrlEntry->GetExtensions(env, info);
393 }
394 
NapiHasExtensions(napi_env env,napi_callback_info info)395 static napi_value NapiHasExtensions(napi_env env, napi_callback_info info)
396 {
397     napi_value thisVar = nullptr;
398     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
399     NapiX509CrlEntry *x509CrlEntry = nullptr;
400     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509CrlEntry));
401     if (x509CrlEntry == nullptr) {
402         LOGE("x509CrlEntry is nullptr!");
403         return nullptr;
404     }
405     return x509CrlEntry->HasExtensions(env, info);
406 }
407 
X509CrlEntryConstructor(napi_env env,napi_callback_info info)408 static napi_value X509CrlEntryConstructor(napi_env env, napi_callback_info info)
409 {
410     napi_value thisVar = nullptr;
411     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
412     return thisVar;
413 }
414 
DefineX509CrlEntryJSClass(napi_env env,std::string className)415 void NapiX509CrlEntry::DefineX509CrlEntryJSClass(napi_env env, std::string className)
416 {
417     if (className == std::string("X509CrlEntry")) {
418         napi_property_descriptor x509CrlEntryDesc[] = {
419             DECLARE_NAPI_FUNCTION("getEncoded", NapiGetEncoded),
420             DECLARE_NAPI_FUNCTION("getSerialNumber", NapiCrlEntryGetSerialNumber),
421             DECLARE_NAPI_FUNCTION("getCertIssuer", NapiGetCertificateIssuer),
422             DECLARE_NAPI_FUNCTION("getRevocationDate", NapiGetRevocationDate),
423         };
424         napi_value constructor = nullptr;
425         napi_define_class(env, className.c_str(), NAPI_AUTO_LENGTH, X509CrlEntryConstructor, nullptr,
426             sizeof(x509CrlEntryDesc) / sizeof(x509CrlEntryDesc[0]), x509CrlEntryDesc, &constructor);
427         napi_create_reference(env, constructor, 1, &classCrlRef_);
428     } else {
429         napi_property_descriptor x509CrlEntryDesc[] = {
430             DECLARE_NAPI_FUNCTION("getEncoded", NapiGetEncoded),
431             DECLARE_NAPI_FUNCTION("getSerialNumber", NapiCRLEntryGetSerialNumber),
432             DECLARE_NAPI_FUNCTION("getCertIssuer", NapiGetCertificateIssuer),
433             DECLARE_NAPI_FUNCTION("getRevocationDate", NapiGetRevocationDate),
434             DECLARE_NAPI_FUNCTION("getExtensions", NapiGetExtensions),
435             DECLARE_NAPI_FUNCTION("hasExtensions", NapiHasExtensions),
436         };
437         napi_value constructor = nullptr;
438         napi_define_class(env, className.c_str(), NAPI_AUTO_LENGTH, X509CrlEntryConstructor, nullptr,
439             sizeof(x509CrlEntryDesc) / sizeof(x509CrlEntryDesc[0]), x509CrlEntryDesc, &constructor);
440         napi_create_reference(env, constructor, 1, &classCRLRef_);
441     }
442 }
443 
CreateX509CrlEntry(napi_env env,std::string className)444 napi_value NapiX509CrlEntry::CreateX509CrlEntry(napi_env env, std::string className)
445 {
446     napi_value constructor = nullptr;
447     napi_value instance = nullptr;
448     if (className == std::string("X509CrlEntry")) {
449         napi_get_reference_value(env, classCrlRef_, &constructor);
450     } else {
451         napi_get_reference_value(env, classCRLRef_, &constructor);
452     }
453     napi_new_instance(env, constructor, 0, nullptr, &instance);
454     return instance;
455 }
456 } // namespace CertFramework
457 } // namespace OHOS
458