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_cert_match_parameters.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_defines.h"
24 #include "napi_cert_utils.h"
25 #include "napi_object.h"
26 #include "napi_x509_certificate.h"
27 #include "utils.h"
28
29 namespace OHOS {
30 namespace CertFramework {
31
GetValidDate(napi_env env,napi_value arg,CfBlob * & out)32 static bool GetValidDate(napi_env env, napi_value arg, CfBlob *&out)
33 {
34 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_VALID_DATE.c_str());
35 if (obj == nullptr) {
36 return true;
37 }
38
39 out = CertGetBlobFromStringJSParams(env, obj);
40 if (out == nullptr) {
41 LOGE("out is nullptr");
42 return false;
43 }
44 return true;
45 }
46
GetIssuer(napi_env env,napi_value arg,CfBlob * & out)47 static bool GetIssuer(napi_env env, napi_value arg, CfBlob *&out)
48 {
49 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_ISSUER.c_str());
50 if (obj == nullptr) {
51 return true;
52 }
53 out = CertGetBlobFromUint8ArrJSParams(env, obj);
54 if (out == nullptr) {
55 LOGE("out is nullptr");
56 return false;
57 }
58 return true;
59 }
60
GetKeyUsage(napi_env env,napi_value arg,CfBlob * & out)61 static bool GetKeyUsage(napi_env env, napi_value arg, CfBlob *&out)
62 {
63 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_KEY_USAGE.c_str());
64 if (obj == nullptr) {
65 return true;
66 }
67 out = CertGetBlobFromArrBoolJSParams(env, obj);
68 if (out == nullptr) {
69 LOGE("out is nullptr");
70 return false;
71 }
72 return true;
73 }
74
GetSerialNumber(napi_env env,napi_value arg,CfBlob * & out)75 static bool GetSerialNumber(napi_env env, napi_value arg, CfBlob *&out)
76 {
77 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_SERIAL_NUMBER.c_str());
78 if (obj == nullptr) {
79 return true;
80 }
81 CfBlob outBlob = { 0, nullptr };
82 bool flag = CertGetSerialNumberFromBigIntJSParams(env, obj, outBlob);
83 if (!flag || outBlob.data == nullptr || outBlob.size == 0) {
84 LOGE("out is nullptr");
85 return false;
86 }
87 out = static_cast<CfBlob *>(CfMalloc(sizeof(CfBlob), 0));
88 if (out == nullptr) {
89 LOGE("Failed to allocate newBlob memory!");
90 CfBlobDataFree(&outBlob);
91 return false;
92 }
93 out->data = outBlob.data;
94 out->size = outBlob.size;
95 return true;
96 }
97
GetSubject(napi_env env,napi_value arg,CfBlob * & out)98 static bool GetSubject(napi_env env, napi_value arg, CfBlob *&out)
99 {
100 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_SUBJECT.c_str());
101 if (obj == nullptr) {
102 return true;
103 }
104 out = CertGetBlobFromUint8ArrJSParams(env, obj);
105 if (out == nullptr) {
106 LOGE("out is nullptr");
107 return false;
108 }
109 return true;
110 }
111
GetPublicKey(napi_env env,napi_value arg,CfBlob * & out)112 static bool GetPublicKey(napi_env env, napi_value arg, CfBlob *&out)
113 {
114 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_PUBLIC_KEY.c_str());
115 if (obj == nullptr) {
116 return true;
117 }
118 out = CertGetBlobFromNapiValue(env, obj);
119 if (out == nullptr) {
120 LOGE("out is nullptr");
121 return false;
122 }
123 return true;
124 }
125
GetPublicKeyAlgId(napi_env env,napi_value arg,CfBlob * & out)126 static bool GetPublicKeyAlgId(napi_env env, napi_value arg, CfBlob *&out)
127 {
128 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_PUBLIC_KEY_ALGID.c_str());
129 if (obj == nullptr) {
130 return true;
131 }
132 out = CertGetBlobFromStringJSParams(env, obj);
133 if (out == nullptr) {
134 LOGE("out is nullptr");
135 return false;
136 }
137 return true;
138 }
139
GetX509Cert(napi_env env,napi_value arg,HcfCertificate * & out)140 static bool GetX509Cert(napi_env env, napi_value arg, HcfCertificate *&out)
141 {
142 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_X509CERT.c_str());
143 if (obj == nullptr) {
144 return true;
145 }
146 NapiX509Certificate *napiX509Cert = nullptr;
147 napi_unwrap(env, obj, reinterpret_cast<void **>(&napiX509Cert));
148 if (napiX509Cert == nullptr) {
149 LOGE("napiX509Cert is null!");
150 return false;
151 }
152
153 HcfX509Certificate *cert = napiX509Cert->GetX509Cert();
154 if (cert == nullptr) {
155 LOGE("cert is null!");
156 return false;
157 }
158 out = &(cert->base);
159 return true;
160 }
161
GetSubjectAltNamesArray(napi_env env,napi_value arg,SubAltNameArray * & out)162 static bool GetSubjectAltNamesArray(napi_env env, napi_value arg, SubAltNameArray *&out)
163 {
164 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_SUBJECT_ALT_NAMES.c_str());
165 if (obj == nullptr) {
166 return true;
167 }
168 out = CertGetSANArrFromArrUarrJSParams(env, obj);
169 if (out == nullptr) {
170 LOGE("Failed to get subject alternative name array!");
171 return false;
172 }
173 return true;
174 }
175
GetMatchAllSubjectAltNames(napi_env env,napi_value arg,bool & out)176 static bool GetMatchAllSubjectAltNames(napi_env env, napi_value arg, bool &out)
177 {
178 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_MATCH_ALL_SUBJECT.c_str());
179 if (obj == nullptr) {
180 return true;
181 }
182
183 napi_valuetype valueType;
184 napi_typeof(env, obj, &valueType);
185 if (valueType != napi_boolean) {
186 LOGE("Get %s obj is not bool!", CERT_MATCH_TAG_MATCH_ALL_SUBJECT.c_str());
187 return false;
188 }
189
190 napi_status status = napi_get_value_bool(env, obj, &out);
191 if (status != napi_ok) {
192 LOGE("Failed to get value bool!");
193 return false;
194 }
195 return true;
196 }
197
GetAuthorityKeyIdentifier(napi_env env,napi_value arg,CfBlob * & out)198 static bool GetAuthorityKeyIdentifier(napi_env env, napi_value arg, CfBlob *&out)
199 {
200 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_AUTH_KEY_ID.c_str());
201 if (obj == nullptr) {
202 return true;
203 }
204 out = CertGetBlobFromUint8ArrJSParams(env, obj);
205 if (out == nullptr) {
206 LOGE("Out is nullptr");
207 return false;
208 }
209 return true;
210 }
211
GetMinPathLenConstraint(napi_env env,napi_value arg,int32_t & out)212 static bool GetMinPathLenConstraint(napi_env env, napi_value arg, int32_t &out)
213 {
214 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_MIN_PATH_LEN.c_str());
215 if (obj == nullptr) {
216 out = -1; // default value
217 return true;
218 }
219 napi_status status = napi_get_value_int32(env, obj, &out);
220 if (status != napi_ok) {
221 LOGE("Failed to get value int32!");
222 return false;
223 }
224 return true;
225 }
226
GetExtendedKeyUsage(napi_env env,napi_value arg,CfArray * & out)227 static bool GetExtendedKeyUsage(napi_env env, napi_value arg, CfArray *&out)
228 {
229 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_EXTENDED_KEY_USAGE.c_str());
230 if (obj == nullptr) {
231 return true;
232 }
233 out = CertGetArrFromArrUarrJSParams(env, obj);
234 if (out == nullptr) {
235 LOGE("Out is nullptr");
236 return false;
237 }
238 return true;
239 }
240
GetNameConstraints(napi_env env,napi_value arg,CfBlob * & out)241 static bool GetNameConstraints(napi_env env, napi_value arg, CfBlob *&out)
242 {
243 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_NAME_CONSTRAINTS.c_str());
244 if (obj == nullptr) {
245 return true;
246 }
247 out = CertGetBlobFromUint8ArrJSParams(env, obj);
248 if (out == nullptr) {
249 LOGE("Out is nullptr");
250 return false;
251 }
252 return true;
253 }
254
GetCertPolicy(napi_env env,napi_value arg,CfArray * & out)255 static bool GetCertPolicy(napi_env env, napi_value arg, CfArray *&out)
256 {
257 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_CERT_POLICY.c_str());
258 if (obj == nullptr) {
259 return true;
260 }
261 out = CertGetArrFromArrUarrJSParams(env, obj);
262 if (out == nullptr) {
263 LOGE("Out is nullptr");
264 return false;
265 }
266 return true;
267 }
268
GetPrivateKeyValid(napi_env env,napi_value arg,CfBlob * & out)269 static bool GetPrivateKeyValid(napi_env env, napi_value arg, CfBlob *&out)
270 {
271 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_PRIVATE_KEY_VALID.c_str());
272 if (obj == nullptr) {
273 return true;
274 }
275
276 out = CertGetBlobFromStringJSParams(env, obj);
277 if (out == nullptr) {
278 LOGE("Out is nullptr");
279 return false;
280 }
281 return true;
282 }
283
GetSubjectKeyIdentifier(napi_env env,napi_value arg,CfBlob * & out)284 static bool GetSubjectKeyIdentifier(napi_env env, napi_value arg, CfBlob *&out)
285 {
286 napi_value obj = GetProp(env, arg, CERT_MATCH_TAG_SUBJECT_KEY_IDENTIFIER.c_str());
287 if (obj == nullptr) {
288 return true;
289 }
290 out = CertGetBlobFromUint8ArrJSParams(env, obj);
291 if (out == nullptr) {
292 LOGE("Out is nullptr.");
293 return false;
294 }
295 return true;
296 }
297
BuildX509CertMatchParamsV1(napi_env env,napi_value arg,HcfX509CertMatchParams * & matchParams)298 bool BuildX509CertMatchParamsV1(napi_env env, napi_value arg, HcfX509CertMatchParams *&matchParams)
299 {
300 napi_valuetype type;
301 napi_typeof(env, arg, &type);
302 if (type != napi_object) {
303 LOGE("Wrong argument type. expect object type. [Type]: %d", type);
304 return false;
305 }
306 if (!GetValidDate(env, arg, matchParams->validDate)) {
307 return false;
308 }
309 if (!GetIssuer(env, arg, matchParams->issuer)) {
310 return false;
311 }
312 if (!GetKeyUsage(env, arg, matchParams->keyUsage)) {
313 return false;
314 }
315 if (!GetSerialNumber(env, arg, matchParams->serialNumber)) {
316 return false;
317 }
318 if (!GetSubject(env, arg, matchParams->subject)) {
319 return false;
320 }
321 if (!GetPublicKey(env, arg, matchParams->publicKey)) {
322 return false;
323 }
324 if (!GetPublicKeyAlgId(env, arg, matchParams->publicKeyAlgID)) {
325 return false;
326 }
327 if (!GetX509Cert(env, arg, matchParams->x509Cert)) {
328 return false;
329 }
330 return true;
331 }
332
BuildX509CertMatchParamsV2(napi_env env,napi_value arg,HcfX509CertMatchParams * & matchParams)333 bool BuildX509CertMatchParamsV2(napi_env env, napi_value arg, HcfX509CertMatchParams *&matchParams)
334 {
335 napi_valuetype type;
336 napi_typeof(env, arg, &type);
337 if (type != napi_object) {
338 LOGE("Wrong argument type. expect object type. [Type]: %d", type);
339 return false;
340 }
341 if (!GetSubjectAltNamesArray(env, arg, matchParams->subjectAlternativeNames)) {
342 return false;
343 }
344 if (!GetMatchAllSubjectAltNames(env, arg, matchParams->matchAllSubjectAltNames)) {
345 return false;
346 }
347 if (!GetAuthorityKeyIdentifier(env, arg, matchParams->authorityKeyIdentifier)) {
348 return false;
349 }
350 if (!GetMinPathLenConstraint(env, arg, matchParams->minPathLenConstraint)) {
351 return false;
352 }
353 if (!GetExtendedKeyUsage(env, arg, matchParams->extendedKeyUsage)) {
354 return false;
355 }
356 if (!GetNameConstraints(env, arg, matchParams->nameConstraints)) {
357 return false;
358 }
359 if (!GetCertPolicy(env, arg, matchParams->certPolicy)) {
360 return false;
361 }
362 if (!GetPrivateKeyValid(env, arg, matchParams->privateKeyValid)) {
363 return false;
364 }
365 if (!GetSubjectKeyIdentifier(env, arg, matchParams->subjectKeyIdentifier)) {
366 return false;
367 }
368 return true;
369 }
370
BuildX509CertMatchParams(napi_env env,napi_value arg,HcfX509CertMatchParams * & matchParams)371 bool BuildX509CertMatchParams(napi_env env, napi_value arg, HcfX509CertMatchParams *&matchParams)
372 {
373 napi_valuetype type;
374 napi_typeof(env, arg, &type);
375 if (type != napi_object) {
376 LOGE("wrong argument type. expect object type. [Type]: %d", type);
377 return false;
378 }
379 if (!BuildX509CertMatchParamsV1(env, arg, matchParams)) {
380 return false;
381 }
382 if (!BuildX509CertMatchParamsV2(env, arg, matchParams)) {
383 return false;
384 }
385
386 return true;
387 }
388
FreeX509CertMatchParams(HcfX509CertMatchParams * & matchParams)389 void FreeX509CertMatchParams(HcfX509CertMatchParams *&matchParams)
390 {
391 if (matchParams == nullptr) {
392 return;
393 }
394
395 matchParams->x509Cert = nullptr;
396 CfBlobFree(&matchParams->validDate);
397 CfBlobFree(&matchParams->issuer);
398 CfBlobFree(&matchParams->keyUsage);
399 CfBlobFree(&matchParams->serialNumber);
400 CfBlobFree(&matchParams->subject);
401 CfBlobFree(&matchParams->publicKey);
402 CfBlobFree(&matchParams->publicKeyAlgID);
403 CfBlobFree(&matchParams->authorityKeyIdentifier);
404 CfBlobFree(&matchParams->nameConstraints);
405 CfBlobFree(&matchParams->privateKeyValid);
406 CfBlobFree(&matchParams->subjectKeyIdentifier);
407 CfArrayDataClearAndFree(matchParams->certPolicy);
408 CfArrayDataClearAndFree(matchParams->extendedKeyUsage);
409 CfFree(matchParams->certPolicy);
410 CfFree(matchParams->extendedKeyUsage);
411 if (matchParams->subjectAlternativeNames != nullptr) {
412 for (uint32_t i = 0; i < matchParams->subjectAlternativeNames->count; ++i) {
413 if (matchParams->subjectAlternativeNames->data != nullptr) {
414 CF_FREE_BLOB(matchParams->subjectAlternativeNames->data[i].name);
415 }
416 }
417 CfFree(matchParams->subjectAlternativeNames->data);
418 CfFree(matchParams->subjectAlternativeNames);
419 }
420
421 CF_FREE_PTR(matchParams);
422 }
423
424 } // namespace CertFramework
425 } // namespace OHOS
426