• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 "blob.h"
20 #include "cipher.h"
21 #include "key_pair.h"
22 #include "memory.h"
23 #include "openssl_class.h"
24 #include "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             HcfObjDestroy(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, *p;
107         HcfAsyKeyGenerator *generator = nullptr;
108         HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_3", &generator);
109         generator->generateKeyPair(generator, nullptr, &g_keyPair);
110         RSA *rsaPrikey = (reinterpret_cast<HcfOpensslRsaPriKey *>(g_keyPair->priKey))->sk;
111         EVP_PKEY *prikey = EVP_PKEY_new();
112         EVP_PKEY_assign_RSA(prikey, rsaPrikey);
113 
114         X509_CRL *crl = X509_CRL_new();
115         (void)X509_CRL_set_version(crl, TEST_VERSION);
116 
117         // Set Issuer
118         X509_NAME *issuer = X509_NAME_new();
119         const char *tmp = "CRL issuer";
120         (void)X509_NAME_add_entry_by_NID(issuer, NID_commonName, V_ASN1_PRINTABLESTRING,
121             reinterpret_cast<const unsigned char *>(tmp), 10, -1, 0);
122         (void)X509_CRL_set_issuer_name(crl, issuer);
123 
124         g_lastUpdate = ASN1_TIME_new();
125         time_t t = time(nullptr);
126         ASN1_TIME_set(g_lastUpdate, t + TEST_OFFSET_TIME);
127         (void)X509_CRL_set_lastUpdate(crl, g_lastUpdate);
128 
129         g_nextUpdate = ASN1_TIME_new();
130         t = TEST_TIME;
131         ASN1_TIME_set(g_nextUpdate, t);
132         (void)X509_CRL_set_nextUpdate(crl, g_nextUpdate);
133 
134         X509_REVOKED *revoked = X509_REVOKED_new();
135         ASN1_INTEGER *serial = ASN1_INTEGER_new();
136         (void)ASN1_INTEGER_set(serial, TEST_SN);
137         (void)X509_REVOKED_set_serialNumber(revoked, serial);
138 
139         g_rvTime = ASN1_TIME_new();
140         t = TEST_TIME;
141         ASN1_TIME_set(g_rvTime, t);
142         (void)X509_CRL_set_nextUpdate(crl, g_rvTime);
143         (void)X509_REVOKED_set_revocationDate(revoked, g_rvTime);
144         (void)X509_CRL_add0_revoked(crl, revoked);
145 
146         (void)X509_CRL_sort(crl);
147         (void)X509_CRL_sign(crl, prikey, EVP_md5());
148         int len = i2d_X509_CRL(crl, nullptr);
149         buf = reinterpret_cast<unsigned char *>(malloc(len + TEST_OFFSET));
150         p = buf;
151         (void)i2d_X509_CRL(crl, &p);
152         return buf;
153     }
154 
TestX509CrlPem(HcfX509Crl * x509CrlPem)155     static void TestX509CrlPem(HcfX509Crl *x509CrlPem)
156     {
157         HcfEncodingBlob encodingBlob = { 0 };
158         (void)x509CrlPem->getEncoded(x509CrlPem, &encodingBlob);
159         if (encodingBlob.data != nullptr) {
160             HcfFree(encodingBlob.data);
161         }
162         HcfBlob issuerName = { 0 };
163         (void)x509CrlPem->getIssuerName(x509CrlPem, &issuerName);
164         if (issuerName.data != nullptr) {
165             HcfFree(issuerName.data);
166         }
167         HcfBlob lastUpdate = { 0 };
168         (void)x509CrlPem->getLastUpdate(x509CrlPem, &lastUpdate);
169         if (lastUpdate.data != nullptr) {
170             HcfFree(lastUpdate.data);
171         }
172         HcfBlob nextUpdate = { 0 };
173         (void)x509CrlPem->getNextUpdate(x509CrlPem, &nextUpdate);
174         if (nextUpdate.data != nullptr) {
175             HcfFree(nextUpdate.data);
176         }
177         (void)x509CrlPem->base.getType(&(x509CrlPem->base));
178         HcfX509Certificate *x509Cert = nullptr;
179         HcfEncodingBlob inStreamCert = { 0 };
180         inStreamCert.data = reinterpret_cast<uint8_t *>(g_testCert);
181         inStreamCert.encodingFormat = HCF_FORMAT_PEM;
182         inStreamCert.len = strlen(g_testCert) + 1;
183         HcfResult result = HcfX509CertificateCreate(&inStreamCert, &x509Cert);
184         if (result != HCF_SUCCESS) {
185             return;
186         }
187         HcfX509CrlEntry *crlEntry = nullptr;
188         x509CrlPem->getRevokedCertWithCert(x509CrlPem, x509Cert, &crlEntry);
189         if (crlEntry != nullptr) {
190             HcfObjDestroy(crlEntry);
191         }
192         (void)x509CrlPem->base.isRevoked(&(x509CrlPem->base), &(x509Cert->base));
193         HcfObjDestroy(x509Cert);
194     }
195 
TestX509CrlEntry(HcfX509Crl * x509CrlDer,const uint8_t * data,size_t size)196     static void TestX509CrlEntry(HcfX509Crl *x509CrlDer, const uint8_t *data, size_t size)
197     {
198         long serialNumber = 1000;
199         HcfX509CrlEntry *entry = nullptr;
200         x509CrlDer->getRevokedCert(x509CrlDer, serialNumber, &entry);
201         if (entry != nullptr) {
202             HcfEncodingBlob entryEncoded = { 0 };
203             entry->getEncoded(entry, &entryEncoded);
204             if (entryEncoded.data != nullptr) {
205                 HcfFree(entryEncoded.data);
206             }
207             HcfBlob certIssuer = { 0 };
208             entry->getCertIssuer(entry, &certIssuer);
209             if (certIssuer.data != nullptr) {
210                 HcfFree(certIssuer.data);
211             }
212             HcfBlob revocationDate = { 0 };
213             entry->getRevocationDate(entry, &revocationDate);
214             if (revocationDate.data != nullptr) {
215                 HcfFree(revocationDate.data);
216             }
217             entry->getSerialNumber(entry);
218             HcfObjDestroy(entry);
219         }
220         if (size >= sizeof(long)) {
221             entry = nullptr;
222             const long *serialNumberPtr = reinterpret_cast<const long *>(data);
223             x509CrlDer->getRevokedCert(x509CrlDer, *serialNumberPtr, &entry);
224             if (entry != nullptr) {
225                 HcfObjDestroy(entry);
226             }
227         }
228     }
229 
TestX509CrlDer(HcfX509Crl * x509CrlDer)230     static void TestX509CrlDer(HcfX509Crl *x509CrlDer)
231     {
232         HcfArray entrys = { 0 };
233         x509CrlDer->getRevokedCerts(x509CrlDer, &entrys);
234         if (entrys.data != nullptr) {
235             HcfX509CrlEntry *crlEntry = reinterpret_cast<HcfX509CrlEntry *>(entrys.data[0].data);
236             HcfObjDestroy(crlEntry);
237         }
238 
239         HcfBlob signature = { 0 };
240         x509CrlDer->getSignature(x509CrlDer, &signature);
241         if (signature.data != nullptr) {
242             HcfFree(signature.data);
243         }
244         HcfBlob signatureAlgName = { 0 };
245         x509CrlDer->getSignatureAlgName(x509CrlDer, &signatureAlgName);
246         if (signatureAlgName.data != nullptr) {
247             HcfFree(signatureAlgName.data);
248         }
249         HcfBlob signatureAlgOid = { 0 };
250         x509CrlDer->getSignatureAlgOid(x509CrlDer, &signatureAlgOid);
251         if (signatureAlgOid.data != nullptr) {
252             HcfFree(signatureAlgOid.data);
253         }
254         HcfBlob signatureAlgParams = { 0 };
255         x509CrlDer->getSignatureAlgParams(x509CrlDer, &signatureAlgParams);
256         if (signatureAlgParams.data != nullptr) {
257             HcfFree(signatureAlgParams.data);
258         }
259         HcfBlob tbsInfo = { 0 };
260         x509CrlDer->getTbsInfo(x509CrlDer, &tbsInfo);
261         if (tbsInfo.data != nullptr) {
262             HcfFree(tbsInfo.data);
263         }
264         (void)x509CrlDer->getVersion(x509CrlDer);
265         (void)x509CrlDer->verify(x509CrlDer, g_keyPair->pubKey);
266     }
267 
FuzzDoX509CrlTest(const uint8_t * data,size_t size)268     bool FuzzDoX509CrlTest(const uint8_t* data, size_t size)
269     {
270         if ((data == nullptr) || (size < sizeof(long))) {
271             return false;
272         }
273         HcfX509Crl *x509CrlDer = nullptr;
274         HcfEncodingBlob crlDerInStream = { 0 };
275         unsigned char *crlStream = GetCrlStream();
276         crlDerInStream.data = reinterpret_cast<uint8_t *>(crlStream);
277         crlDerInStream.encodingFormat = HCF_FORMAT_DER;
278         crlDerInStream.len = TEST_CRL_LEN;
279         HcfResult result = HcfX509CrlCreate(&crlDerInStream, &x509CrlDer);
280         HcfFree(crlStream);
281         if (result != HCF_SUCCESS) {
282             FreeCrlData();
283             return false;
284         }
285         HcfEncodingBlob crlPemInStream = { 0 };
286         crlPemInStream.data = reinterpret_cast<uint8_t *>(g_testCrl);
287         crlPemInStream.encodingFormat = HCF_FORMAT_PEM;
288         crlPemInStream.len = strlen(g_testCrl) + 1;
289         HcfX509Crl *x509CrlPem = nullptr;
290         result = HcfX509CrlCreate(&crlPemInStream, &x509CrlPem);
291         if (result != HCF_SUCCESS) {
292             FreeCrlData();
293             HcfObjDestroy(x509CrlDer);
294             return false;
295         }
296         TestX509CrlPem(x509CrlPem);
297         HcfObjDestroy(x509CrlPem);
298 
299         TestX509CrlEntry(x509CrlDer, data, size);
300         TestX509CrlDer(x509CrlDer);
301         FreeCrlData();
302         HcfObjDestroy(x509CrlDer);
303 
304         HcfX509Crl *x509Crl = nullptr;
305         HcfEncodingBlob crlInStream = { 0 };
306         crlInStream.data = const_cast<uint8_t *>(data);
307         crlInStream.encodingFormat = HCF_FORMAT_PEM;
308         crlInStream.len = size;
309         result = HcfX509CrlCreate(&crlInStream, &x509Crl);
310         if (result == HCF_SUCCESS) {
311             HcfObjDestroy(x509Crl);
312         }
313         return true;
314     }
315 }
316 
317 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)318 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
319 {
320     /* Run your code on data */
321     OHOS::FuzzDoX509CrlTest(data, size);
322     return 0;
323 }
324