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_trust_anchor.h"
17
18 #include "cf_log.h"
19 #include "cf_memory.h"
20 #include "cf_type.h"
21 #include "napi/native_api.h"
22 #include "napi/native_node_api.h"
23 #include "napi_cert_defines.h"
24 #include "napi_cert_utils.h"
25 #include "napi_object.h"
26 #include "napi_x509_certificate.h"
27 #include "napi_cert_crl_common.h"
28 #include "utils.h"
29
30 namespace OHOS {
31 namespace CertFramework {
32
GetCACert(napi_env env,napi_value arg,HcfX509Certificate * & out)33 static bool GetCACert(napi_env env, napi_value arg, HcfX509Certificate *&out)
34 {
35 napi_value obj = GetProp(env, arg, CERT_CHAIN_TRUSTANCHOR_TAG_CACERT.c_str());
36 if (obj == nullptr) {
37 return true;
38 }
39 NapiX509Certificate *napiX509Cert = nullptr;
40 napi_unwrap(env, obj, reinterpret_cast<void **>(&napiX509Cert));
41 if (napiX509Cert == nullptr) {
42 LOGE("napiX509Cert is null!");
43 return false;
44 }
45
46 out = napiX509Cert->GetX509Cert();
47 if (out == nullptr) {
48 LOGE("out is null!");
49 return false;
50 }
51 return true;
52 }
53
GetCASubject(napi_env env,napi_value arg,CfBlob * & out)54 static bool GetCASubject(napi_env env, napi_value arg, CfBlob *&out)
55 {
56 napi_value obj = GetProp(env, arg, CERT_CHAIN_TRUSTANCHOR_TAG_CASUBJECT.c_str());
57 if (obj == nullptr) {
58 return true;
59 }
60 out = CertGetBlobFromUint8ArrJSParams(env, obj);
61 if (out == nullptr) {
62 LOGE("out is null!");
63 return false;
64 }
65 return true;
66 }
67
GetCAPubKey(napi_env env,napi_value arg,CfBlob * & out)68 static bool GetCAPubKey(napi_env env, napi_value arg, CfBlob *&out)
69 {
70 napi_value obj = GetProp(env, arg, CERT_CHAIN_TRUSTANCHOR_TAG_CAPUBKEY.c_str());
71 if (obj == nullptr) {
72 return true;
73 }
74 out = CertGetBlobFromUint8ArrJSParams(env, obj);
75 if (out == nullptr) {
76 LOGE("out is null!");
77 return false;
78 }
79 return true;
80 }
81
BuildX509TrustAnchorJS(napi_env env,const HcfX509TrustAnchor * trustAnchor)82 napi_value BuildX509TrustAnchorJS(napi_env env, const HcfX509TrustAnchor *trustAnchor)
83 {
84 if (trustAnchor == nullptr) {
85 LOGE("input param invalid!");
86 return nullptr;
87 }
88 napi_value instance = nullptr;
89 napi_create_object(env, &instance);
90 if (trustAnchor->CAPubKey != nullptr) {
91 napi_value CAPubKey = ConvertBlobToUint8ArrNapiValue(env, trustAnchor->CAPubKey);
92 if (CAPubKey == nullptr) {
93 LOGE("CA pub key convert failed!");
94 return nullptr;
95 }
96 napi_set_named_property(env, instance, CERT_CHAIN_TRUSTANCHOR_TAG_CAPUBKEY.c_str(), CAPubKey);
97 }
98
99 if (trustAnchor->CASubject != nullptr) {
100 napi_value CASubject = ConvertBlobToUint8ArrNapiValue(env, trustAnchor->CASubject);
101 if (CASubject == nullptr) {
102 LOGE("CA subject convert failed!");
103 return nullptr;
104 }
105 napi_set_named_property(env, instance, CERT_CHAIN_TRUSTANCHOR_TAG_CASUBJECT.c_str(), CASubject);
106 }
107
108 if (trustAnchor->CACert != nullptr) {
109 napi_value CACert = ConvertCertToNapiValue(env, trustAnchor->CACert);
110 if (CACert == nullptr) {
111 LOGE("CA cert convert failed!");
112 return nullptr;
113 }
114 napi_set_named_property(env, instance, CERT_CHAIN_TRUSTANCHOR_TAG_CACERT.c_str(), CACert);
115 }
116
117 return instance;
118 }
119
BuildX509TrustAnchorObj(napi_env env,napi_value arg,HcfX509TrustAnchor * & trustAnchor)120 bool BuildX509TrustAnchorObj(napi_env env, napi_value arg, HcfX509TrustAnchor *&trustAnchor)
121 {
122 napi_valuetype type;
123 napi_typeof(env, arg, &type);
124 if (type != napi_object) {
125 LOGE("wrong argument type. expect string type. [Type]: %d", type);
126 return false;
127 }
128 trustAnchor = static_cast<HcfX509TrustAnchor *>(HcfMalloc(sizeof(HcfX509TrustAnchor), 0));
129 if (trustAnchor == nullptr) {
130 LOGE("Failed to allocate data memory!");
131 return false;
132 }
133
134 if (!GetCAPubKey(env, arg, trustAnchor->CAPubKey)) {
135 FreeX509TrustAnchorObj(trustAnchor);
136 return false;
137 }
138 if (!GetCACert(env, arg, trustAnchor->CACert)) {
139 FreeX509TrustAnchorObj(trustAnchor);
140 return false;
141 }
142 if (!GetCASubject(env, arg, trustAnchor->CASubject)) {
143 FreeX509TrustAnchorObj(trustAnchor);
144 return false;
145 }
146 return true;
147 }
148
149 /* [freeCertFlag] : if building a obj for RETURN failed, the cert object need to free manually. */
FreeX509TrustAnchorObj(HcfX509TrustAnchor * & trustAnchor,bool freeCertFlag)150 void FreeX509TrustAnchorObj(HcfX509TrustAnchor *&trustAnchor, bool freeCertFlag)
151 {
152 if (trustAnchor == nullptr) {
153 return;
154 }
155 CfBlobFree(&trustAnchor->CAPubKey);
156 CfBlobFree(&trustAnchor->CASubject);
157 if (freeCertFlag) {
158 CfObjDestroy(trustAnchor->CACert);
159 }
160 trustAnchor->CACert = nullptr;
161
162 CF_FREE_PTR(trustAnchor);
163 }
164
165 } // namespace CertFramework
166 } // namespace OHOS