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 "cfgetandcheck_fuzzer.h"
17 
18 #include <securec.h>
19 
20 #include "cf_api.h"
21 #include "cf_memory.h"
22 #include "cf_param.h"
23 #include "cf_result.h"
24 #include "cf_test_sdk_common.h"
25 #include "cf_test_data.h"
26 
27 using namespace CertframeworkSdkTest;
28 using namespace CertframeworkTestData;
29 
30 namespace OHOS {
31     constexpr size_t PARAMS_SIZE_TWO = 2;
32     constexpr size_t PARAMS_SIZE_THREE = 3;
33 
34     const static CfEncodingBlob g_cert[] = {
35         { const_cast<uint8_t *>(g_certData01), sizeof(g_certData01), CF_FORMAT_DER },
36     };
37 
38     const static CfEncodingBlob g_extensionBlob[] = {
39         { const_cast<uint8_t *>(g_extensionData03), sizeof(g_extensionData03), CF_FORMAT_DER },
40     };
41 
TestCommonfunc(const CfObject * object,uint32_t cnt,const CfParam * params,uint32_t functype)42     void TestCommonfunc(const CfObject *object, uint32_t cnt, const CfParam *params, uint32_t functype)
43     {
44         CfParamSet *inParamSet = nullptr;
45         CfParamSet *outParamSet = nullptr;
46         int32_t ret = TestConstructParamSetIn(params, cnt, &inParamSet);
47         if (ret != CF_SUCCESS) {
48             return;
49         }
50 
51         if (functype == CF_TAG_GET_TYPE) {
52             (void)object->get(object, inParamSet, &outParamSet);
53         } else {
54             (void)object->check(object, inParamSet, &outParamSet);
55         }
56 
57         CfFreeParamSet(&outParamSet);
58         CfFreeParamSet(&inParamSet);
59     }
60 
TestObjectTypeFunc1(const CfObject * object,uint8_t * data,size_t size)61     void TestObjectTypeFunc1(const CfObject *object, uint8_t* data, size_t size)
62     {
63         size_t offset = 0;
64 
65         if (size < (sizeof(CfParam) * PARAMS_SIZE_THREE)) {
66             return;
67         }
68 
69         CfParam params[PARAMS_SIZE_THREE];
70         for (int i = 0; i < PARAMS_SIZE_THREE; i++) {
71             params[i].tag = *reinterpret_cast<uint32_t *>(data + offset);
72             offset += sizeof(uint32_t);
73             params[i].int32Param = *reinterpret_cast<int32_t *>(data + offset);
74             offset += sizeof(int32_t);
75         }
76 
77         TestCommonfunc(object, PARAMS_SIZE_THREE, params, CF_TAG_GET_TYPE);
78         TestCommonfunc(object, PARAMS_SIZE_THREE, params, CF_TAG_CHECK_TYPE);
79     }
80 
TestObjectTypeFunc2(const CfObject * object,uint8_t * data,size_t size)81     void TestObjectTypeFunc2(const CfObject *object, uint8_t* data, size_t size)
82     {
83         if (size < (sizeof(CfParam) * PARAMS_SIZE_TWO)) {
84             return;
85         }
86 
87         CfParam params[] = {
88             { .tag = CF_TAG_GET_TYPE, .int32Param = CF_GET_TYPE_EXT_ITEM },
89             { .tag = CF_TAG_PARAM0_INT32, .int32Param = *reinterpret_cast<int32_t *>(data) },
90         };
91 
92         TestCommonfunc(object, sizeof(params) / sizeof(CfParam), params, CF_TAG_GET_TYPE);
93     }
94 
TestObjectTypeFunc3(const CfObject * object,uint8_t * data,size_t size)95     void TestObjectTypeFunc3(const CfObject *object, uint8_t* data, size_t size)
96     {
97         if (size < (sizeof(CfParam) * PARAMS_SIZE_TWO)) {
98             return;
99         }
100 
101         CfParam params[] = {
102             { .tag = CF_TAG_GET_TYPE, .int32Param = CF_GET_TYPE_EXT_OIDS },
103             { .tag = CF_TAG_PARAM0_INT32, .int32Param = *reinterpret_cast<int32_t *>(data) },
104         };
105 
106         TestCommonfunc(object, sizeof(params) / sizeof(CfParam), params, CF_TAG_GET_TYPE);
107     }
108 
TestObjectTypeFunc4(const CfObject * object,uint8_t * data,size_t size)109     void TestObjectTypeFunc4(const CfObject *object, uint8_t* data, size_t size)
110     {
111         if (size < (sizeof(CfParam) * PARAMS_SIZE_THREE)) {
112             return;
113         }
114 
115         CfBlob oid = { size - sizeof(uint32_t), reinterpret_cast<uint8_t *>(data + sizeof(uint32_t)) };
116 
117         CfParam params[] = {
118             { .tag = CF_TAG_GET_TYPE, .int32Param = CF_GET_TYPE_EXT_ENTRY },
119             { .tag = CF_TAG_PARAM0_INT32, .int32Param = *reinterpret_cast<int32_t *>(data) },
120             { .tag = CF_TAG_PARAM1_BUFFER, .blob = oid },
121         };
122 
123         TestCommonfunc(object, sizeof(params) / sizeof(CfParam), params, CF_TAG_GET_TYPE);
124     }
125 
TestObjectTypeFunc5(const CfObject * object,uint8_t * data,size_t size)126     void TestObjectTypeFunc5(const CfObject *object, uint8_t* data, size_t size)
127     {
128         if (size < (sizeof(CfParam) * PARAMS_SIZE_TWO)) {
129             return;
130         }
131 
132         CfParam params[] = {
133             { .tag = CF_TAG_GET_TYPE, .int32Param = CF_GET_TYPE_CERT_ITEM },
134             { .tag = CF_TAG_PARAM0_INT32, .int32Param = *reinterpret_cast<int32_t *>(data) },
135         };
136 
137         TestCommonfunc(object, sizeof(params) / sizeof(CfParam), params, CF_TAG_GET_TYPE);
138     }
139 
TestObjectTypeFunc6(const CfObject * object,uint8_t * data,size_t size)140     void TestObjectTypeFunc6(const CfObject *object, uint8_t* data, size_t size)
141     {
142         if (size < (sizeof(CfParam))) {
143             return;
144         }
145 
146         CfParam params[] = {
147             { .tag = CF_TAG_CHECK_TYPE, .int32Param = *reinterpret_cast<int32_t *>(data) },
148         };
149 
150         TestCommonfunc(object, sizeof(params) / sizeof(CfParam), params, CF_TAG_CHECK_TYPE);
151     }
152 
CfObjectFuzzTest(const uint8_t * data,size_t size,CfObjectType objType)153     bool CfObjectFuzzTest(const uint8_t* data, size_t size, CfObjectType objType)
154     {
155         uint8_t *tmpData = static_cast<uint8_t *>(CfMalloc(size, 0));
156         if (tmpData == nullptr) {
157             return false;
158         }
159         (void)memcpy_s(tmpData, size, data, size);
160 
161         CfObject *object = nullptr;
162         if (objType == CF_OBJ_TYPE_EXTENSION) {
163             int32_t ret = CfCreate(CF_OBJ_TYPE_EXTENSION, &g_extensionBlob[0], &object);
164             if (ret != CF_SUCCESS) {
165                 CfFree(tmpData);
166                 if (object != nullptr) {
167                     object->destroy(&object);
168                 }
169                 return false;
170             }
171         } else {
172             int32_t ret = CfCreate(CF_OBJ_TYPE_CERT, &g_cert[0], &object);
173             if (ret != CF_SUCCESS) {
174                 CfFree(tmpData);
175                 if (object != nullptr) {
176                     object->destroy(&object);
177                 }
178                 return false;
179             }
180         }
181         TestObjectTypeFunc1(object, tmpData, size);
182         TestObjectTypeFunc2(object, tmpData, size);
183         TestObjectTypeFunc3(object, tmpData, size);
184         TestObjectTypeFunc4(object, tmpData, size);
185         TestObjectTypeFunc5(object, tmpData, size);
186         TestObjectTypeFunc6(object, tmpData, size);
187 
188         if (object != nullptr) {
189             object->destroy(&object);
190         }
191         CfFree(tmpData);
192         return true;
193     }
194 }
195 
196 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)197 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
198 {
199     /* Run your code on data */
200     OHOS::CfObjectFuzzTest(data, size, CF_OBJ_TYPE_EXTENSION);
201     OHOS::CfObjectFuzzTest(data, size, CF_OBJ_TYPE_CERT);
202     return 0;
203 }
204