• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
18 #include <openssl/x509.h>
19 
20 #include "asy_key_generator.h"
21 #include "certificate_openssl_class.h"
22 #include "cf_blob.h"
23 #include "cf_memory.h"
24 #include "cf_result.h"
25 #include "cipher.h"
26 #include "key_pair.h"
27 #include "securec.h"
28 #include "x509_certificate.h"
29 #include "x509_crl.h"
30 #include "x509_crl_entry.h"
31 
32 namespace OHOS {
33     constexpr int TEST_VERSION = 3;
34     constexpr int TEST_OFFSET_TIME = 1000;
35     constexpr int TEST_SN = 1000;
36     constexpr int TEST_TIME = 1986598400;
37     constexpr int TEST_OFFSET = 10;
38     constexpr int TEST_CRL_LEN = 256;
39 
40     HcfKeyPair *g_keyPair = nullptr;
41     ASN1_TIME *g_lastUpdate = nullptr;
42     ASN1_TIME *g_nextUpdate = nullptr;
43     ASN1_TIME *g_rvTime = nullptr;
44 
45     static char g_testCrl[] =
46     "-----BEGIN X509 CRL-----\r\n"
47     "MIIB4zCBzAIBATANBgkqhkiG9w0BAQsFADAsMQswCQYDVQQGEwJDTjENMAsGA1UE\r\n"
48     "CgwEdGVzdDEOMAwGA1UEAwwFc3ViY2EXDTIzMDkxMjA2NDc1MFoXDTIzMTAxMjA2\r\n"
49     "NDc1MFowOzATAgID6BcNMjMwOTEyMDY0NzQ5WjAkAhMXXWqf7KkJ1xKySFKmPkj2\r\n"
50     "EpOpFw0yMzA5MTIwNjQyNTRaoC8wLTAfBgNVHSMEGDAWgBQiKxjehNkwTvY939f0\r\n"
51     "Au1EIoQg6DAKBgNVHRQEAwIBAjANBgkqhkiG9w0BAQsFAAOCAQEAQKGCXs5aXY56\r\n"
52     "06A/0HynLmq+frJ7p5Uj9cD2vwbZV4xaP2E5jXogBz7YCjmxp0PB995XC9oi3QKQ\r\n"
53     "gLVKY4Nz21WQRecmmZm1cDweDDPwGJ8/I0d2CwMTJfP7rEgsuhgIBq+JUjFcNNaW\r\n"
54     "dia2Gu/aAuIjlaJ5A4W7vvhGVUx9CDUdN8YF5knA3BoQ1uFc1z7gNckkIpTTccQL\r\n"
55     "zoELFDG8/z+bOnAuSg1lZCyv9fOz9lVafC+qaHo+NW9rdChxV1oC5S6jHTu879CO\r\n"
56     "MQnLr3jEBCszNzDjFI64l6f3JVnLZepp6NU1gdunjQL4gtWQXZFlFV75xR8aahd8\r\n"
57     "seB5oDTPQg==\r\n"
58     "-----END X509 CRL-----\r\n";
59 
60     static char g_testCert[] =
61     "-----BEGIN CERTIFICATE-----\r\n"
62     "MIIDTzCCAjegAwIBAgICA+gwDQYJKoZIhvcNAQELBQAwLDELMAkGA1UEBhMCQ04x\r\n"
63     "DTALBgNVBAoMBHRlc3QxDjAMBgNVBAMMBXN1YmNhMB4XDTIzMDkxMjA2NDc0OVoX\r\n"
64     "DTMzMDkwOTA2NDc0OVowLDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBHRlc3QxDjAM\r\n"
65     "BgNVBAMMBWxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuEcw\r\n"
66     "tv/K2MnMB+AX2oL2KsTMjKteaQncpr6BPfe/LvSXQImnETvzSSIX2Iy19ZEbEDxn\r\n"
67     "osFXGvmrE8iT1P8lP+LYC8WIjzArbQeBvM6n8gq7QW2jAlfAmVy2/SBeBhRFT1Eq\r\n"
68     "rwqld6qqGa0WTnRTnax7v52FddvpG9XBAexE2gQ6UyScWikAKuDgnSQsivz6SMTQ\r\n"
69     "vbax3ffiy2p2RjxH9ZrQTxpUFDRHqMxJvq57wBDLkAtG4TlhQMDIB86cbOQfHHam\r\n"
70     "VHPVSvyZgmr3V4kb9UlDwB9bjrjSMlRsnNqocGEepZQ57IKgLf5SCWRec5Oww+OO\r\n"
71     "3WJOa7ja10sZ0LDdxwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQf\r\n"
72     "Fh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQURsHdrG4w\r\n"
73     "i4GQKaFbmEpdNyNkvB4wHwYDVR0jBBgwFoAUIisY3oTZME72Pd/X9ALtRCKEIOgw\r\n"
74     "DQYJKoZIhvcNAQELBQADggEBAKVdgTE4Q8Nl5nQUQVL/uZMVCmDRcpXdJHq3cyAH\r\n"
75     "4BtbFW/K3MbVcZl2j1tPl6bgI5pn9Tk4kkc+SfxGUKAPR7FQ01zfgEJipSlsmAxS\r\n"
76     "wOZL+PGUbYUL1jzU8207PZOIZcyD67Sj8LeOV4BCNLiBIo++MjpD++x77GnP3veg\r\n"
77     "bDKHfDSVILdH/qnqyGSAGJ4YGJld00tehnTAqBWzmkXVIgWk0bnPTNE0dn5Tj7ZY\r\n"
78     "7zh6YU5JILHnrkjRGdNGmpz8SXJ+bh7u8ffHc4R9FO1q4c9/1YSsOXQj0KazyDIP\r\n"
79     "IArlydFj8wK8sHvYC9WhPs+hiirrRb9Y2ApFzcYX5aYn46Y=\r\n"
80     "-----END CERTIFICATE-----\r\n";
81 
FreeCrlData()82     static void FreeCrlData()
83     {
84         if (g_keyPair != nullptr) {
85             CfObjDestroy(g_keyPair);
86             g_keyPair = nullptr;
87         }
88         if (g_lastUpdate != nullptr) {
89             ASN1_TIME_free(g_lastUpdate);
90             g_lastUpdate = nullptr;
91         }
92         if (g_nextUpdate != nullptr) {
93             ASN1_TIME_free(g_nextUpdate);
94             g_nextUpdate = nullptr;
95         }
96         if (g_rvTime != nullptr) {
97             ASN1_TIME_free(g_rvTime);
98             g_rvTime = nullptr;
99         }
100     }
101 
GetCrlStream()102     static unsigned char *GetCrlStream()
103     {
104         unsigned char *buf = nullptr;
105         unsigned char *p = nullptr;
106         HcfAsyKeyGenerator *generator = nullptr;
107         HcfAsyKeyGeneratorCreate("RSA1024|PRIMES_3", &generator);
108         generator->generateKeyPair(generator, nullptr, &g_keyPair);
109         RSA *rsaPrikey = (reinterpret_cast<HcfOpensslRsaPriKey *>(g_keyPair->priKey))->sk;
110         EVP_PKEY *prikey = EVP_PKEY_new();
111         EVP_PKEY_assign_RSA(prikey, rsaPrikey);
112 
113         X509_CRL *crl = X509_CRL_new();
114         (void)X509_CRL_set_version(crl, TEST_VERSION);
115 
116         // Set Issuer
117         X509_NAME *issuer = X509_NAME_new();
118         const char *tmp = "CRL issuer";
119         (void)X509_NAME_add_entry_by_NID(issuer, NID_commonName, V_ASN1_PRINTABLESTRING,
120             reinterpret_cast<const unsigned char *>(tmp), 10, -1, 0);
121         (void)X509_CRL_set_issuer_name(crl, issuer);
122 
123         g_lastUpdate = ASN1_TIME_new();
124         time_t t = time(nullptr);
125         ASN1_TIME_set(g_lastUpdate, t + TEST_OFFSET_TIME);
126         (void)X509_CRL_set_lastUpdate(crl, g_lastUpdate);
127 
128         g_nextUpdate = ASN1_TIME_new();
129         t = TEST_TIME;
130         ASN1_TIME_set(g_nextUpdate, t);
131         (void)X509_CRL_set_nextUpdate(crl, g_nextUpdate);
132 
133         X509_REVOKED *revoked = X509_REVOKED_new();
134         ASN1_INTEGER *serial = ASN1_INTEGER_new();
135         (void)ASN1_INTEGER_set(serial, TEST_SN);
136         (void)X509_REVOKED_set_serialNumber(revoked, serial);
137 
138         g_rvTime = ASN1_TIME_new();
139         t = TEST_TIME;
140         ASN1_TIME_set(g_rvTime, t);
141         (void)X509_CRL_set_nextUpdate(crl, g_rvTime);
142         (void)X509_REVOKED_set_revocationDate(revoked, g_rvTime);
143         (void)X509_CRL_add0_revoked(crl, revoked);
144 
145         (void)X509_CRL_sort(crl);
146         (void)X509_CRL_sign(crl, prikey, EVP_sha256());
147         int len = i2d_X509_CRL(crl, nullptr);
148         buf = reinterpret_cast<unsigned char *>(malloc(len + TEST_OFFSET));
149         p = buf;
150         (void)i2d_X509_CRL(crl, &p);
151         return buf;
152     }
153 
TestX509CrlPem(HcfX509Crl * x509CrlPem)154     static void TestX509CrlPem(HcfX509Crl *x509CrlPem)
155     {
156         CfEncodingBlob encodingBlob = { 0 };
157         (void)x509CrlPem->getEncoded(x509CrlPem, &encodingBlob);
158         if (encodingBlob.data != nullptr) {
159             CfFree(encodingBlob.data);
160         }
161         CfBlob issuerName = { 0 };
162         (void)x509CrlPem->getIssuerName(x509CrlPem, &issuerName);
163         if (issuerName.data != nullptr) {
164             CfFree(issuerName.data);
165         }
166         CfBlob lastUpdate = { 0 };
167         (void)x509CrlPem->getLastUpdate(x509CrlPem, &lastUpdate);
168         if (lastUpdate.data != nullptr) {
169             CfFree(lastUpdate.data);
170         }
171         CfBlob nextUpdate = { 0 };
172         (void)x509CrlPem->getNextUpdate(x509CrlPem, &nextUpdate);
173         if (nextUpdate.data != nullptr) {
174             CfFree(nextUpdate.data);
175         }
176         (void)x509CrlPem->base.getType(&(x509CrlPem->base));
177         HcfX509Certificate *x509Cert = nullptr;
178         CfEncodingBlob inStreamCert = { 0 };
179         inStreamCert.data = reinterpret_cast<uint8_t *>(g_testCert);
180         inStreamCert.encodingFormat = CF_FORMAT_PEM;
181         inStreamCert.len = strlen(g_testCert) + 1;
182         CfResult result = HcfX509CertificateCreate(&inStreamCert, &x509Cert);
183         if (result != CF_SUCCESS) {
184             return;
185         }
186         HcfX509CrlEntry *crlEntry = nullptr;
187         x509CrlPem->getRevokedCertWithCert(x509CrlPem, x509Cert, &crlEntry);
188         if (crlEntry != nullptr) {
189             CfObjDestroy(crlEntry);
190         }
191         (void)x509CrlPem->base.isRevoked(&(x509CrlPem->base), &(x509Cert->base));
192         CfObjDestroy(x509Cert);
193     }
194 
TestX509CrlEntry(HcfX509Crl * x509CrlDer,const uint8_t * data,size_t size)195     static void TestX509CrlEntry(HcfX509Crl *x509CrlDer, const uint8_t *data, size_t size)
196     {
197         long serialNumber = 1000;
198 		CfBlob serialBlob = { sizeof(long), reinterpret_cast<uint8_t *>(&serialNumber) };
199         HcfX509CrlEntry *entry = nullptr;
200         x509CrlDer->getRevokedCert(x509CrlDer, &serialBlob, &entry);
201         if (entry != nullptr) {
202             CfEncodingBlob entryEncoded = { 0 };
203             entry->getEncoded(entry, &entryEncoded);
204             if (entryEncoded.data != nullptr) {
205                 CfFree(entryEncoded.data);
206             }
207             CfBlob certIssuer = { 0 };
208             entry->getCertIssuer(entry, &certIssuer);
209             if (certIssuer.data != nullptr) {
210                 CfFree(certIssuer.data);
211             }
212             CfBlob revocationDate = { 0 };
213             entry->getRevocationDate(entry, &revocationDate);
214             if (revocationDate.data != nullptr) {
215                 CfFree(revocationDate.data);
216             }
217             CfBlob snBlob = { 0 };
218             entry->getSerialNumber(entry, &snBlob);
219             if (snBlob.data != nullptr) {
220                 CfFree(snBlob.data);
221             }
222             CfObjDestroy(entry);
223         }
224         if (size >= sizeof(long)) {
225             entry = nullptr;
226             serialBlob.size = sizeof(long);
227             serialBlob.data = const_cast<uint8_t *>(data);
228             x509CrlDer->getRevokedCert(x509CrlDer, &serialBlob, &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