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 "user_auth_service_fuzzer.h"
17
18 #include <cinttypes>
19 #include <cstddef>
20 #include <cstdint>
21
22 #include "parcel.h"
23
24 #include "iam_fuzz_test.h"
25 #include "iam_logger.h"
26 #include "user_auth_service.h"
27
28 #undef private
29
30 #ifdef LOG_LABEL
31 #undef LOG_LABEL
32 #endif
33 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SA
34
35 using namespace std;
36 using namespace OHOS::UserIam::Common;
37 using namespace OHOS::UserIam::UserAuth;
38
39 namespace OHOS {
40 namespace UserIam {
41 namespace UserAuth {
42 namespace {
43 class DummyUserAuthCallback : public UserAuthCallbackInterface {
44 public:
45 ~DummyUserAuthCallback() override = default;
46
OnAcquireInfo(int32_t module,int32_t acquireInfo,const Attributes & extraInfo)47 void OnAcquireInfo(int32_t module, int32_t acquireInfo, const Attributes &extraInfo) override
48 {
49 IAM_LOGI("start");
50 static_cast<void>(module);
51 static_cast<void>(acquireInfo);
52 static_cast<void>(extraInfo);
53 return;
54 }
55
OnResult(int32_t result,const Attributes & extraInfo)56 void OnResult(int32_t result, const Attributes &extraInfo) override
57 {
58 IAM_LOGI("start");
59 static_cast<void>(result);
60 static_cast<void>(extraInfo);
61 return;
62 }
63
AsObject()64 sptr<IRemoteObject> AsObject() override
65 {
66 return nullptr;
67 }
68 };
69
70 class DummyGetExecutorPropertyCallback : public GetExecutorPropertyCallbackInterface {
71 public:
72 ~DummyGetExecutorPropertyCallback() override = default;
73
OnGetExecutorPropertyResult(int32_t result,const Attributes & attributes)74 void OnGetExecutorPropertyResult(int32_t result, const Attributes &attributes) override
75 {
76 IAM_LOGI("start");
77 return;
78 }
79
AsObject()80 sptr<IRemoteObject> AsObject() override
81 {
82 return nullptr;
83 }
84 };
85
86 class DummySetExecutorPropertyCallback : public SetExecutorPropertyCallbackInterface {
87 public:
88 ~DummySetExecutorPropertyCallback() override = default;
89
OnSetExecutorPropertyResult(int32_t result)90 void OnSetExecutorPropertyResult(int32_t result) override
91 {
92 IAM_LOGI("start");
93 return;
94 }
95
AsObject()96 sptr<IRemoteObject> AsObject() override
97 {
98 return nullptr;
99 }
100 };
101
102 UserAuthService g_userAuthService(SUBSYS_USERIAM_SYS_ABILITY_USERAUTH, true);
103
FuzzOnStart(Parcel & parcel)104 void FuzzOnStart(Parcel &parcel)
105 {
106 IAM_LOGI("begin");
107 g_userAuthService.OnStart();
108 IAM_LOGI("end");
109 }
110
FuzzOnStop(Parcel & parcel)111 void FuzzOnStop(Parcel &parcel)
112 {
113 IAM_LOGI("begin");
114 static int32_t skipCount = 1000;
115 // OnStop affects test of other function, skip it in the first phase
116 if (skipCount > 0) {
117 --skipCount;
118 return;
119 }
120 g_userAuthService.OnStop();
121 IAM_LOGI("end");
122 }
123
FuzzGetAvailableStatus(Parcel & parcel)124 void FuzzGetAvailableStatus(Parcel &parcel)
125 {
126 IAM_LOGI("begin");
127 int32_t apiVersion = parcel.ReadInt32();
128 AuthType authType = static_cast<AuthType>(parcel.ReadInt32());
129 AuthTrustLevel authTrustLevel = static_cast<AuthTrustLevel>(parcel.ReadInt32());
130 g_userAuthService.GetAvailableStatus(apiVersion, authType, authTrustLevel);
131 IAM_LOGI("end");
132 }
133
FuzzGetProperty(Parcel & parcel)134 void FuzzGetProperty(Parcel &parcel)
135 {
136 IAM_LOGI("begin");
137 constexpr uint32_t maxDataLen = 50;
138 int32_t userId = parcel.ReadInt32();
139 AuthType authType = static_cast<AuthType>(parcel.ReadInt32());
140 std::vector<Attributes::AttributeKey> keys;
141 uint32_t keysLen = parcel.ReadUint32() % maxDataLen;
142 keys.reserve(keysLen);
143 for (uint32_t i = 0; i < keysLen; i++) {
144 keys.emplace_back(static_cast<Attributes::AttributeKey>(parcel.ReadInt32()));
145 }
146
147 sptr<GetExecutorPropertyCallbackInterface> callback = nullptr;
148 if (parcel.ReadBool()) {
149 callback = new (nothrow) DummyGetExecutorPropertyCallback();
150 }
151 g_userAuthService.GetProperty(userId, authType, keys, callback);
152 IAM_LOGI("end");
153 }
154
FuzzSetProperty(Parcel & parcel)155 void FuzzSetProperty(Parcel &parcel)
156 {
157 IAM_LOGI("begin");
158 int32_t userId = parcel.ReadInt32();
159 AuthType authType = static_cast<AuthType>(parcel.ReadInt32());
160 vector<uint8_t> attributesRaw;
161 FillFuzzUint8Vector(parcel, attributesRaw);
162 Attributes attributes(attributesRaw);
163 sptr<SetExecutorPropertyCallbackInterface> callback = nullptr;
164 if (parcel.ReadBool()) {
165 callback = new (nothrow) DummySetExecutorPropertyCallback();
166 }
167
168 g_userAuthService.SetProperty(userId, authType, attributes, callback);
169 IAM_LOGI("end");
170 }
171
FuzzAuth(Parcel & parcel)172 void FuzzAuth(Parcel &parcel)
173 {
174 IAM_LOGI("begin");
175 int32_t apiVersion = parcel.ReadInt32();
176 std::vector<uint8_t> challenge;
177 FillFuzzUint8Vector(parcel, challenge);
178 AuthType authType = static_cast<AuthType>(parcel.ReadInt32());
179 AuthTrustLevel authTrustLevel = static_cast<AuthTrustLevel>(parcel.ReadInt32());
180 sptr<UserAuthCallbackInterface> callback = nullptr;
181 if (parcel.ReadBool()) {
182 callback = new (nothrow) DummyUserAuthCallback();
183 }
184 g_userAuthService.AuthUser(apiVersion, challenge, authType, authTrustLevel, callback);
185 IAM_LOGI("end");
186 }
187
FuzzAuthUser(Parcel & parcel)188 void FuzzAuthUser(Parcel &parcel)
189 {
190 IAM_LOGI("begin");
191 int32_t userId = parcel.ReadInt32();
192 std::vector<uint8_t> challenge;
193 FillFuzzUint8Vector(parcel, challenge);
194 AuthType authType = static_cast<AuthType>(parcel.ReadInt32());
195 AuthTrustLevel authTrustLevel = static_cast<AuthTrustLevel>(parcel.ReadInt32());
196 sptr<UserAuthCallbackInterface> callback = nullptr;
197 if (parcel.ReadBool()) {
198 callback = new (nothrow) DummyUserAuthCallback();
199 }
200 g_userAuthService.AuthUser(userId, challenge, authType, authTrustLevel, callback);
201 IAM_LOGI("end");
202 }
203
FuzzIdentify(Parcel & parcel)204 void FuzzIdentify(Parcel &parcel)
205 {
206 IAM_LOGI("begin");
207 std::vector<uint8_t> challenge;
208 FillFuzzUint8Vector(parcel, challenge);
209 AuthType authType = static_cast<AuthType>(parcel.ReadInt32());
210 sptr<UserAuthCallbackInterface> callback = nullptr;
211 if (parcel.ReadBool()) {
212 callback = new (nothrow) DummyUserAuthCallback();
213 }
214 g_userAuthService.Identify(challenge, authType, callback);
215 IAM_LOGI("end");
216 }
217
FuzzCancelAuthOrIdentify(Parcel & parcel)218 void FuzzCancelAuthOrIdentify(Parcel &parcel)
219 {
220 IAM_LOGI("begin");
221 uint64_t contextId = parcel.ReadUint64();
222 g_userAuthService.CancelAuthOrIdentify(contextId);
223 IAM_LOGI("end");
224 }
225
FuzzGetVersion(Parcel & parcel)226 void FuzzGetVersion(Parcel &parcel)
227 {
228 IAM_LOGI("begin");
229 int32_t version = -1;
230 g_userAuthService.GetVersion(version);
231 IAM_LOGI("end");
232 }
233
234 using FuzzFunc = decltype(FuzzOnStart);
235 FuzzFunc *g_fuzzFuncs[] = {
236 FuzzOnStart,
237 FuzzOnStop,
238 FuzzGetAvailableStatus,
239 FuzzGetProperty,
240 FuzzSetProperty,
241 FuzzAuth,
242 FuzzAuthUser,
243 FuzzIdentify,
244 FuzzCancelAuthOrIdentify,
245 FuzzGetVersion,
246 };
247
UserAuthFuzzTest(const uint8_t * data,size_t size)248 void UserAuthFuzzTest(const uint8_t *data, size_t size)
249 {
250 Parcel parcel;
251 parcel.WriteBuffer(data, size);
252 parcel.RewindRead(0);
253 uint32_t index = parcel.ReadUint32() % (sizeof(g_fuzzFuncs)) / sizeof(FuzzFunc *);
254 auto fuzzFunc = g_fuzzFuncs[index];
255 fuzzFunc(parcel);
256 return;
257 }
258 } // namespace
259 } // namespace UserAuth
260 } // namespace UserIam
261 } // namespace OHOS
262
263 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)264 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
265 {
266 OHOS::UserIam::UserAuth::UserAuthFuzzTest(data, size);
267 return 0;
268 }
269