1 /*
2  * Copyright (c) 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 <cstring>
17 #include <map>
18 #include <securec.h>
19 #include <string>
20 #include <vector>
21 
22 #include "net_ssl.h"
23 #include "net_ssl_c.h"
24 #include "net_ssl_c_type.h"
25 #include "net_ssl_type.h"
26 #include "net_ssl_verify_cert.h"
27 #include "netstack_log.h"
28 #include "secure_char.h"
29 
30 namespace OHOS {
31 namespace NetStack {
32 namespace Ssl {
33 namespace {
34 
35 const uint8_t *g_baseFuzzData = nullptr;
36 size_t g_baseFuzzSize = 0;
37 size_t g_baseFuzzPos = 0;
38 [[maybe_unused]] constexpr size_t STR_LEN = 255;
39 } // namespace
GetData()40 template <class T> T GetData()
41 {
42     T object{};
43     size_t objectSize = sizeof(object);
44     if (g_baseFuzzData == nullptr || g_baseFuzzSize <= g_baseFuzzPos || objectSize > g_baseFuzzSize - g_baseFuzzPos) {
45         return object;
46     }
47     errno_t ret = memcpy_s(&object, objectSize, g_baseFuzzData + g_baseFuzzPos, objectSize);
48     if (ret != EOK) {
49         return object;
50     }
51     g_baseFuzzPos += objectSize;
52     return object;
53 }
54 
SetGlobalFuzzData(const uint8_t * data,size_t size)55 void SetGlobalFuzzData(const uint8_t *data, size_t size)
56 {
57     g_baseFuzzData = data;
58     g_baseFuzzSize = size;
59     g_baseFuzzPos = 0;
60 }
61 
GetStringFromData(int strlen)62 std::string GetStringFromData(int strlen)
63 {
64     if (strlen < 1) {
65         return "";
66     }
67 
68     char cstr[strlen];
69     cstr[strlen - 1] = '\0';
70     for (int i = 0; i < strlen - 1; i++) {
71         cstr[i] = GetData<char>();
72     }
73     std::string str(cstr);
74     return str;
75 }
76 
stringToUint8(const std::string & str)77 uint8_t *stringToUint8(const std::string &str)
78 {
79     uint8_t *data = new uint8_t[str.size() + 1];
80     for (size_t i = 0; i < str.size(); ++i) {
81         data[i] = static_cast<uint8_t>(str[i]);
82     }
83     data[str.size()] = '\0';
84     return data;
85 }
86 
SetNetStackVerifyCertificationTestOne(const uint8_t * data,size_t size)87 void SetNetStackVerifyCertificationTestOne(const uint8_t *data, size_t size)
88 {
89     if ((data == nullptr) || (size < 1)) {
90         return;
91     }
92     SetGlobalFuzzData(data, size);
93     std::string str = GetStringFromData(STR_LEN);
94     CertBlob certBlob;
95     certBlob.type = CERT_TYPE_PEM;
96     certBlob.size = str.size();
97     certBlob.data = stringToUint8(str);
98     NetStackVerifyCertification(&certBlob);
99     delete[] certBlob.data;
100     certBlob.data = nullptr;
101 }
102 
SetNetStackVerifyCertificationTestTwo(const uint8_t * data,size_t size)103 void SetNetStackVerifyCertificationTestTwo(const uint8_t *data, size_t size)
104 {
105     if ((data == nullptr) || (size < 1)) {
106         return;
107     }
108     SetGlobalFuzzData(data, size);
109     std::string str = GetStringFromData(STR_LEN);
110     CertBlob certBlob;
111     certBlob.type = CERT_TYPE_PEM;
112     certBlob.size = str.size();
113     certBlob.data = stringToUint8(str);
114     NetStackVerifyCertification(&certBlob, &certBlob);
115     delete[] certBlob.data;
116     certBlob.data = nullptr;
117 }
118 
SetVerifyCertTestOne(const uint8_t * data,size_t size)119 void SetVerifyCertTestOne(const uint8_t *data, size_t size)
120 {
121     if ((data == nullptr) || (size < 1)) {
122         return;
123     }
124     SetGlobalFuzzData(data, size);
125     std::string str = GetStringFromData(STR_LEN);
126     CertBlob certBlob;
127     certBlob.type = CERT_TYPE_PEM;
128     certBlob.size = str.size();
129     certBlob.data = stringToUint8(str);
130     VerifyCert(&certBlob);
131     delete[] certBlob.data;
132     certBlob.data = nullptr;
133 }
134 
SetVerifyCertTestTwo(const uint8_t * data,size_t size)135 void SetVerifyCertTestTwo(const uint8_t *data, size_t size)
136 {
137     if ((data == nullptr) || (size < 1)) {
138         return;
139     }
140     SetGlobalFuzzData(data, size);
141     std::string str = GetStringFromData(STR_LEN);
142     CertBlob certBlob;
143     certBlob.type = CERT_TYPE_PEM;
144     certBlob.size = str.size();
145     certBlob.data = stringToUint8(str);
146     VerifyCert(&certBlob, &certBlob);
147     delete[] certBlob.data;
148     certBlob.data = nullptr;
149 }
150 
SetFreeResourcesTest(const uint8_t * data,size_t size)151 void SetFreeResourcesTest(const uint8_t *data, size_t size)
152 {
153     if ((data == nullptr) || (size < 1)) {
154         return;
155     }
156     SetGlobalFuzzData(data, size);
157     std::string str = GetStringFromData(STR_LEN);
158     CertBlob certBlob;
159     certBlob.type = CERT_TYPE_PEM;
160     certBlob.size = str.size();
161     certBlob.data = stringToUint8(str);
162     X509 *cert = PemToX509(certBlob.data, certBlob.size);
163     X509_STORE *store = nullptr;
164     X509_STORE_CTX *ctx = nullptr;
165     FreeResources(&cert, &cert, &store, &ctx);
166     delete[] certBlob.data;
167     certBlob.data = nullptr;
168 }
169 
SetPemToX509Test(const uint8_t * data,size_t size)170 void SetPemToX509Test(const uint8_t *data, size_t size)
171 {
172     if ((data == nullptr) || (size < 1)) {
173         return;
174     }
175     SetGlobalFuzzData(data, size);
176     std::string str = GetStringFromData(STR_LEN);
177     CertBlob certBlob;
178     certBlob.type = CERT_TYPE_PEM;
179     certBlob.size = str.size();
180     certBlob.data = stringToUint8(str);
181     PemToX509(data, size);
182     delete[] certBlob.data;
183     certBlob.data = nullptr;
184 }
185 
SetDerToX509Test(const uint8_t * data,size_t size)186 void SetDerToX509Test(const uint8_t *data, size_t size)
187 {
188     if ((data == nullptr) || (size < 1)) {
189         return;
190     }
191     SetGlobalFuzzData(data, size);
192     std::string str = GetStringFromData(STR_LEN);
193     CertBlob certBlob;
194     certBlob.type = CERT_TYPE_PEM;
195     certBlob.size = str.size();
196     certBlob.data = stringToUint8(str);
197     DerToX509(data, size);
198     delete[] certBlob.data;
199     certBlob.data = nullptr;
200 }
201 
SetCertBlobToX509Test(const uint8_t * data,size_t size)202 void SetCertBlobToX509Test(const uint8_t *data, size_t size)
203 {
204     if ((data == nullptr) || (size < 1)) {
205         return;
206     }
207     SetGlobalFuzzData(data, size);
208     std::string str = GetStringFromData(STR_LEN);
209     CertBlob certBlob;
210     certBlob.type = CERT_TYPE_PEM;
211     certBlob.size = str.size();
212     certBlob.data = stringToUint8(str);
213     CertBlobToX509(&certBlob);
214     delete[] certBlob.data;
215     certBlob.data = nullptr;
216 }
217 
SetOHNetStackCertVerificationTest(const uint8_t * data,size_t size)218 void SetOHNetStackCertVerificationTest(const uint8_t *data, size_t size)
219 {
220     if ((data == nullptr) || (size < 1)) {
221         return;
222     }
223     SetGlobalFuzzData(data, size);
224     std::string str = GetStringFromData(STR_LEN);
225     CertBlob certBlob;
226     certBlob.type = CERT_TYPE_PEM;
227     certBlob.size = str.size();
228     certBlob.data = stringToUint8(str);
229     OH_NetStack_CertVerification((const struct NetStack_CertBlob *)&certBlob,
230                                  (const struct NetStack_CertBlob *)&certBlob);
231     delete[] certBlob.data;
232     certBlob.data = nullptr;
233 }
234 
235 } // namespace Ssl
236 } // namespace NetStack
237 } // namespace OHOS
238 
239 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)240 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
241 {
242     /* Run your code on data */
243     OHOS::NetStack::Ssl::SetNetStackVerifyCertificationTestOne(data, size);
244     OHOS::NetStack::Ssl::SetNetStackVerifyCertificationTestTwo(data, size);
245     OHOS::NetStack::Ssl::SetVerifyCertTestOne(data, size);
246     OHOS::NetStack::Ssl::SetVerifyCertTestTwo(data, size);
247     OHOS::NetStack::Ssl::SetFreeResourcesTest(data, size);
248     OHOS::NetStack::Ssl::SetPemToX509Test(data, size);
249     OHOS::NetStack::Ssl::SetDerToX509Test(data, size);
250     OHOS::NetStack::Ssl::SetCertBlobToX509Test(data, size);
251     OHOS::NetStack::Ssl::SetOHNetStackCertVerificationTest(data, size);
252     return 0;
253 }