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 "cmappcert_fuzzer.h"
17 
18 #include "cm_fuzz_test_common.h"
19 #include "cm_test_common.h"
20 #include "cm_cert_data_part1_rsa.h"
21 #include "cm_ipc_client_serialization.h"
22 #include "cm_ipc_service.h"
23 #include "cm_param.h"
24 #include "cert_manager_api.h"
25 
26 using namespace CmFuzzTest;
27 namespace OHOS {
28     constexpr uint32_t MIN_DATA_USE_TIME = 4;
InstallAppCert(uint8_t * tmpData,uint32_t * remainSize,uint32_t * offset,uint32_t store,struct CmBlob * keyUri)29     static bool InstallAppCert(uint8_t *tmpData, uint32_t *remainSize, uint32_t *offset, uint32_t store,
30         struct CmBlob *keyUri)
31     {
32         uint8_t certAliasBuf[] = "keyA";
33         struct CmBlob certAlias = { sizeof(certAliasBuf), certAliasBuf };
34         if (TenPercentChanceOfBeingTrue(tmpData, remainSize, offset)) {
35             if (!GetCmBlobFromBuffer(tmpData, remainSize, offset, keyUri)) {
36                 return false;
37             }
38         }
39 
40         const struct CmBlob appCert = { sizeof(g_rsa2048P12CertInfo), const_cast<uint8_t *>(g_rsa2048P12CertInfo) };
41         const struct CmBlob appCertPwd = { sizeof(g_certPwd), const_cast<uint8_t *>(g_certPwd) };
42         struct CmParam params01[] = {
43             { .tag = CM_TAG_PARAM0_BUFFER, .blob = appCert },
44             { .tag = CM_TAG_PARAM1_BUFFER, .blob = appCertPwd },
45             { .tag = CM_TAG_PARAM2_BUFFER, .blob = certAlias },
46             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
47             { .tag = CM_TAG_PARAM1_UINT32, .uint32Param = TEST_USERID },
48         };
49         struct CmParamSet *paramSet01 = NULL;
50         int32_t ret = CmParamsToParamSet(params01, CM_ARRAY_SIZE(params01), &paramSet01);
51         if (ret != CM_SUCCESS) {
52             return false;
53         }
54         struct CmBlob paramSetBlob = { paramSet01->paramSetSize, reinterpret_cast<uint8_t *>(paramSet01) };
55 
56         (void)CmIpcServiceInstallAppCert(&paramSetBlob, keyUri, nullptr);
57         CmFreeParamSet(&paramSet01);
58         return true;
59     }
60 
GetAllAppCert(uint8_t * tmpData,uint32_t * remainSize,uint32_t * offset,uint32_t store)61     static bool GetAllAppCert(uint8_t *tmpData, uint32_t *remainSize, uint32_t *offset, uint32_t store)
62     {
63         struct CmParam params02[] = { { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store } };
64         struct CmParamSet *paramSet02 = NULL;
65         int32_t ret = CmParamsToParamSet(params02, CM_ARRAY_SIZE(params02), &paramSet02);
66         if (ret != CM_SUCCESS) {
67             return false;
68         }
69         struct CmBlob paramSetBlob = { paramSet02->paramSetSize, reinterpret_cast<uint8_t *>(paramSet02) };
70 
71         (void)CmIpcServiceGetAppCertList(&paramSetBlob, nullptr, nullptr);
72         CmFreeParamSet(&paramSet02);
73         return true;
74     }
75 
GetAppCert(uint8_t * tmpData,uint32_t * remainSize,uint32_t * offset,uint32_t store,struct CmBlob * keyUri)76     static bool GetAppCert(uint8_t *tmpData, uint32_t *remainSize, uint32_t *offset, uint32_t store,
77         struct CmBlob *keyUri)
78     {
79         if (TenPercentChanceOfBeingTrue(tmpData, remainSize, offset)) {
80             if (!GetCmBlobFromBuffer(tmpData, remainSize, offset, keyUri)) {
81                 return false;
82             }
83         }
84 
85         struct CmParam params03[] = {
86             { .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri },
87             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
88         };
89         struct CmParamSet *paramSet03 = NULL;
90         int32_t ret = CmParamsToParamSet(params03, CM_ARRAY_SIZE(params03), &paramSet03);
91         if (ret != CM_SUCCESS) {
92             return false;
93         }
94         struct CmBlob paramSetBlob = { paramSet03->paramSetSize, reinterpret_cast<uint8_t *>(paramSet03) };
95 
96         (void)CmIpcServiceGetAppCert(&paramSetBlob, nullptr, nullptr);
97         CmFreeParamSet(&paramSet03);
98         return true;
99     }
100 
UnInstallAppCert(uint8_t * tmpData,uint32_t * remainSize,uint32_t * offset,uint32_t store,struct CmBlob * keyUri)101     static bool UnInstallAppCert(uint8_t *tmpData, uint32_t *remainSize, uint32_t *offset, uint32_t store,
102         struct CmBlob *keyUri)
103     {
104         if (TenPercentChanceOfBeingTrue(tmpData, remainSize, offset)) {
105             if (!GetCmBlobFromBuffer(tmpData, remainSize, offset, keyUri)) {
106                 return false;
107             }
108         }
109 
110         struct CmParam params04[] = {
111             { .tag = CM_TAG_PARAM0_BUFFER, .blob = *keyUri },
112             { .tag = CM_TAG_PARAM0_UINT32, .uint32Param = store },
113         };
114         struct CmParamSet *paramSet04 = NULL;
115         int32_t ret = CmParamsToParamSet(params04, CM_ARRAY_SIZE(params04), &paramSet04);
116         if (ret != CM_SUCCESS) {
117             return false;
118         }
119         struct CmBlob paramSetBlob = { paramSet04->paramSetSize, reinterpret_cast<uint8_t *>(paramSet04) };
120 
121         (void)CmIpcServiceUninstallAppCert(&paramSetBlob, nullptr, nullptr);
122         CmFreeParamSet(&paramSet04);
123         return true;
124     }
125 
DoSomethingInterestingWithMyAPI(const uint8_t * data,size_t size)126     bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
127     {
128         uint8_t *tmpData = nullptr;
129         if (!CopyMyData(data, size, sizeof(uint32_t) * MIN_DATA_USE_TIME, &tmpData)) {
130             return false;
131         }
132 
133         uint32_t remainSize = static_cast<uint32_t>(size);
134         uint32_t offset = 0;
135         CertmanagerTest::SetATPermission();
136 
137         uint32_t store;
138         if (!GetUintFromBuffer(tmpData, &remainSize, &offset, &store)) {
139             CmFree(tmpData);
140             return false;
141         }
142         store %= CM_SYS_CREDENTIAL_STORE + 1;
143         bool ret = false;
144         uint8_t uriBuf[MAX_LEN_URI] = {0};
145         struct CmBlob keyUri = { sizeof(uriBuf), uriBuf };
146 
147         do {
148             if (!InstallAppCert(tmpData, &remainSize, &offset, store, &keyUri)) {
149                 break;
150             }
151 
152             if (!GetAllAppCert(tmpData, &remainSize, &offset, store)) {
153                 break;
154             }
155 
156             if (!GetAppCert(tmpData, &remainSize, &offset, store, &keyUri)) {
157                 break;
158             }
159 
160             if (!UnInstallAppCert(tmpData, &remainSize, &offset, store, &keyUri)) {
161                 break;
162             }
163             ret = true;
164         } while (0);
165         (void)CmIpcServiceUninstallAllAppCert(nullptr, nullptr, nullptr);
166         CmFree(tmpData);
167         return ret;
168     }
169 }
170 
171 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)172 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
173 {
174     /* Run your code on data */
175     OHOS::DoSomethingInterestingWithMyAPI(data, size);
176     return 0;
177 }
178 
179