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 "x509certificate_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include "securec.h"
21
22 #include "blob.h"
23 #include "result.h"
24 #include "x509_certificate.h"
25
26 namespace OHOS {
27 static char g_fuzzCert[] =
28 "-----BEGIN CERTIFICATE-----\r\n"
29 "MIIEMjCCAxqgAwIBAgICARAwDQYJKoZIhvcNAQELBQAwdjELMAkGA1UEBhMCQ04x\r\n"
30 "CzAJBgNVBAgMAkJKMQswCQYDVQQHDAJCSjELMAkGA1UECgwCSEQxDDAKBgNVBAsM\r\n"
31 "A2RldjELMAkGA1UEAwwCY2ExJTAjBgkqhkiG9w0BCQEWFmNhQGNyeXB0b2ZyYW1l\r\n"
32 "d29yay5jb20wHhcNMjIwODE5MTI0OTA2WhcNMzIwODE2MTI0OTA2WjB2MQswCQYD\r\n"
33 "VQQGEwJDTjELMAkGA1UECAwCQkoxCzAJBgNVBAcMAkJKMQswCQYDVQQKDAJIRDEM\r\n"
34 "MAoGA1UECwwDZGV2MQswCQYDVQQDDAJjYTElMCMGCSqGSIb3DQEJARYWY2FAY3J5\r\n"
35 "cHRvZnJhbWV3b3JrLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\r\n"
36 "AJ8p0IWE7WwwbtATg+AbYQj33WNBBktU+/AVf+Tl1aAa4TOeW2/ZARc4sdwLVTxd\r\n"
37 "XCipFseuiGN30hwXrXFUHrcMf0w2sCkznJVZ/rQcfEO5Kb1vBz6DEEcgISYEhhqO\r\n"
38 "BfYBit5qfpq5R2+2R/Th/ybV+kBrUl+GssXbDAe6oZCy56lGphDvmHMUO7a13j+S\r\n"
39 "FmThMbI2yeyua1LagSoaBJfY1J+i7jWPmmEFR0dQ2p0EGjHTgQGhRo5VuwDHipNS\r\n"
40 "v0XP8OUA/PYbL/SBj1Fq4C3gtfvjeswUbzVaMoq/wCuy1qcXI80ZLe3whR24c0cX\r\n"
41 "YFO0uGi9egPp24fw7yYGqgECAwEAAaOByTCBxjAdBgNVHQ4EFgQUjKM7QmMBs01R\r\n"
42 "9uQttYN/GDkvt7UwHwYDVR0jBBgwFoAUjKM7QmMBs01R9uQttYN/GDkvt7UwEgYD\r\n"
43 "VR0TAQH/BAgwBgEB/wIBAjALBgNVHQ8EBAMCAQYwHQYDVR0lBBYwFAYIKwYBBQUH\r\n"
44 "AwEGCCsGAQUFBwMCMCEGA1UdEQQaMBiBFmNhQGNyeXB0b2ZyYW1ld29yay5jb20w\r\n"
45 "IQYDVR0SBBowGIEWY2FAY3J5cHRvZnJhbWV3b3JrLmNvbTANBgkqhkiG9w0BAQsF\r\n"
46 "AAOCAQEAh+4RE6cJ62/gLYssLkc7ESg7exKwZlmisHyBicuy/+XagOZ3cTbgQNXl\r\n"
47 "QoZKbw/ks/B/cInbQGYbpAm47Sudo+I/G9xj0X7gQB9wtSrbStOs6SjnLiYU0xFc\r\n"
48 "Fsc0j6k2SrlyiwRQcjS4POKiUS0Cm3F3DHGdj55PlBkXxudXCq2V3J3VwKf2bVjQ\r\n"
49 "bzz2+M/Q1m+P7FhB+JmeO8eemkqMQ0tFMU3EM441NpejC5iFVAGgownC8S0B+fxH\r\n"
50 "9dBJuHM6vpxEWw3ckZFDZQ1kd91YRgr7jY8fc0v/T0tzHWbOEVzklEIBWL1mompL\r\n"
51 "BCwe0/Gw+BO60bfi2MoJw8t2IcB1Qw==\r\n"
52 "-----END CERTIFICATE-----\r\n";
53
54 static bool g_testFlag = true;
55
TestGetEncoded(HcfX509Certificate * x509CertObj)56 static void TestGetEncoded(HcfX509Certificate *x509CertObj)
57 {
58 HcfEncodingBlob derBlob = { 0 };
59 HcfResult res = x509CertObj->base.getEncoded(&(x509CertObj->base), &derBlob);
60 if (res != HCF_SUCCESS) {
61 return;
62 }
63 free(derBlob.data);
64 }
65
TestVerify(HcfX509Certificate * x509CertObj)66 static void TestVerify(HcfX509Certificate *x509CertObj)
67 {
68 HcfPubKey *keyOut = nullptr;
69 HcfResult res = x509CertObj->base.getPublicKey(&(x509CertObj->base), &keyOut);
70 if (res != HCF_SUCCESS) {
71 return;
72 }
73 (void)x509CertObj->base.verify(&(x509CertObj->base), keyOut);
74 HcfObjDestroy(keyOut);
75 }
76
TestQuery(HcfX509Certificate * x509CertObj)77 static void TestQuery(HcfX509Certificate *x509CertObj)
78 {
79 long serialNumber = x509CertObj->getSerialNumber(x509CertObj);
80 if (serialNumber < 0) {
81 return;
82 }
83 HcfBlob issuerName = { 0 };
84 (void)x509CertObj->getIssuerName(x509CertObj, &issuerName);
85 HcfBlobDataClearAndFree(&issuerName);
86
87 HcfBlob subjectName = { 0 };
88 (void)x509CertObj->getSubjectName(x509CertObj, &subjectName);
89 HcfBlobDataClearAndFree(&subjectName);
90
91 HcfBlob notBeforeTime = { 0 };
92 (void)x509CertObj->getNotBeforeTime(x509CertObj, ¬BeforeTime);
93 HcfBlobDataClearAndFree(¬BeforeTime);
94
95 HcfBlob notAfterTime = { 0 };
96 (void)x509CertObj->getNotAfterTime(x509CertObj, ¬AfterTime);
97 HcfBlobDataClearAndFree(¬AfterTime);
98
99 HcfBlob sigOut = { 0 };
100 (void)x509CertObj->getSignature(x509CertObj, &sigOut);
101 HcfBlobDataClearAndFree(&sigOut);
102
103 HcfBlob sigAlgOid = { 0 };
104 (void)x509CertObj->getSignatureAlgOid(x509CertObj, &sigAlgOid);
105 HcfBlobDataClearAndFree(&sigAlgOid);
106
107 HcfBlob sigAlgParamsOut = { 0 };
108 (void)x509CertObj->getSignatureAlgParams(x509CertObj, &sigAlgParamsOut);
109 HcfBlobDataClearAndFree(&sigAlgParamsOut);
110
111 HcfArray keyUsageOut = { 0 };
112 (void)x509CertObj->getExtKeyUsage(x509CertObj, &keyUsageOut);
113 HcfArrayDataClearAndFree(&keyUsageOut);
114
115 int32_t pathLen = x509CertObj->getBasicConstraints(x509CertObj);
116 if (pathLen < 0) {
117 return;
118 }
119 HcfArray subjectAltName = { 0 };
120 (void)x509CertObj->getSubjectAltNames(x509CertObj, &subjectAltName);
121 HcfArrayDataClearAndFree(&subjectAltName);
122 }
123
CreateOneCert(void)124 static void CreateOneCert(void)
125 {
126 HcfEncodingBlob inStream = { 0 };
127 inStream.data = reinterpret_cast<uint8_t *>(g_fuzzCert);
128 inStream.encodingFormat = HCF_FORMAT_PEM;
129 inStream.len = strlen(g_fuzzCert) + 1;
130 HcfX509Certificate *x509CertObj = nullptr;
131 HcfResult res = HcfX509CertificateCreate(&inStream, &x509CertObj);
132 if (res != HCF_SUCCESS) {
133 return;
134 }
135 TestGetEncoded(x509CertObj);
136 TestVerify(x509CertObj);
137 TestQuery(x509CertObj);
138 }
139
X509CertificateFuzzTest(const uint8_t * data,size_t size)140 bool X509CertificateFuzzTest(const uint8_t* data, size_t size)
141 {
142 if (g_testFlag) {
143 CreateOneCert();
144 g_testFlag = false;
145 }
146 if (data == nullptr) {
147 return false;
148 }
149 HcfEncodingBlob inStream = { 0 };
150 inStream.data = const_cast<uint8_t *>(data);
151 inStream.encodingFormat = HCF_FORMAT_PEM;
152 inStream.len = size;
153 HcfX509Certificate *x509CertObj = nullptr;
154 HcfResult res = HcfX509CertificateCreate(&inStream, &x509CertObj);
155 if (res != HCF_SUCCESS) {
156 return false;
157 }
158 HcfObjDestroy(x509CertObj);
159 return true;
160 }
161 }
162
163 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)164 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
165 {
166 /* Run your code on data */
167 OHOS::X509CertificateFuzzTest(data, size);
168 return 0;
169 }
170