1 /*
2 * Copyright (c) 2023-2024 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_common.h"
23 #include "napi_cert_crl_common.h"
24 #include "napi_cert_defines.h"
25 #include "napi_cert_utils.h"
26 #include "napi_object.h"
27 #include "napi_x509_certificate.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
GetNameConstraints(napi_env env,napi_value arg,CfBlob * & out)68 static bool GetNameConstraints(napi_env env, napi_value arg, CfBlob *&out)
69 {
70 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_NAME_CONSTRAINTS.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
GetCAPubKey(napi_env env,napi_value arg,CfBlob * & out)82 static bool GetCAPubKey(napi_env env, napi_value arg, CfBlob *&out)
83 {
84 napi_value obj = GetProp(env, arg, CERT_CHAIN_TRUSTANCHOR_TAG_CAPUBKEY.c_str());
85 if (obj == nullptr) {
86 return true;
87 }
88 out = CertGetBlobFromUint8ArrJSParams(env, obj);
89 if (out == nullptr) {
90 LOGE("out is null!");
91 return false;
92 }
93 return true;
94 }
95
BuildX509TrustAnchorJS(napi_env env,const HcfX509TrustAnchor * trustAnchor)96 napi_value BuildX509TrustAnchorJS(napi_env env, const HcfX509TrustAnchor *trustAnchor)
97 {
98 if (trustAnchor == nullptr) {
99 LOGE("input param invalid!");
100 return nullptr;
101 }
102 napi_value instance = nullptr;
103 napi_create_object(env, &instance);
104 if (trustAnchor->CAPubKey != nullptr) {
105 napi_value CAPubKey = ConvertBlobToUint8ArrNapiValue(env, trustAnchor->CAPubKey);
106 if (CAPubKey == nullptr) {
107 LOGE("CA pub key convert failed!");
108 return nullptr;
109 }
110 napi_set_named_property(env, instance, CERT_CHAIN_TRUSTANCHOR_TAG_CAPUBKEY.c_str(), CAPubKey);
111 }
112
113 if (trustAnchor->CASubject != nullptr) {
114 napi_value CASubject = ConvertBlobToUint8ArrNapiValue(env, trustAnchor->CASubject);
115 if (CASubject == nullptr) {
116 LOGE("CA subject convert failed!");
117 return nullptr;
118 }
119 napi_set_named_property(env, instance, CERT_CHAIN_TRUSTANCHOR_TAG_CASUBJECT.c_str(), CASubject);
120 }
121
122 if (trustAnchor->CACert != nullptr) {
123 napi_value CACert = ConvertCertToNapiValue(env, trustAnchor->CACert);
124 if (CACert == nullptr) {
125 LOGE("CA cert convert failed!");
126 return nullptr;
127 }
128 napi_set_named_property(env, instance, CERT_CHAIN_TRUSTANCHOR_TAG_CACERT.c_str(), CACert);
129 }
130
131 if (trustAnchor->nameConstraints != nullptr) {
132 napi_value nameConstraints = ConvertBlobToUint8ArrNapiValue(env, trustAnchor->nameConstraints);
133 if (nameConstraints == nullptr) {
134 LOGE("Name constraints convert failed!");
135 return nullptr;
136 }
137 napi_set_named_property(env, instance, CERT_MATCH_TAG_NAME_CONSTRAINTS.c_str(), nameConstraints);
138 }
139
140 return instance;
141 }
142
BuildX509TrustAnchorObj(napi_env env,napi_value arg,HcfX509TrustAnchor * & trustAnchor)143 bool BuildX509TrustAnchorObj(napi_env env, napi_value arg, HcfX509TrustAnchor *&trustAnchor)
144 {
145 napi_valuetype type;
146 napi_typeof(env, arg, &type);
147 if (type != napi_object) {
148 LOGE("wrong argument type. expect string type. [Type]: %d", type);
149 return false;
150 }
151 trustAnchor = static_cast<HcfX509TrustAnchor *>(CfMalloc(sizeof(HcfX509TrustAnchor), 0));
152 if (trustAnchor == nullptr) {
153 LOGE("Failed to allocate data memory!");
154 return false;
155 }
156
157 if (!GetCAPubKey(env, arg, trustAnchor->CAPubKey)) {
158 FreeX509TrustAnchorObj(trustAnchor);
159 return false;
160 }
161 if (!GetCACert(env, arg, trustAnchor->CACert)) {
162 FreeX509TrustAnchorObj(trustAnchor);
163 return false;
164 }
165 if (!GetCASubject(env, arg, trustAnchor->CASubject)) {
166 FreeX509TrustAnchorObj(trustAnchor);
167 return false;
168 }
169 if (!GetNameConstraints(env, arg, trustAnchor->nameConstraints)) {
170 FreeX509TrustAnchorObj(trustAnchor);
171 return false;
172 }
173 return true;
174 }
175
176 /* [freeCertFlag] : if building a obj for RETURN failed, the cert object need to free manually. */
FreeX509TrustAnchorObj(HcfX509TrustAnchor * & trustAnchor,bool freeCertFlag)177 void FreeX509TrustAnchorObj(HcfX509TrustAnchor *&trustAnchor, bool freeCertFlag)
178 {
179 if (trustAnchor == nullptr) {
180 return;
181 }
182 CfBlobFree(&trustAnchor->CAPubKey);
183 CfBlobFree(&trustAnchor->CASubject);
184 CfBlobFree(&trustAnchor->nameConstraints);
185 if (freeCertFlag) {
186 CfObjDestroy(trustAnchor->CACert);
187 }
188 trustAnchor->CACert = nullptr;
189
190 CF_FREE_PTR(trustAnchor);
191 }
192
193 } // namespace CertFramework
194 } // namespace OHOS
195