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