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 <string>
17 #include "cf_log.h"
18 #include "cf_type.h"
19 #include "napi_cert_chain_validator.h"
20 #include "napi_cert_defines.h"
21 #include "napi_cert_extension.h"
22 #include "napi_cert_utils.h"
23 #include "napi_pub_key.h"
24 #include "napi_x509_cert_chain.h"
25 #include "napi_x509_certificate.h"
26 #include "napi_x509_crl.h"
27 #include "napi_x509_crl_entry.h"
28 #include "napi_cert_crl_collection.h"
29 #include "napi_x509_distinguished_name.h"
30 #include "securec.h"
31 
32 namespace OHOS {
33 namespace CertFramework {
CreateEncodingFormat(napi_env env)34 static napi_value CreateEncodingFormat(napi_env env)
35 {
36     napi_value encodingFormat = nullptr;
37     napi_create_object(env, &encodingFormat);
38 
39     CertAddUint32Property(env, encodingFormat, "FORMAT_DER", CF_FORMAT_DER);
40     CertAddUint32Property(env, encodingFormat, "FORMAT_PEM", CF_FORMAT_PEM);
41     CertAddUint32Property(env, encodingFormat, "FORMAT_PKCS7", CF_FORMAT_PKCS7);
42 
43     return encodingFormat;
44 }
45 
DefineEncodingFormatProperties(napi_env env,napi_value exports)46 static void DefineEncodingFormatProperties(napi_env env, napi_value exports)
47 {
48     napi_property_descriptor desc[] = {
49         DECLARE_NAPI_PROPERTY("EncodingFormat", CreateEncodingFormat(env)),
50     };
51     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
52 }
53 
CreateCertResultCode(napi_env env)54 static napi_value CreateCertResultCode(napi_env env)
55 {
56     napi_value resultCode = nullptr;
57     napi_create_object(env, &resultCode);
58 
59     CertAddUint32Property(env, resultCode, "INVALID_PARAMS", JS_ERR_CERT_INVALID_PARAMS);
60     CertAddUint32Property(env, resultCode, "NOT_SUPPORT", JS_ERR_CERT_NOT_SUPPORT);
61     CertAddUint32Property(env, resultCode, "ERR_OUT_OF_MEMORY", JS_ERR_CERT_OUT_OF_MEMORY);
62     CertAddUint32Property(env, resultCode, "ERR_RUNTIME_ERROR", JS_ERR_CERT_RUNTIME_ERROR);
63     CertAddUint32Property(env, resultCode, "ERR_CRYPTO_OPERATION", JS_ERR_CERT_CRYPTO_OPERATION);
64     CertAddUint32Property(env, resultCode, "ERR_CERT_SIGNATURE_FAILURE", JS_ERR_CERT_SIGNATURE_FAILURE);
65     CertAddUint32Property(env, resultCode, "ERR_CERT_NOT_YET_VALID", JS_ERR_CERT_NOT_YET_VALID);
66     CertAddUint32Property(env, resultCode, "ERR_CERT_HAS_EXPIRED", JS_ERR_CERT_HAS_EXPIRED);
67     CertAddUint32Property(env, resultCode, "ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
68         JS_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY);
69     CertAddUint32Property(env, resultCode, "ERR_KEYUSAGE_NO_CERTSIGN", JS_ERR_KEYUSAGE_NO_CERTSIGN);
70     CertAddUint32Property(env, resultCode, "ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE", JS_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE);
71 
72     return resultCode;
73 }
74 
DefineResultCodeProperties(napi_env env,napi_value exports)75 static void DefineResultCodeProperties(napi_env env, napi_value exports)
76 {
77     napi_property_descriptor desc[] = {
78         DECLARE_NAPI_PROPERTY("CertResult", CreateCertResultCode(env)),
79     };
80     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
81 }
82 
CreateCertItemType(napi_env env)83 static napi_value CreateCertItemType(napi_env env)
84 {
85     napi_value certItemType = nullptr;
86     napi_create_object(env, &certItemType);
87 
88     CertAddUint32Property(env, certItemType, "CERT_ITEM_TYPE_TBS", CF_ITEM_TBS);
89     CertAddUint32Property(env, certItemType, "CERT_ITEM_TYPE_PUBLIC_KEY", CF_ITEM_PUBLIC_KEY);
90     CertAddUint32Property(env, certItemType, "CERT_ITEM_TYPE_ISSUER_UNIQUE_ID", CF_ITEM_ISSUER_UNIQUE_ID);
91     CertAddUint32Property(env, certItemType, "CERT_ITEM_TYPE_SUBJECT_UNIQUE_ID", CF_ITEM_SUBJECT_UNIQUE_ID);
92     CertAddUint32Property(env, certItemType, "CERT_ITEM_TYPE_EXTENSIONS", CF_ITEM_EXTENSIONS);
93 
94     return certItemType;
95 }
96 
DefineCertItemTypeProperties(napi_env env,napi_value exports)97 static void DefineCertItemTypeProperties(napi_env env, napi_value exports)
98 {
99     napi_property_descriptor desc[] = {
100         DECLARE_NAPI_PROPERTY("CertItemType", CreateCertItemType(env)),
101     };
102     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
103 }
104 
CreateExtensionOidType(napi_env env)105 static napi_value CreateExtensionOidType(napi_env env)
106 {
107     napi_value extensionOidType = nullptr;
108     napi_create_object(env, &extensionOidType);
109 
110     CertAddUint32Property(env, extensionOidType, "EXTENSION_OID_TYPE_ALL", CF_EXT_TYPE_ALL_OIDS);
111     CertAddUint32Property(env, extensionOidType, "EXTENSION_OID_TYPE_CRITICAL", CF_EXT_TYPE_CRITICAL_OIDS);
112     CertAddUint32Property(env, extensionOidType, "EXTENSION_OID_TYPE_UNCRITICAL", CF_EXT_TYPE_UNCRITICAL_OIDS);
113 
114     return extensionOidType;
115 }
116 
DefineExtensionOidTypeProperties(napi_env env,napi_value exports)117 static void DefineExtensionOidTypeProperties(napi_env env, napi_value exports)
118 {
119     napi_property_descriptor desc[] = {
120         DECLARE_NAPI_PROPERTY("ExtensionOidType", CreateExtensionOidType(env)),
121     };
122     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
123 }
124 
CreateExtensionEntryType(napi_env env)125 static napi_value CreateExtensionEntryType(napi_env env)
126 {
127     napi_value extensionEntryType  = nullptr;
128     napi_create_object(env, &extensionEntryType);
129 
130     CertAddUint32Property(env, extensionEntryType, "EXTENSION_ENTRY_TYPE_ENTRY", CF_EXT_ENTRY_TYPE_ENTRY);
131     CertAddUint32Property(env, extensionEntryType, "EXTENSION_ENTRY_TYPE_ENTRY_CRITICAL",
132         CF_EXT_ENTRY_TYPE_ENTRY_CRITICAL);
133     CertAddUint32Property(env, extensionEntryType, "EXTENSION_ENTRY_TYPE_ENTRY_VALUE", CF_EXT_ENTRY_TYPE_ENTRY_VALUE);
134 
135     return extensionEntryType;
136 }
137 
DefineExtensionEntryTypeProperties(napi_env env,napi_value exports)138 static void DefineExtensionEntryTypeProperties(napi_env env, napi_value exports)
139 {
140     napi_property_descriptor desc[] = {
141         DECLARE_NAPI_PROPERTY("ExtensionEntryType", CreateExtensionEntryType(env)),
142     };
143     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
144 }
145 
CreateGeneralNameTypeType(napi_env env)146 static napi_value CreateGeneralNameTypeType(napi_env env)
147 {
148     napi_value generalNameType = nullptr;
149     napi_create_object(env, &generalNameType);
150 
151     CertAddUint32Property(env, generalNameType, "GENERAL_NAME_TYPE_OTHER_NAME", CF_GENERAL_NAME_TYPE_OTHER_NAME);
152     CertAddUint32Property(env, generalNameType, "GENERAL_NAME_TYPE_RFC822_NAME", CF_GENERAL_NAME_TYPE_RFC822_NAME);
153     CertAddUint32Property(env, generalNameType, "GENERAL_NAME_TYPE_DNS_NAME", CF_GENERAL_NAME_TYPE_DNS_NAME);
154     CertAddUint32Property(env, generalNameType, "GENERAL_NAME_TYPE_X400_ADDRESS", CF_GENERAL_NAME_TYPE_X400_ADDRESS);
155     CertAddUint32Property(
156         env, generalNameType, "GENERAL_NAME_TYPE_DIRECTORY_NAME", CF_GENERAL_NAME_TYPE_DIRECTORY_NAME);
157     CertAddUint32Property(
158         env, generalNameType, "GENERAL_NAME_TYPE_EDI_PARTY_NAME", CF_GENERAL_NAME_TYPE_EDI_PARTY_NAME);
159     CertAddUint32Property(
160         env, generalNameType, "GENERAL_NAME_TYPE_UNIFORM_RESOURCE_ID", CF_GENERAL_NAME_TYPE_UNIFORM_RESOURCE_ID);
161     CertAddUint32Property(env, generalNameType, "GENERAL_NAME_TYPE_IP_ADDRESS", CF_GENERAL_NAME_TYPE_IP_ADDRESS);
162     CertAddUint32Property(env, generalNameType, "GENERAL_NAME_TYPE_REGISTERED_ID", CF_GENERAL_NAME_TYPE_REGISTERED_ID);
163 
164     return generalNameType;
165 }
166 
DefineGeneralNameTypeProperties(napi_env env,napi_value exports)167 static void DefineGeneralNameTypeProperties(napi_env env, napi_value exports)
168 {
169     napi_property_descriptor desc[] = {
170         DECLARE_NAPI_PROPERTY("GeneralNameType", CreateGeneralNameTypeType(env)),
171     };
172     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
173 }
174 
CreateRevocationCheckOptions(napi_env env)175 static napi_value CreateRevocationCheckOptions(napi_env env)
176 {
177     napi_value revocationCheckOptions = nullptr;
178     napi_create_object(env, &revocationCheckOptions);
179 
180     CertAddUint32Property(
181         env, revocationCheckOptions, "REVOCATION_CHECK_OPTION_PREFER_OCSP", CF_REVOCATION_CHECK_OPTION_PREFER_OCSP);
182     CertAddUint32Property(env, revocationCheckOptions, "REVOCATION_CHECK_OPTION_ACCESS_NETWORK",
183         CF_REVOCATION_CHECK_OPTION_ACCESS_NETWORK);
184     CertAddUint32Property(env, revocationCheckOptions, "REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER",
185         CF_REVOCATION_CHECK_OPTION_FALLBACK_NO_PREFER);
186     CertAddUint32Property(env, revocationCheckOptions, "REVOCATION_CHECK_OPTION_FALLBACK_LOCAL",
187         CF_REVOCATION_CHECK_OPTION_FALLBACK_LOCAL);
188 
189     return revocationCheckOptions;
190 }
191 
CreateValidationPolicyType(napi_env env)192 static napi_value CreateValidationPolicyType(napi_env env)
193 {
194     napi_value ValidationPolicyType = nullptr;
195     napi_create_object(env, &ValidationPolicyType);
196 
197     CertAddUint32Property(env, ValidationPolicyType, "VALIDATION_POLICY_TYPE_X509", CF_VALIDATION_POLICY_TYPE_X509);
198     CertAddUint32Property(env, ValidationPolicyType, "VALIDATION_POLICY_TYPE_SSL", CF_VALIDATION_POLICY_TYPE_SSL);
199 
200     return ValidationPolicyType;
201 }
202 
CreateValidationKeyUsageType(napi_env env)203 static napi_value CreateValidationKeyUsageType(napi_env env)
204 {
205     napi_value ValidationKeyUsageType = nullptr;
206     napi_create_object(env, &ValidationKeyUsageType);
207 
208     CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_DIGITAL_SIGNATURE", CF_KEYUSAGE_DIGITAL_SIGNATURE);
209     CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_NON_REPUDIATION", CF_KEYUSAGE_NON_REPUDIATION);
210     CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_KEY_ENCIPHERMENT", CF_KEYUSAGE_KEY_ENCIPHERMENT);
211     CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_DATA_ENCIPHERMENT", CF_KEYUSAGE_DATA_ENCIPHERMENT);
212     CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_KEY_AGREEMENT", CF_KEYUSAGE_KEY_AGREEMENT);
213     CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_KEY_CERT_SIGN", CF_KEYUSAGE_KEY_CERT_SIGN);
214     CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_CRL_SIGN", CF_KEYUSAGE_CRL_SIGN);
215     CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_ENCIPHER_ONLY", CF_KEYUSAGE_ENCIPHER_ONLY);
216     CertAddUint32Property(env, ValidationKeyUsageType, "KEYUSAGE_DECIPHER_ONLY", CF_KEYUSAGE_DECIPHER_ONLY);
217 
218     return ValidationKeyUsageType;
219 }
220 
DefineOcspCheckOptionTypeProperties(napi_env env,napi_value exports)221 static void DefineOcspCheckOptionTypeProperties(napi_env env, napi_value exports)
222 {
223     napi_property_descriptor desc[] = {
224         DECLARE_NAPI_PROPERTY("RevocationCheckOptions", CreateRevocationCheckOptions(env)),
225     };
226     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
227 }
228 
DefineValidationPolicyTypeProperties(napi_env env,napi_value exports)229 static void DefineValidationPolicyTypeProperties(napi_env env, napi_value exports)
230 {
231     napi_property_descriptor desc[] = {
232         DECLARE_NAPI_PROPERTY("ValidationPolicyType", CreateValidationPolicyType(env)),
233     };
234     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
235 }
236 
DefineValidationKeyUsageTypeProperties(napi_env env,napi_value exports)237 static void DefineValidationKeyUsageTypeProperties(napi_env env, napi_value exports)
238 {
239     napi_property_descriptor desc[] = {
240         DECLARE_NAPI_PROPERTY("KeyUsageType", CreateValidationKeyUsageType(env)),
241     };
242     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
243 }
244 
CreateEncodingType(napi_env env)245 static napi_value CreateEncodingType(napi_env env)
246 {
247     napi_value encodingType = nullptr;
248     napi_create_object(env, &encodingType);
249 
250     CertAddUint32Property(env, encodingType, "ENCODING_UTF8", CF_ENCODING_UTF8);
251 
252     return encodingType;
253 }
254 
DefineEncodingTypeProperties(napi_env env,napi_value exports)255 static void DefineEncodingTypeProperties(napi_env env, napi_value exports)
256 {
257     napi_property_descriptor desc[] = {
258         DECLARE_NAPI_PROPERTY("EncodingType", CreateEncodingType(env)),
259     };
260     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
261 }
262 
263 /***********************************************
264  * Module export and register
265  ***********************************************/
CertModuleExport(napi_env env,napi_value exports)266 static napi_value CertModuleExport(napi_env env, napi_value exports)
267 {
268     DefineEncodingFormatProperties(env, exports);
269     DefineResultCodeProperties(env, exports);
270     DefineCertItemTypeProperties(env, exports);
271     DefineExtensionOidTypeProperties(env, exports);
272     DefineExtensionEntryTypeProperties(env, exports);
273     DefineGeneralNameTypeProperties(env, exports);
274     DefineOcspCheckOptionTypeProperties(env, exports);
275     DefineValidationPolicyTypeProperties(env, exports);
276     DefineValidationKeyUsageTypeProperties(env, exports);
277     DefineEncodingTypeProperties(env, exports);
278 
279     NapiKey::DefineHcfKeyJSClass(env);
280     NapiPubKey::DefinePubKeyJSClass(env);
281     NapiCertChainValidator::DefineCertChainValidatorJSClass(env, exports);
282     NapiX509Certificate::DefineX509CertJSClass(env, exports);
283     NapiX509CrlEntry::DefineX509CrlEntryJSClass(env, std::string("X509CrlEntry"));
284     NapiX509CrlEntry::DefineX509CrlEntryJSClass(env, std::string("X509CRLEntry"));
285     NapiX509Crl::DefineX509CrlJSClass(env, exports, std::string("X509Crl"));
286     NapiX509Crl::DefineX509CrlJSClass(env, exports, std::string("X509CRL"));
287     NapiX509DistinguishedName::DefineX509DistinguishedNameJSClass(env, exports);
288     NapiCertExtension::DefineCertExtensionJsClass(env, exports);
289     NapiX509CertChain::DefineX509CertChainJsClass(env, exports);
290     NapiX509CertChainBulidResult::DefineX509CertChainBuildResultJsClass(env, exports);
291     NapiCertCRLCollection::DefineCertCRLCollectionJSClass(env, exports);
292     return exports;
293 }
294 
RegisterCertModule(void)295 extern "C" __attribute__((constructor)) void RegisterCertModule(void)
296 {
297     static napi_module cryptoFrameworkCertModule = {
298         .nm_version = 1,
299         .nm_flags = 0,
300         .nm_filename = nullptr,
301         .nm_register_func = CertModuleExport,
302         .nm_modname = "security.cert",
303         .nm_priv = nullptr,
304         .reserved = { nullptr },
305     };
306     napi_module_register(&cryptoFrameworkCertModule);
307 }
308 }  // namespace CertFramework
309 }  // namespace OHOS
310