1 /*
2 * Copyright (c) 2022 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
18 #include "napi/native_node_api.h"
19 #include "napi/native_api.h"
20 #include "log.h"
21 #include "memory.h"
22 #include "utils.h"
23 #include "object_base.h"
24 #include "result.h"
25 #include "napi_crypto_framework_defines.h"
26 #include "napi_pub_key.h"
27 #include "napi_utils.h"
28
29 namespace OHOS {
30 namespace CryptoFramework {
31 thread_local napi_ref NapiX509Certificate::classRef_ = nullptr;
32
33 struct CfCtx {
34 CfAsyncType 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 HcfEncodingBlob *encodingBlob = nullptr;
41 NapiX509Certificate *certClass = nullptr;
42 HcfPubKey *pubKey = nullptr;
43
44 int32_t errCode = 0;
45 const char *errMsg = nullptr;
46 HcfX509Certificate *cert;
47 HcfEncodingBlob *encoded = nullptr;
48 };
49
NapiX509Certificate(HcfX509Certificate * x509Cert)50 NapiX509Certificate::NapiX509Certificate(HcfX509Certificate *x509Cert)
51 {
52 this->x509Cert_ = x509Cert;
53 }
54
~NapiX509Certificate()55 NapiX509Certificate::~NapiX509Certificate()
56 {
57 HcfObjDestroy(this->x509Cert_);
58 }
59
FreeCryptoFwkCtx(napi_env env,CfCtx * context)60 static void FreeCryptoFwkCtx(napi_env env, CfCtx *context)
61 {
62 if (context == nullptr) {
63 return;
64 }
65
66 if (context->asyncWork != nullptr) {
67 napi_delete_async_work(env, context->asyncWork);
68 }
69
70 if (context->callback != nullptr) {
71 napi_delete_reference(env, context->callback);
72 }
73
74 HcfEncodingBlobDataFree(context->encodingBlob);
75 HcfFree(context->encodingBlob);
76 context->encodingBlob = nullptr;
77
78 HcfEncodingBlobDataFree(context->encoded);
79 HcfFree(context->encoded);
80 context->encoded = nullptr;
81
82 HcfFree(context);
83 }
84
ReturnCallbackResult(napi_env env,CfCtx * context,napi_value result)85 static void ReturnCallbackResult(napi_env env, CfCtx *context, napi_value result)
86 {
87 napi_value businessError = nullptr;
88 if (context->errCode != HCF_SUCCESS) {
89 businessError = GenerateBusinessError(env, context->errCode, context->errMsg, true);
90 }
91 napi_value params[ARGS_SIZE_TWO] = { businessError, result };
92
93 napi_value func = nullptr;
94 napi_get_reference_value(env, context->callback, &func);
95
96 napi_value recv = nullptr;
97 napi_value callFuncRet = nullptr;
98 napi_get_undefined(env, &recv);
99 napi_call_function(env, recv, func, ARGS_SIZE_TWO, params, &callFuncRet);
100 }
101
ReturnPromiseResult(napi_env env,CfCtx * context,napi_value result)102 static void ReturnPromiseResult(napi_env env, CfCtx *context, napi_value result)
103 {
104 if (context->errCode == HCF_SUCCESS) {
105 napi_resolve_deferred(env, context->deferred, result);
106 } else {
107 napi_reject_deferred(env, context->deferred,
108 GenerateBusinessError(env, context->errCode, context->errMsg, true));
109 }
110 }
111
ReturnResult(napi_env env,CfCtx * context,napi_value result)112 static void ReturnResult(napi_env env, CfCtx *context, napi_value result)
113 {
114 if (context->asyncType == ASYNC_TYPE_CALLBACK) {
115 ReturnCallbackResult(env, context, result);
116 } else {
117 ReturnPromiseResult(env, context, result);
118 }
119 }
120
CreateCallbackAndPromise(napi_env env,CfCtx * context,size_t argc,size_t maxCount,napi_value callbackValue)121 static bool CreateCallbackAndPromise(napi_env env, CfCtx *context, size_t argc,
122 size_t maxCount, napi_value callbackValue)
123 {
124 context->asyncType = (argc == maxCount) ? ASYNC_TYPE_CALLBACK : ASYNC_TYPE_PROMISE;
125 if (context->asyncType == ASYNC_TYPE_CALLBACK) {
126 if (!GetCallbackFromJSParams(env, callbackValue, &context->callback, true)) {
127 LOGE("get callback failed!");
128 return false;
129 }
130 } else {
131 napi_create_promise(env, &context->deferred, &context->promise);
132 }
133 return true;
134 }
135
VerifyExecute(napi_env env,void * data)136 static void VerifyExecute(napi_env env, void *data)
137 {
138 LOGI("start to verify.");
139 CfCtx *context = static_cast<CfCtx *>(data);
140 HcfX509Certificate *cert = context->certClass->GetX509Cert();
141 context->errCode = cert->base.verify(&(cert->base), context->pubKey);
142 if (context->errCode != HCF_SUCCESS) {
143 LOGE("verify cert failed!");
144 context->errMsg = "verify cert failed";
145 }
146 }
147
VerifyComplete(napi_env env,napi_status status,void * data)148 static void VerifyComplete(napi_env env, napi_status status, void *data)
149 {
150 CfCtx *context = static_cast<CfCtx *>(data);
151 ReturnResult(env, context, NapiGetNull(env));
152 FreeCryptoFwkCtx(env, context);
153 }
154
GetEncodedExecute(napi_env env,void * data)155 static void GetEncodedExecute(napi_env env, void *data)
156 {
157 CfCtx *context = static_cast<CfCtx *>(data);
158 HcfX509Certificate *cert = context->certClass->GetX509Cert();
159 HcfEncodingBlob *encodingBlob = static_cast<HcfEncodingBlob *>(HcfMalloc(sizeof(HcfEncodingBlob), 0));
160 if (encodingBlob == nullptr) {
161 LOGE("malloc encoding blob failed!");
162 context->errCode = HCF_ERR_MALLOC;
163 context->errMsg = "malloc encoding blob failed";
164 return;
165 }
166 context->errCode = cert->base.getEncoded(&(cert->base), encodingBlob);
167 if (context->errCode != HCF_SUCCESS) {
168 LOGE("get cert encoded failed!");
169 context->errMsg = "get cert encoded failed";
170 }
171 context->encoded = encodingBlob;
172 }
173
GetEncodedComplete(napi_env env,napi_status status,void * data)174 static void GetEncodedComplete(napi_env env, napi_status status, void *data)
175 {
176 CfCtx *context = static_cast<CfCtx *>(data);
177 if (context->errCode != HCF_SUCCESS) {
178 ReturnResult(env, context, nullptr);
179 FreeCryptoFwkCtx(env, context);
180 return;
181 }
182 napi_value returnEncodingBlob = ConvertEncodingBlobToNapiValue(env, context->encoded);
183 ReturnResult(env, context, returnEncodingBlob);
184 FreeCryptoFwkCtx(env, context);
185 }
186
Verify(napi_env env,napi_callback_info info)187 napi_value NapiX509Certificate::Verify(napi_env env, napi_callback_info info)
188 {
189 size_t argc = ARGS_SIZE_TWO;
190 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
191 napi_value thisVar = nullptr;
192 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
193 if (!CheckArgsCount(env, argc, ARGS_SIZE_TWO, false, true)) {
194 return nullptr;
195 }
196
197 CfCtx *context = static_cast<CfCtx *>(HcfMalloc(sizeof(CfCtx), 0));
198 if (context == nullptr) {
199 LOGE("malloc context failed!");
200 return nullptr;
201 }
202 context->certClass = this;
203
204 NapiPubKey *pubKey = nullptr;
205 napi_unwrap(env, argv[PARAM0], (void**)&pubKey);
206 if (pubKey == nullptr) {
207 napi_throw(env, GenerateBusinessError(env, HCF_INVALID_PARAMS, "public key is null", true));
208 LOGE("pubKey is null!");
209 FreeCryptoFwkCtx(env, context);
210 return nullptr;
211 }
212 context->pubKey = pubKey->GetPubKey();
213
214 if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, argv[PARAM1])) {
215 FreeCryptoFwkCtx(env, context);
216 return nullptr;
217 }
218
219 napi_create_async_work(
220 env, nullptr, GetResourceName(env, "Verify"),
221 VerifyExecute,
222 VerifyComplete,
223 static_cast<void *>(context),
224 &context->asyncWork);
225
226 napi_queue_async_work(env, context->asyncWork);
227 if (context->asyncType == ASYNC_TYPE_PROMISE) {
228 return context->promise;
229 } else {
230 return NapiGetNull(env);
231 }
232 }
233
GetEncoded(napi_env env,napi_callback_info info)234 napi_value NapiX509Certificate::GetEncoded(napi_env env, napi_callback_info info)
235 {
236 size_t argc = ARGS_SIZE_ONE;
237 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
238 napi_value thisVar = nullptr;
239 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
240 if (!CheckArgsCount(env, argc, ARGS_SIZE_ONE, false, true)) {
241 return nullptr;
242 }
243
244 CfCtx *context = static_cast<CfCtx *>(HcfMalloc(sizeof(CfCtx), 0));
245 if (context == nullptr) {
246 LOGE("malloc context failed!");
247 return nullptr;
248 }
249 context->certClass = this;
250
251 if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_ONE, argv[PARAM0])) {
252 FreeCryptoFwkCtx(env, context);
253 return nullptr;
254 }
255
256 napi_create_async_work(
257 env, nullptr, GetResourceName(env, "GetEncoded"),
258 GetEncodedExecute,
259 GetEncodedComplete,
260 static_cast<void *>(context),
261 &context->asyncWork);
262
263 napi_queue_async_work(env, context->asyncWork);
264 if (context->asyncType == ASYNC_TYPE_PROMISE) {
265 return context->promise;
266 } else {
267 return NapiGetNull(env);
268 }
269 }
270
GetPublicKey(napi_env env,napi_callback_info info)271 napi_value NapiX509Certificate::GetPublicKey(napi_env env, napi_callback_info info)
272 {
273 HcfX509Certificate *cert = GetX509Cert();
274 HcfPubKey *returnPubKey = nullptr;
275 HcfResult ret = cert->base.getPublicKey(&(cert->base), &returnPubKey);
276 if (ret != HCF_SUCCESS) {
277 napi_throw(env, GenerateBusinessError(env, ret, "get cert public key failed!", true));
278 LOGE("get cert public key failed!");
279 return nullptr;
280 }
281
282 NapiPubKey *pubKeyClass = new (std::nothrow) NapiPubKey(returnPubKey);
283 if (pubKeyClass == nullptr) {
284 LOGE("create for x509 cert's public key obj failed");
285 HcfObjDestroy(returnPubKey);
286 return nullptr;
287 }
288 napi_value instance = pubKeyClass->ConvertToJsPubKey(env);
289 napi_wrap(
290 env, instance, pubKeyClass,
291 [](napi_env env, void *data, void *hint) {
292 NapiPubKey *pubKeyClass = static_cast<NapiPubKey *>(data);
293 HcfObjDestroy(pubKeyClass->GetPubKey());
294 delete pubKeyClass;
295 return;
296 },
297 nullptr, nullptr);
298 return instance;
299 }
300
CheckValidityWithDate(napi_env env,napi_callback_info info)301 napi_value NapiX509Certificate::CheckValidityWithDate(napi_env env, napi_callback_info info)
302 {
303 size_t argc = ARGS_SIZE_ONE;
304 napi_value argv[ARGS_SIZE_ONE] = { nullptr };
305 napi_value thisVar = nullptr;
306 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
307 if (!CheckArgsCount(env, argc, ARGS_SIZE_ONE, true, true)) {
308 return nullptr;
309 }
310 std::string date;
311 if (!GetStringFromJSParams(env, argv[PARAM0], date, true)) {
312 LOGE("get date param failed!");
313 return nullptr;
314 }
315 HcfX509Certificate *cert = GetX509Cert();
316 HcfResult ret = cert->checkValidityWithDate(cert, date.c_str());
317 if (ret != HCF_SUCCESS) {
318 napi_throw(env, GenerateBusinessError(env, ret, "check cert validity failed!", true));
319 LOGE("check cert validity failed!");
320 }
321 return nullptr;
322 }
323
GetVersion(napi_env env,napi_callback_info info)324 napi_value NapiX509Certificate::GetVersion(napi_env env, napi_callback_info info)
325 {
326 HcfX509Certificate *cert = GetX509Cert();
327 int version = cert->getVersion(cert);
328 napi_value result = nullptr;
329 napi_create_int32(env, version, &result);
330 return result;
331 }
332
333
GetSerialNumber(napi_env env,napi_callback_info info)334 napi_value NapiX509Certificate::GetSerialNumber(napi_env env, napi_callback_info info)
335 {
336 HcfX509Certificate *cert = GetX509Cert();
337 long serialNumber = cert->getSerialNumber(cert);
338 napi_value result = nullptr;
339 napi_create_int64(env, serialNumber, &result);
340 return result;
341 }
342
GetIssuerName(napi_env env,napi_callback_info info)343 napi_value NapiX509Certificate::GetIssuerName(napi_env env, napi_callback_info info)
344 {
345 HcfBlob *blob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
346 if (blob == nullptr) {
347 LOGE("malloc blob failed!");
348 return nullptr;
349 }
350 HcfX509Certificate *cert = GetX509Cert();
351 HcfResult ret = cert->getIssuerName(cert, blob);
352 if (ret != HCF_SUCCESS) {
353 napi_throw(env, GenerateBusinessError(env, ret, "get issuer name failed", true));
354 LOGE("getIssuerName failed!");
355 HcfFree(blob);
356 blob = nullptr;
357 return nullptr;
358 }
359 napi_value returnValue = ConvertBlobToNapiValue(env, blob);
360 HcfBlobDataFree(blob);
361 HcfFree(blob);
362 blob = nullptr;
363 return returnValue;
364 }
365
GetSubjectName(napi_env env,napi_callback_info info)366 napi_value NapiX509Certificate::GetSubjectName(napi_env env, napi_callback_info info)
367 {
368 HcfBlob *blob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
369 if (blob == nullptr) {
370 LOGE("malloc blob failed!");
371 return nullptr;
372 }
373 HcfX509Certificate *cert = GetX509Cert();
374 HcfResult ret = cert->getSubjectName(cert, blob);
375 if (ret != HCF_SUCCESS) {
376 napi_throw(env, GenerateBusinessError(env, ret, "get subject name failed", true));
377 LOGE("getSubjectName failed!");
378 HcfFree(blob);
379 blob = nullptr;
380 return nullptr;
381 }
382 napi_value returnValue = ConvertBlobToNapiValue(env, blob);
383 HcfBlobDataFree(blob);
384 HcfFree(blob);
385 blob = nullptr;
386 return returnValue;
387 }
388
GetNotBeforeTime(napi_env env,napi_callback_info info)389 napi_value NapiX509Certificate::GetNotBeforeTime(napi_env env, napi_callback_info info)
390 {
391 HcfBlob *blob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
392 if (blob == nullptr) {
393 LOGE("malloc blob failed!");
394 return nullptr;
395 }
396 HcfX509Certificate *cert = GetX509Cert();
397 HcfResult res = cert->getNotBeforeTime(cert, blob);
398 if (res != HCF_SUCCESS) {
399 napi_throw(env, GenerateBusinessError(env, res, "get not before time failed", true));
400 LOGE("getNotBeforeTime failed!");
401 HcfFree(blob);
402 blob = nullptr;
403 return nullptr;
404 }
405 napi_value result = nullptr;
406 napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), blob->len, &result);
407 HcfBlobDataFree(blob);
408 HcfFree(blob);
409 blob = nullptr;
410 return result;
411 }
412
GetNotAfterTime(napi_env env,napi_callback_info info)413 napi_value NapiX509Certificate::GetNotAfterTime(napi_env env, napi_callback_info info)
414 {
415 HcfBlob *blob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
416 if (blob == nullptr) {
417 LOGE("malloc blob failed!");
418 return nullptr;
419 }
420 HcfX509Certificate *cert = GetX509Cert();
421 HcfResult res = cert->getNotAfterTime(cert, blob);
422 if (res != HCF_SUCCESS) {
423 napi_throw(env, GenerateBusinessError(env, res, "get not after time failed", true));
424 LOGE("getNotAfterTime failed!");
425 HcfFree(blob);
426 blob = nullptr;
427 return nullptr;
428 }
429 napi_value result = nullptr;
430 napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), blob->len, &result);
431 HcfBlobDataFree(blob);
432 HcfFree(blob);
433 blob = nullptr;
434 return result;
435 }
436
GetSignature(napi_env env,napi_callback_info info)437 napi_value NapiX509Certificate::GetSignature(napi_env env, napi_callback_info info)
438 {
439 HcfBlob *blob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
440 if (blob == nullptr) {
441 LOGE("malloc blob failed!");
442 return nullptr;
443 }
444 HcfX509Certificate *cert = GetX509Cert();
445 HcfResult ret = cert->getSignature(cert, blob);
446 if (ret != HCF_SUCCESS) {
447 napi_throw(env, GenerateBusinessError(env, ret, "get signature failed", true));
448 LOGE("getSignature failed!");
449 HcfFree(blob);
450 blob = nullptr;
451 return nullptr;
452 }
453 napi_value returnValue = ConvertBlobToNapiValue(env, blob);
454 HcfBlobDataFree(blob);
455 HcfFree(blob);
456 blob = nullptr;
457 return returnValue;
458 }
459
GetSigAlgName(napi_env env,napi_callback_info info)460 napi_value NapiX509Certificate::GetSigAlgName(napi_env env, napi_callback_info info)
461 {
462 HcfBlob *blob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
463 if (blob == nullptr) {
464 LOGE("malloc blob failed!");
465 return nullptr;
466 }
467 HcfX509Certificate *cert = GetX509Cert();
468 HcfResult res = cert->getSignatureAlgName(cert, blob);
469 if (res != HCF_SUCCESS) {
470 napi_throw(env, GenerateBusinessError(env, res, "get signature alg name failed", true));
471 LOGE("getSignatureAlgName failed!");
472 HcfFree(blob);
473 blob = nullptr;
474 return nullptr;
475 }
476 napi_value result = nullptr;
477 napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), blob->len, &result);
478 HcfBlobDataFree(blob);
479 HcfFree(blob);
480 blob = nullptr;
481 return result;
482 }
483
GetSigAlgOID(napi_env env,napi_callback_info info)484 napi_value NapiX509Certificate::GetSigAlgOID(napi_env env, napi_callback_info info)
485 {
486 HcfBlob *blob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
487 if (blob == nullptr) {
488 LOGE("malloc blob failed!");
489 return nullptr;
490 }
491 HcfX509Certificate *cert = GetX509Cert();
492 HcfResult res = cert->getSignatureAlgOid(cert, blob);
493 if (res != HCF_SUCCESS) {
494 napi_throw(env, GenerateBusinessError(env, res, "get signature alg oid failed", true));
495 LOGE("getSignatureAlgOid failed!");
496 HcfFree(blob);
497 blob = nullptr;
498 return nullptr;
499 }
500 napi_value result = nullptr;
501 napi_create_string_utf8(env, reinterpret_cast<char *>(blob->data), blob->len, &result);
502 HcfBlobDataFree(blob);
503 HcfFree(blob);
504 blob = nullptr;
505 return result;
506 }
507
GetSigAlgParams(napi_env env,napi_callback_info info)508 napi_value NapiX509Certificate::GetSigAlgParams(napi_env env, napi_callback_info info)
509 {
510 HcfBlob *blob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
511 if (blob == nullptr) {
512 LOGE("malloc blob failed!");
513 return nullptr;
514 }
515 HcfX509Certificate *cert = GetX509Cert();
516 HcfResult ret = cert->getSignatureAlgParams(cert, blob);
517 if (ret != HCF_SUCCESS) {
518 napi_throw(env, GenerateBusinessError(env, ret, "get signature alg params failed", true));
519 LOGE("getSignatureAlgParams failed!");
520 HcfFree(blob);
521 blob = nullptr;
522 return nullptr;
523 }
524 napi_value returnValue = ConvertBlobToNapiValue(env, blob);
525 HcfBlobDataFree(blob);
526 HcfFree(blob);
527 blob = nullptr;
528 return returnValue;
529 }
530
GetKeyUsage(napi_env env,napi_callback_info info)531 napi_value NapiX509Certificate::GetKeyUsage(napi_env env, napi_callback_info info)
532 {
533 HcfBlob *blob = reinterpret_cast<HcfBlob *>(HcfMalloc(sizeof(HcfBlob), 0));
534 if (blob == nullptr) {
535 LOGE("malloc blob failed!");
536 return nullptr;
537 }
538 HcfX509Certificate *cert = GetX509Cert();
539 HcfResult ret = cert->getKeyUsage(cert, blob);
540 if (ret != HCF_SUCCESS) {
541 napi_throw(env, GenerateBusinessError(env, ret, "get key usage failed", true));
542 LOGE("getKeyUsage failed!");
543 HcfFree(blob);
544 blob = nullptr;
545 return nullptr;
546 }
547 napi_value returnValue = ConvertBlobToNapiValue(env, blob);
548 HcfBlobDataFree(blob);
549 HcfFree(blob);
550 blob = nullptr;
551 return returnValue;
552 }
553
GetExtendedKeyUsage(napi_env env,napi_callback_info info)554 napi_value NapiX509Certificate::GetExtendedKeyUsage(napi_env env, napi_callback_info info)
555 {
556 HcfArray *array = reinterpret_cast<HcfArray *>(HcfMalloc(sizeof(HcfArray), 0));
557 if (array == nullptr) {
558 LOGE("malloc array failed!");
559 return nullptr;
560 }
561 HcfX509Certificate *cert = GetX509Cert();
562 HcfResult ret = cert->getExtKeyUsage(cert, array);
563 if (ret != HCF_SUCCESS) {
564 napi_throw(env, GenerateBusinessError(env, ret, "get ext key usage failed", true));
565 LOGE("call getExtKeyUsage failed!");
566 HcfFree(array);
567 array = nullptr;
568 return nullptr;
569 }
570 napi_value returnValue = ConvertArrayToNapiValue(env, array);
571 HcfArrayDataClearAndFree(array);
572 HcfFree(array);
573 array = nullptr;
574 return returnValue;
575 }
576
577
GetBasicConstraints(napi_env env,napi_callback_info info)578 napi_value NapiX509Certificate::GetBasicConstraints(napi_env env, napi_callback_info info)
579 {
580 HcfX509Certificate *cert = GetX509Cert();
581 int32_t constrains = cert->getBasicConstraints(cert);
582 napi_value result = nullptr;
583 napi_create_int32(env, constrains, &result);
584 return result;
585 }
586
GetSubjectAlternativeNames(napi_env env,napi_callback_info info)587 napi_value NapiX509Certificate::GetSubjectAlternativeNames(napi_env env, napi_callback_info info)
588 {
589 HcfArray *array = reinterpret_cast<HcfArray *>(HcfMalloc(sizeof(HcfArray), 0));
590 if (array == nullptr) {
591 LOGE("malloc array failed!");
592 return nullptr;
593 }
594 HcfX509Certificate *cert = GetX509Cert();
595 HcfResult ret = cert->getSubjectAltNames(cert, array);
596 if (ret != HCF_SUCCESS) {
597 napi_throw(env, GenerateBusinessError(env, ret, "get subject alt names failed", true));
598 LOGE("call getSubjectAltNames failed!");
599 HcfFree(array);
600 array = nullptr;
601 return nullptr;
602 }
603 napi_value returnValue = ConvertArrayToNapiValue(env, array);
604 HcfArrayDataClearAndFree(array);
605 HcfFree(array);
606 array = nullptr;
607 return returnValue;
608 }
609
GetIssuerAlternativeNames(napi_env env,napi_callback_info info)610 napi_value NapiX509Certificate::GetIssuerAlternativeNames(napi_env env, napi_callback_info info)
611 {
612 HcfArray *array = reinterpret_cast<HcfArray *>(HcfMalloc(sizeof(HcfArray), 0));
613 if (array == nullptr) {
614 LOGE("malloc array failed!");
615 return nullptr;
616 }
617 HcfX509Certificate *cert = GetX509Cert();
618 HcfResult ret = cert->getIssuerAltNames(cert, array);
619 if (ret != HCF_SUCCESS) {
620 napi_throw(env, GenerateBusinessError(env, ret, "get issuer alt names failed", true));
621 LOGE("call getIssuerAltNames failed!");
622 HcfFree(array);
623 array = nullptr;
624 return nullptr;
625 }
626 napi_value returnValue = ConvertArrayToNapiValue(env, array);
627 HcfArrayDataClearAndFree(array);
628 HcfFree(array);
629 array = nullptr;
630 return returnValue;
631 }
632
NapiVerify(napi_env env,napi_callback_info info)633 static napi_value NapiVerify(napi_env env, napi_callback_info info)
634 {
635 napi_value thisVar = nullptr;
636 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
637 NapiX509Certificate *x509Cert = nullptr;
638 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
639 if (x509Cert == nullptr) {
640 LOGE("x509Cert is nullptr!");
641 return nullptr;
642 }
643 return x509Cert->Verify(env, info);
644 }
645
NapiGetEncoded(napi_env env,napi_callback_info info)646 static napi_value NapiGetEncoded(napi_env env, napi_callback_info info)
647 {
648 napi_value thisVar = nullptr;
649 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
650 NapiX509Certificate *x509Cert = nullptr;
651 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
652 if (x509Cert == nullptr) {
653 LOGE("x509Cert is nullptr!");
654 return nullptr;
655 }
656 return x509Cert->GetEncoded(env, info);
657 }
658
NapiGetPublicKey(napi_env env,napi_callback_info info)659 static napi_value NapiGetPublicKey(napi_env env, napi_callback_info info)
660 {
661 napi_value thisVar = nullptr;
662 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
663 NapiX509Certificate *x509Cert = nullptr;
664 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
665 if (x509Cert == nullptr) {
666 LOGE("x509Cert is nullptr!");
667 return nullptr;
668 }
669 return x509Cert->GetPublicKey(env, info);
670 }
671
NapiCheckValidityWithDate(napi_env env,napi_callback_info info)672 static napi_value NapiCheckValidityWithDate(napi_env env, napi_callback_info info)
673 {
674 napi_value thisVar = nullptr;
675 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
676 NapiX509Certificate *x509Cert = nullptr;
677 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
678 if (x509Cert == nullptr) {
679 LOGE("x509Cert is nullptr!");
680 return nullptr;
681 }
682 return x509Cert->CheckValidityWithDate(env, info);
683 }
684
NapiGetVersion(napi_env env,napi_callback_info info)685 static napi_value NapiGetVersion(napi_env env, napi_callback_info info)
686 {
687 napi_value thisVar = nullptr;
688 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
689 NapiX509Certificate *x509Cert = nullptr;
690 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
691 if (x509Cert == nullptr) {
692 LOGE("x509Cert is nullptr!");
693 return nullptr;
694 }
695 return x509Cert->GetVersion(env, info);
696 }
697
NapiGetSerialNumber(napi_env env,napi_callback_info info)698 static napi_value NapiGetSerialNumber(napi_env env, napi_callback_info info)
699 {
700 napi_value thisVar = nullptr;
701 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
702 NapiX509Certificate *x509Cert = nullptr;
703 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
704 if (x509Cert == nullptr) {
705 LOGE("x509Cert is nullptr!");
706 return nullptr;
707 }
708 return x509Cert->GetSerialNumber(env, info);
709 }
710
NapiGetIssuerName(napi_env env,napi_callback_info info)711 static napi_value NapiGetIssuerName(napi_env env, napi_callback_info info)
712 {
713 napi_value thisVar = nullptr;
714 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
715 NapiX509Certificate *x509Cert = nullptr;
716 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
717 if (x509Cert == nullptr) {
718 LOGE("x509Cert is nullptr!");
719 return nullptr;
720 }
721 return x509Cert->GetIssuerName(env, info);
722 }
723
NapiGetSubjectName(napi_env env,napi_callback_info info)724 static napi_value NapiGetSubjectName(napi_env env, napi_callback_info info)
725 {
726 napi_value thisVar = nullptr;
727 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
728 NapiX509Certificate *x509Cert = nullptr;
729 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
730 if (x509Cert == nullptr) {
731 LOGE("x509Cert is nullptr!");
732 return nullptr;
733 }
734 return x509Cert->GetSubjectName(env, info);
735 }
736
NapiGetNotBeforeTime(napi_env env,napi_callback_info info)737 static napi_value NapiGetNotBeforeTime(napi_env env, napi_callback_info info)
738 {
739 napi_value thisVar = nullptr;
740 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
741 NapiX509Certificate *x509Cert = nullptr;
742 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
743 if (x509Cert == nullptr) {
744 LOGE("x509Cert is nullptr!");
745 return nullptr;
746 }
747 return x509Cert->GetNotBeforeTime(env, info);
748 }
749
NapiGetNotAfterTime(napi_env env,napi_callback_info info)750 static napi_value NapiGetNotAfterTime(napi_env env, napi_callback_info info)
751 {
752 napi_value thisVar = nullptr;
753 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
754 NapiX509Certificate *x509Cert = nullptr;
755 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
756 if (x509Cert == nullptr) {
757 LOGE("x509Cert is nullptr!");
758 return nullptr;
759 }
760 return x509Cert->GetNotAfterTime(env, info);
761 }
762
NapiGetSignature(napi_env env,napi_callback_info info)763 static napi_value NapiGetSignature(napi_env env, napi_callback_info info)
764 {
765 napi_value thisVar = nullptr;
766 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
767 NapiX509Certificate *x509Cert = nullptr;
768 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
769 if (x509Cert == nullptr) {
770 LOGE("x509Cert is nullptr!");
771 return nullptr;
772 }
773 return x509Cert->GetSignature(env, info);
774 }
775
NapiGetSigAlgName(napi_env env,napi_callback_info info)776 static napi_value NapiGetSigAlgName(napi_env env, napi_callback_info info)
777 {
778 napi_value thisVar = nullptr;
779 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
780 NapiX509Certificate *x509Cert = nullptr;
781 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
782 if (x509Cert == nullptr) {
783 LOGE("x509Cert is nullptr!");
784 return nullptr;
785 }
786 return x509Cert->GetSigAlgName(env, info);
787 }
788
NapiGetSigAlgOID(napi_env env,napi_callback_info info)789 static napi_value NapiGetSigAlgOID(napi_env env, napi_callback_info info)
790 {
791 napi_value thisVar = nullptr;
792 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
793 NapiX509Certificate *x509Cert = nullptr;
794 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
795 if (x509Cert == nullptr) {
796 LOGE("x509Cert is nullptr!");
797 return nullptr;
798 }
799 return x509Cert->GetSigAlgOID(env, info);
800 }
801
NapiGetSigAlgParams(napi_env env,napi_callback_info info)802 static napi_value NapiGetSigAlgParams(napi_env env, napi_callback_info info)
803 {
804 napi_value thisVar = nullptr;
805 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
806 NapiX509Certificate *x509Cert = nullptr;
807 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
808 if (x509Cert == nullptr) {
809 LOGE("x509Cert is nullptr!");
810 return nullptr;
811 }
812 return x509Cert->GetSigAlgParams(env, info);
813 }
814
NapiGetKeyUsage(napi_env env,napi_callback_info info)815 static napi_value NapiGetKeyUsage(napi_env env, napi_callback_info info)
816 {
817 napi_value thisVar = nullptr;
818 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
819 NapiX509Certificate *x509Cert = nullptr;
820 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
821 if (x509Cert == nullptr) {
822 LOGE("x509Cert is nullptr!");
823 return nullptr;
824 }
825 return x509Cert->GetKeyUsage(env, info);
826 }
827
NapiGetExtendedKeyUsage(napi_env env,napi_callback_info info)828 static napi_value NapiGetExtendedKeyUsage(napi_env env, napi_callback_info info)
829 {
830 napi_value thisVar = nullptr;
831 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
832 NapiX509Certificate *x509Cert = nullptr;
833 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
834 if (x509Cert == nullptr) {
835 LOGE("x509Cert is nullptr!");
836 return nullptr;
837 }
838 return x509Cert->GetExtendedKeyUsage(env, info);
839 }
840
NapiGetBasicConstraints(napi_env env,napi_callback_info info)841 static napi_value NapiGetBasicConstraints(napi_env env, napi_callback_info info)
842 {
843 napi_value thisVar = nullptr;
844 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
845 NapiX509Certificate *x509Cert = nullptr;
846 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
847 if (x509Cert == nullptr) {
848 LOGE("x509Cert is nullptr!");
849 return nullptr;
850 }
851 return x509Cert->GetBasicConstraints(env, info);
852 }
853
NapiGetSubjectAlternativeNames(napi_env env,napi_callback_info info)854 static napi_value NapiGetSubjectAlternativeNames(napi_env env, napi_callback_info info)
855 {
856 napi_value thisVar = nullptr;
857 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
858 NapiX509Certificate *x509Cert = nullptr;
859 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
860 if (x509Cert == nullptr) {
861 LOGE("x509Cert is nullptr!");
862 return nullptr;
863 }
864 return x509Cert->GetSubjectAlternativeNames(env, info);
865 }
866
NapiGetIssuerAlternativeNames(napi_env env,napi_callback_info info)867 static napi_value NapiGetIssuerAlternativeNames(napi_env env, napi_callback_info info)
868 {
869 napi_value thisVar = nullptr;
870 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
871 NapiX509Certificate *x509Cert = nullptr;
872 napi_unwrap(env, thisVar, reinterpret_cast<void **>(&x509Cert));
873 if (x509Cert == nullptr) {
874 LOGE("x509Cert is nullptr!");
875 return nullptr;
876 }
877 return x509Cert->GetIssuerAlternativeNames(env, info);
878 }
879
CreateX509CertExecute(napi_env env,void * data)880 void NapiX509Certificate::CreateX509CertExecute(napi_env env, void *data)
881 {
882 CfCtx *context = static_cast<CfCtx *>(data);
883 context->errCode = HcfX509CertificateCreate(context->encodingBlob, &context->cert);
884 if (context->errCode != HCF_SUCCESS) {
885 context->errMsg = "create X509Cert failed";
886 }
887 }
888
CreateX509CertComplete(napi_env env,napi_status status,void * data)889 void NapiX509Certificate::CreateX509CertComplete(napi_env env, napi_status status, void *data)
890 {
891 CfCtx *context = static_cast<CfCtx *>(data);
892 if (context->errCode != HCF_SUCCESS) {
893 LOGE("call create X509Cert failed!");
894 ReturnResult(env, context, nullptr);
895 FreeCryptoFwkCtx(env, context);
896 return;
897 }
898 napi_value instance = CreateX509Cert(env);
899 NapiX509Certificate *x509CertClass = new NapiX509Certificate(context->cert);
900 napi_wrap(
901 env, instance, x509CertClass,
902 [](napi_env env, void *data, void *hint) {
903 NapiX509Certificate *certClass = static_cast<NapiX509Certificate *>(data);
904 delete certClass;
905 return;
906 },
907 nullptr, nullptr);
908 ReturnResult(env, context, instance);
909 FreeCryptoFwkCtx(env, context);
910 }
911
NapiCreateX509Cert(napi_env env,napi_callback_info info)912 napi_value NapiX509Certificate::NapiCreateX509Cert(napi_env env, napi_callback_info info)
913 {
914 size_t argc = ARGS_SIZE_TWO;
915 napi_value argv[ARGS_SIZE_TWO] = { nullptr };
916 napi_value thisVar = nullptr;
917 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
918 if (!CheckArgsCount(env, argc, ARGS_SIZE_TWO, false, true)) {
919 return nullptr;
920 }
921
922 CfCtx *context = static_cast<CfCtx *>(HcfMalloc(sizeof(CfCtx), 0));
923 if (context == nullptr) {
924 LOGE("malloc context failed!");
925 return nullptr;
926 }
927 if (!GetEncodingBlobFromValue(env, argv[PARAM0], &context->encodingBlob)) {
928 LOGE("get encoding blob from data failed!");
929 FreeCryptoFwkCtx(env, context);
930 return nullptr;
931 }
932
933 if (!CreateCallbackAndPromise(env, context, argc, ARGS_SIZE_TWO, argv[PARAM1])) {
934 FreeCryptoFwkCtx(env, context);
935 return nullptr;
936 }
937
938 napi_create_async_work(
939 env, nullptr, GetResourceName(env, "CreateX509Cert"),
940 CreateX509CertExecute,
941 CreateX509CertComplete,
942 static_cast<void *>(context),
943 &context->asyncWork);
944
945 napi_queue_async_work(env, context->asyncWork);
946 if (context->asyncType == ASYNC_TYPE_PROMISE) {
947 return context->promise;
948 } else {
949 return NapiGetNull(env);
950 }
951 }
952
X509CertConstructor(napi_env env,napi_callback_info info)953 static napi_value X509CertConstructor(napi_env env, napi_callback_info info)
954 {
955 napi_value thisVar = nullptr;
956 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
957 return thisVar;
958 }
959
DefineX509CertJSClass(napi_env env,napi_value exports)960 void NapiX509Certificate::DefineX509CertJSClass(napi_env env, napi_value exports)
961 {
962 napi_property_descriptor desc[] = {
963 DECLARE_NAPI_FUNCTION("createX509Cert", NapiCreateX509Cert),
964 };
965 napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
966
967 napi_property_descriptor x509CertDesc[] = {
968 DECLARE_NAPI_FUNCTION("verify", NapiVerify),
969 DECLARE_NAPI_FUNCTION("getEncoded", NapiGetEncoded),
970 DECLARE_NAPI_FUNCTION("getPublicKey", NapiGetPublicKey),
971 DECLARE_NAPI_FUNCTION("checkValidityWithDate", NapiCheckValidityWithDate),
972 DECLARE_NAPI_FUNCTION("getVersion", NapiGetVersion),
973 DECLARE_NAPI_FUNCTION("getSerialNumber", NapiGetSerialNumber),
974 DECLARE_NAPI_FUNCTION("getIssuerName", NapiGetIssuerName),
975 DECLARE_NAPI_FUNCTION("getSubjectName", NapiGetSubjectName),
976 DECLARE_NAPI_FUNCTION("getNotBeforeTime", NapiGetNotBeforeTime),
977 DECLARE_NAPI_FUNCTION("getNotAfterTime", NapiGetNotAfterTime),
978 DECLARE_NAPI_FUNCTION("getSignature", NapiGetSignature),
979 DECLARE_NAPI_FUNCTION("getSignatureAlgName", NapiGetSigAlgName),
980 DECLARE_NAPI_FUNCTION("getSignatureAlgOid", NapiGetSigAlgOID),
981 DECLARE_NAPI_FUNCTION("getSignatureAlgParams", NapiGetSigAlgParams),
982 DECLARE_NAPI_FUNCTION("getKeyUsage", NapiGetKeyUsage),
983 DECLARE_NAPI_FUNCTION("getExtKeyUsage", NapiGetExtendedKeyUsage),
984 DECLARE_NAPI_FUNCTION("getBasicConstraints", NapiGetBasicConstraints),
985 DECLARE_NAPI_FUNCTION("getSubjectAltNames", NapiGetSubjectAlternativeNames),
986 DECLARE_NAPI_FUNCTION("getIssuerAltNames", NapiGetIssuerAlternativeNames),
987 };
988 napi_value constructor = nullptr;
989 napi_define_class(env, "X509Cert", NAPI_AUTO_LENGTH, X509CertConstructor, nullptr,
990 sizeof(x509CertDesc) / sizeof(x509CertDesc[0]), x509CertDesc, &constructor);
991 napi_create_reference(env, constructor, 1, &classRef_);
992 }
993
CreateX509Cert(napi_env env)994 napi_value NapiX509Certificate::CreateX509Cert(napi_env env)
995 {
996 napi_value constructor = nullptr;
997 napi_value instance = nullptr;
998 napi_get_reference_value(env, classRef_, &constructor);
999 napi_new_instance(env, constructor, 0, nullptr, &instance);
1000 return instance;
1001 }
1002 } // namespace CryptoFramework
1003 } // namespace OHOS
1004