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 }