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 "x509crl_fuzzer.h"
17 #include <openssl/x509.h>
18 #include "asy_key_generator.h"
19 #include "cf_blob.h"
20 #include "cipher.h"
21 #include "key_pair.h"
22 #include "cf_memory.h"
23 #include "certificate_openssl_class.h"
24 #include "cf_result.h"
25 #include "securec.h"
26 #include "x509_certificate.h"
27 #include "x509_crl.h"
28 #include "x509_crl_entry.h"
29
30 namespace OHOS {
31 constexpr int TEST_VERSION = 3;
32 constexpr int TEST_OFFSET_TIME = 1000;
33 constexpr int TEST_SN = 1000;
34 constexpr int TEST_TIME = 1986598400;
35 constexpr int TEST_OFFSET = 10;
36 constexpr int TEST_CRL_LEN = 256;
37
38 HcfKeyPair *g_keyPair = nullptr;
39 ASN1_TIME *g_lastUpdate = nullptr;
40 ASN1_TIME *g_nextUpdate = nullptr;
41 ASN1_TIME *g_rvTime = nullptr;
42
43 static char g_testCrl[] =
44 "-----BEGIN X509 CRL-----\r\n"
45 "MIIB/DCB5QIBATANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCQ04xETAPBgNV\r\n"
46 "BAgMCHNoYW5naGFpMQ8wDQYDVQQHDAZodWF3ZWkxFTATBgNVBAoMDHd3dy50ZXN0\r\n"
47 "LmNvbTENMAsGA1UECwwEdGVzdDEVMBMGA1UEAwwMd3d3LnRlc3QuY29tMRwwGgYJ\r\n"
48 "KoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tFw0yMjA4MjkwNzAwMTRaFw0yMjA5Mjgw\r\n"
49 "NzAwMTRaMBQwEgIBARcNMjIwODI5MDY1OTUzWqAOMAwwCgYDVR0UBAMCAQAwDQYJ\r\n"
50 "KoZIhvcNAQELBQADggEBAHpfFhhUR59OAvOSuKDQUC5tKeLEuPbY8bYdmQVI8EFd\r\n"
51 "xDkZTXmT3CX1aDPYKVsG/jH9KPAmCV/ODKEGiJzclb3Z4am7tT+Wy4mpXypNS1od\r\n"
52 "wPDcQGsMrjT6iSp6JImiB0dDDSleBTBcYR/hhtFaiGSncyqJ0mhyaXPxIkNOO6nY\r\n"
53 "v+rcTEPQWavViDRyNDhnTbN868I3fzFVBcidF13CA0sCJ91ZvsE9h/YmPO2+e0YE\r\n"
54 "IUgzn37UOiLGObCVBY12QjGiuvVvCl7ncncsFEJuGfvONOqyFHjyxDHo5W0fqTn2\r\n"
55 "eCtiNcgUr9Kz2bwCmvEXhP7PuF4RMLq4vfzi0YjCG98=\r\n"
56 "-----END X509 CRL-----\r\n";
57
58 static char g_testCert[] =
59 "-----BEGIN CERTIFICATE-----\r\n"
60 "MIID/jCCAuagAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCQ04x\r\n"
61 "ETAPBgNVBAgMCHNoYW5naGFpMQ8wDQYDVQQHDAZodWF3ZWkxFTATBgNVBAoMDHd3\r\n"
62 "dy50ZXN0LmNvbTENMAsGA1UECwwEdGVzdDEVMBMGA1UEAwwMd3d3LnRlc3QuY29t\r\n"
63 "MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tMB4XDTIyMDgyOTA2NTUwM1oX\r\n"
64 "DTIzMDgyOTA2NTUwM1owezELMAkGA1UEBhMCQ04xETAPBgNVBAgMCHNoYW5naGFp\r\n"
65 "MRUwEwYDVQQKDAx3d3cudGVzdC5jb20xDTALBgNVBAsMBHRlc3QxFTATBgNVBAMM\r\n"
66 "DHd3dy50ZXN0LmNvbTEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTCCASIw\r\n"
67 "DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJmY9T4SzXXwKvfMvnvMWY7TqUJK\r\n"
68 "jnWf2Puv0YUQ2fdvyoKQ2LQXdtzoUL53j587oI+IXelOr7dg020zPyun0cmZHZ4y\r\n"
69 "l/qAcrWbDjZeEGcbbb5UtQtn1WOEnv8pkXluO355mbZQUKK9L3gFWseXJKGbIXw0\r\n"
70 "NRpaJZzqvPor4m3a5pmJKPHOlivUdYfLaKSkNj3DlaFzCWKV82k5ee6gzVyETtG+\r\n"
71 "XN+vq8qLybT+fIFsLNMmAHzRxlqz3NiH7yh+1/p/Knvf8bkkRVR2btH51RyX2RSu\r\n"
72 "DjPM0/VRL8fxDSDeWBq+Gvn/E6AbOVMmkx63tcyWHhklCSaZtyz7kq39TQMCAwEA\r\n"
73 "AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0\r\n"
74 "ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFFiFDysfADQCzRZCOSPupQxFicwzMB8G\r\n"
75 "A1UdIwQYMBaAFNYQRQiPsG8HefOTsmsVhaVjY7IPMA0GCSqGSIb3DQEBCwUAA4IB\r\n"
76 "AQAeppxf6sKQJxJQXKPTT3xHKaskidNwDBbOSIvnVvWXicZXDs+1sF6tUaRgvPxL\r\n"
77 "OL58+P2Jy0tfSwj2WhqQRGe9MvQ5iFHcdelZc0ciW6EQ0VDHIaDAQc2nQzej/79w\r\n"
78 "UE7BJJV3b9n1be2iCsuodKO14pOkMb84WcIxng+8SD+MiFqV5BPO1QyKGdO1PE1b\r\n"
79 "+evjyTpFSTgZf2Mw3fGtu5hfEXyHw1lnsFY2MlSwiRlAym/gm4aXy+4H6LyXKd56\r\n"
80 "UYQ6fituD0ziaw3RI6liyIe7aENHCkZf6bAvMRhk4QiU4xu6emwX8Qt1bT7RthP0\r\n"
81 "1Vsro0IOeXT9WAcqEtQUegsi\r\n"
82 "-----END CERTIFICATE-----\r\n";
83
FreeCrlData()84 static void FreeCrlData()
85 {
86 if (g_keyPair != nullptr) {
87 CfObjDestroy(g_keyPair);
88 g_keyPair = nullptr;
89 }
90 if (g_lastUpdate != nullptr) {
91 ASN1_TIME_free(g_lastUpdate);
92 g_lastUpdate = nullptr;
93 }
94 if (g_nextUpdate != nullptr) {
95 ASN1_TIME_free(g_nextUpdate);
96 g_nextUpdate = nullptr;
97 }
98 if (g_rvTime != nullptr) {
99 ASN1_TIME_free(g_rvTime);
100 g_rvTime = nullptr;
101 }
102 }
103
GetCrlStream()104 static unsigned char *GetCrlStream()
105 {
106 unsigned char *buf = nullptr;
107 unsigned char *p = nullptr;
108 HcfAsyKeyGenerator *generator = nullptr;
109 HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_3", &generator);
110 generator->generateKeyPair(generator, nullptr, &g_keyPair);
111 RSA *rsaPrikey = (reinterpret_cast<HcfOpensslRsaPriKey *>(g_keyPair->priKey))->sk;
112 EVP_PKEY *prikey = EVP_PKEY_new();
113 EVP_PKEY_assign_RSA(prikey, rsaPrikey);
114
115 X509_CRL *crl = X509_CRL_new();
116 (void)X509_CRL_set_version(crl, TEST_VERSION);
117
118 // Set Issuer
119 X509_NAME *issuer = X509_NAME_new();
120 const char *tmp = "CRL issuer";
121 (void)X509_NAME_add_entry_by_NID(issuer, NID_commonName, V_ASN1_PRINTABLESTRING,
122 reinterpret_cast<const unsigned char *>(tmp), 10, -1, 0);
123 (void)X509_CRL_set_issuer_name(crl, issuer);
124
125 g_lastUpdate = ASN1_TIME_new();
126 time_t t = time(nullptr);
127 ASN1_TIME_set(g_lastUpdate, t + TEST_OFFSET_TIME);
128 (void)X509_CRL_set_lastUpdate(crl, g_lastUpdate);
129
130 g_nextUpdate = ASN1_TIME_new();
131 t = TEST_TIME;
132 ASN1_TIME_set(g_nextUpdate, t);
133 (void)X509_CRL_set_nextUpdate(crl, g_nextUpdate);
134
135 X509_REVOKED *revoked = X509_REVOKED_new();
136 ASN1_INTEGER *serial = ASN1_INTEGER_new();
137 (void)ASN1_INTEGER_set(serial, TEST_SN);
138 (void)X509_REVOKED_set_serialNumber(revoked, serial);
139
140 g_rvTime = ASN1_TIME_new();
141 t = TEST_TIME;
142 ASN1_TIME_set(g_rvTime, t);
143 (void)X509_CRL_set_nextUpdate(crl, g_rvTime);
144 (void)X509_REVOKED_set_revocationDate(revoked, g_rvTime);
145 (void)X509_CRL_add0_revoked(crl, revoked);
146
147 (void)X509_CRL_sort(crl);
148 (void)X509_CRL_sign(crl, prikey, EVP_sha256());
149 int len = i2d_X509_CRL(crl, nullptr);
150 buf = reinterpret_cast<unsigned char *>(malloc(len + TEST_OFFSET));
151 p = buf;
152 (void)i2d_X509_CRL(crl, &p);
153 return buf;
154 }
155
TestX509CrlPem(HcfX509Crl * x509CrlPem)156 static void TestX509CrlPem(HcfX509Crl *x509CrlPem)
157 {
158 CfEncodingBlob encodingBlob = { 0 };
159 (void)x509CrlPem->getEncoded(x509CrlPem, &encodingBlob);
160 if (encodingBlob.data != nullptr) {
161 CfFree(encodingBlob.data);
162 }
163 CfBlob issuerName = { 0 };
164 (void)x509CrlPem->getIssuerName(x509CrlPem, &issuerName);
165 if (issuerName.data != nullptr) {
166 CfFree(issuerName.data);
167 }
168 CfBlob lastUpdate = { 0 };
169 (void)x509CrlPem->getLastUpdate(x509CrlPem, &lastUpdate);
170 if (lastUpdate.data != nullptr) {
171 CfFree(lastUpdate.data);
172 }
173 CfBlob nextUpdate = { 0 };
174 (void)x509CrlPem->getNextUpdate(x509CrlPem, &nextUpdate);
175 if (nextUpdate.data != nullptr) {
176 CfFree(nextUpdate.data);
177 }
178 (void)x509CrlPem->base.getType(&(x509CrlPem->base));
179 HcfX509Certificate *x509Cert = nullptr;
180 CfEncodingBlob inStreamCert = { 0 };
181 inStreamCert.data = reinterpret_cast<uint8_t *>(g_testCert);
182 inStreamCert.encodingFormat = CF_FORMAT_PEM;
183 inStreamCert.len = strlen(g_testCert) + 1;
184 CfResult result = HcfX509CertificateCreate(&inStreamCert, &x509Cert);
185 if (result != CF_SUCCESS) {
186 return;
187 }
188 HcfX509CrlEntry *crlEntry = nullptr;
189 x509CrlPem->getRevokedCertWithCert(x509CrlPem, x509Cert, &crlEntry);
190 if (crlEntry != nullptr) {
191 CfObjDestroy(crlEntry);
192 }
193 (void)x509CrlPem->base.isRevoked(&(x509CrlPem->base), &(x509Cert->base));
194 CfObjDestroy(x509Cert);
195 }
196
TestX509CrlEntry(HcfX509Crl * x509CrlDer,const uint8_t * data,size_t size)197 static void TestX509CrlEntry(HcfX509Crl *x509CrlDer, const uint8_t *data, size_t size)
198 {
199 long serialNumber = 1000;
200 HcfX509CrlEntry *entry = nullptr;
201 x509CrlDer->getRevokedCert(x509CrlDer, serialNumber, &entry);
202 if (entry != nullptr) {
203 CfEncodingBlob entryEncoded = { 0 };
204 entry->getEncoded(entry, &entryEncoded);
205 if (entryEncoded.data != nullptr) {
206 CfFree(entryEncoded.data);
207 }
208 CfBlob certIssuer = { 0 };
209 entry->getCertIssuer(entry, &certIssuer);
210 if (certIssuer.data != nullptr) {
211 CfFree(certIssuer.data);
212 }
213 CfBlob revocationDate = { 0 };
214 entry->getRevocationDate(entry, &revocationDate);
215 if (revocationDate.data != nullptr) {
216 CfFree(revocationDate.data);
217 }
218 CfBlob snBlob = { 0 };
219 entry->getSerialNumber(entry, &snBlob);
220 if (snBlob.data != nullptr) {
221 CfFree(snBlob.data);
222 }
223 CfObjDestroy(entry);
224 }
225 if (size >= sizeof(long)) {
226 entry = nullptr;
227 const long *serialNumberPtr = reinterpret_cast<const long *>(data);
228 x509CrlDer->getRevokedCert(x509CrlDer, *serialNumberPtr, &entry);
229 if (entry != nullptr) {
230 CfObjDestroy(entry);
231 }
232 }
233 }
234
TestX509CrlDer(HcfX509Crl * x509CrlDer)235 static void TestX509CrlDer(HcfX509Crl *x509CrlDer)
236 {
237 CfArray entrys = { 0 };
238 x509CrlDer->getRevokedCerts(x509CrlDer, &entrys);
239 if (entrys.data != nullptr) {
240 HcfX509CrlEntry *crlEntry = reinterpret_cast<HcfX509CrlEntry *>(entrys.data[0].data);
241 CfObjDestroy(crlEntry);
242 }
243
244 CfBlob signature = { 0 };
245 x509CrlDer->getSignature(x509CrlDer, &signature);
246 if (signature.data != nullptr) {
247 CfFree(signature.data);
248 }
249 CfBlob signatureAlgName = { 0 };
250 x509CrlDer->getSignatureAlgName(x509CrlDer, &signatureAlgName);
251 if (signatureAlgName.data != nullptr) {
252 CfFree(signatureAlgName.data);
253 }
254 CfBlob signatureAlgOid = { 0 };
255 x509CrlDer->getSignatureAlgOid(x509CrlDer, &signatureAlgOid);
256 if (signatureAlgOid.data != nullptr) {
257 CfFree(signatureAlgOid.data);
258 }
259 CfBlob signatureAlgParams = { 0 };
260 x509CrlDer->getSignatureAlgParams(x509CrlDer, &signatureAlgParams);
261 if (signatureAlgParams.data != nullptr) {
262 CfFree(signatureAlgParams.data);
263 }
264 CfBlob tbsInfo = { 0 };
265 x509CrlDer->getTbsInfo(x509CrlDer, &tbsInfo);
266 if (tbsInfo.data != nullptr) {
267 CfFree(tbsInfo.data);
268 }
269 (void)x509CrlDer->getVersion(x509CrlDer);
270 (void)x509CrlDer->verify(x509CrlDer, g_keyPair->pubKey);
271 }
272
FuzzDoX509CrlTest(const uint8_t * data,size_t size)273 bool FuzzDoX509CrlTest(const uint8_t* data, size_t size)
274 {
275 if ((data == nullptr) || (size < sizeof(long))) {
276 return false;
277 }
278 HcfX509Crl *x509CrlDer = nullptr;
279 CfEncodingBlob crlDerInStream = { 0 };
280 unsigned char *crlStream = GetCrlStream();
281 crlDerInStream.data = reinterpret_cast<uint8_t *>(crlStream);
282 crlDerInStream.encodingFormat = CF_FORMAT_DER;
283 crlDerInStream.len = TEST_CRL_LEN;
284 CfResult result = HcfX509CrlCreate(&crlDerInStream, &x509CrlDer);
285 CfFree(crlStream);
286 if (result != CF_SUCCESS) {
287 FreeCrlData();
288 return false;
289 }
290 CfEncodingBlob crlPemInStream = { 0 };
291 crlPemInStream.data = reinterpret_cast<uint8_t *>(g_testCrl);
292 crlPemInStream.encodingFormat = CF_FORMAT_PEM;
293 crlPemInStream.len = strlen(g_testCrl) + 1;
294 HcfX509Crl *x509CrlPem = nullptr;
295 result = HcfX509CrlCreate(&crlPemInStream, &x509CrlPem);
296 if (result != CF_SUCCESS) {
297 FreeCrlData();
298 CfObjDestroy(x509CrlDer);
299 return false;
300 }
301 TestX509CrlPem(x509CrlPem);
302 CfObjDestroy(x509CrlPem);
303
304 TestX509CrlEntry(x509CrlDer, data, size);
305 TestX509CrlDer(x509CrlDer);
306 FreeCrlData();
307 CfObjDestroy(x509CrlDer);
308
309 HcfX509Crl *x509Crl = nullptr;
310 CfEncodingBlob crlInStream = { 0 };
311 crlInStream.data = const_cast<uint8_t *>(data);
312 crlInStream.encodingFormat = CF_FORMAT_PEM;
313 crlInStream.len = size;
314 result = HcfX509CrlCreate(&crlInStream, &x509Crl);
315 if (result == CF_SUCCESS) {
316 CfObjDestroy(x509Crl);
317 }
318 return true;
319 }
320 }
321
322 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)323 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
324 {
325 /* Run your code on data */
326 OHOS::FuzzDoX509CrlTest(data, size);
327 return 0;
328 }
329