1 /*
2 * Copyright (c) 2022-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 "pin_auth_all_in_one_hdi.h"
17
18 #include <map>
19
20 #include "hdf_base.h"
21
22 #include "iam_check.h"
23 #include "iam_defines.h"
24 #include "iam_logger.h"
25 #include "pin_auth_executor_callback_hdi.h"
26 #include "pin_auth_executor_hdi_common.h"
27
28 #define LOG_TAG "PIN_AUTH_SA"
29
30 namespace OHOS {
31 namespace UserIam {
32 namespace PinAuth {
PinAuthAllInOneHdi(const sptr<IAllInOneExecutor> & allInOneProxy)33 PinAuthAllInOneHdi::PinAuthAllInOneHdi(const sptr<IAllInOneExecutor> &allInOneProxy)
34 : allInOneProxy_(allInOneProxy)
35 {
36 }
37
GetExecutorInfo(UserAuth::ExecutorInfo & info)38 UserAuth::ResultCode PinAuthAllInOneHdi::GetExecutorInfo(UserAuth::ExecutorInfo &info)
39 {
40 if (allInOneProxy_ == nullptr) {
41 IAM_LOGE("allInOneProxy is null");
42 return UserAuth::ResultCode::GENERAL_ERROR;
43 }
44
45 ExecutorInfo localInfo = { };
46 int32_t status = allInOneProxy_->GetExecutorInfo(localInfo);
47 UserAuth::ResultCode result = ConvertHdiResultCode(status);
48 if (result != UserAuth::ResultCode::SUCCESS) {
49 IAM_LOGE("GetExecutorInfo fail ret=%{public}d", result);
50 return result;
51 }
52 SetAuthType(localInfo.authType);
53 int32_t ret = MoveHdiExecutorInfo(localInfo, info);
54 if (ret != UserAuth::ResultCode::SUCCESS) {
55 IAM_LOGE("MoveHdiExecutorInfo fail ret=%{public}d", ret);
56 return UserAuth::ResultCode::GENERAL_ERROR;
57 }
58 return UserAuth::ResultCode::SUCCESS;
59 }
60
OnRegisterFinish(const std::vector<uint64_t> & templateIdList,const std::vector<uint8_t> & frameworkPublicKey,const std::vector<uint8_t> & extraInfo)61 UserAuth::ResultCode PinAuthAllInOneHdi::OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
62 const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
63 {
64 if (allInOneProxy_ == nullptr) {
65 IAM_LOGE("allInOneProxy is null");
66 return UserAuth::ResultCode::GENERAL_ERROR;
67 }
68 int32_t status = allInOneProxy_->OnRegisterFinish(templateIdList, frameworkPublicKey, extraInfo);
69 UserAuth::ResultCode result = ConvertHdiResultCode(status);
70 if (result != UserAuth::ResultCode::SUCCESS) {
71 IAM_LOGE("OnRegisterFinish fail result %{public}d", result);
72 return result;
73 }
74
75 return UserAuth::ResultCode::SUCCESS;
76 }
77
SendMessage(uint64_t scheduleId,int32_t srcRole,const std::vector<uint8_t> & msg)78 UserAuth::ResultCode PinAuthAllInOneHdi::SendMessage(
79 uint64_t scheduleId, int32_t srcRole, const std::vector<uint8_t> &msg)
80 {
81 if (allInOneProxy_ == nullptr) {
82 IAM_LOGE("allInOneProxy is null");
83 return UserAuth::ResultCode::GENERAL_ERROR;
84 }
85 int32_t status = allInOneProxy_->SendMessage(scheduleId, srcRole, msg);
86 UserAuth::ResultCode result = ConvertHdiResultCode(status);
87 if (result != UserAuth::ResultCode::SUCCESS) {
88 IAM_LOGE("SendMessage fail result %{public}d", result);
89 return result;
90 }
91 return UserAuth::ResultCode::SUCCESS;
92 }
93
OnSetData(uint64_t scheduleId,uint64_t authSubType,const std::vector<uint8_t> & data,int32_t errorCode)94 UserAuth::ResultCode PinAuthAllInOneHdi::OnSetData(uint64_t scheduleId, uint64_t authSubType,
95 const std::vector<uint8_t> &data, int32_t errorCode)
96 {
97 if (allInOneProxy_ == nullptr) {
98 IAM_LOGE("allInOneProxy is null");
99 return UserAuth::ResultCode::GENERAL_ERROR;
100 }
101 int32_t status = allInOneProxy_->SetData(scheduleId, authSubType, data, errorCode);
102 UserAuth::ResultCode result = ConvertHdiResultCode(status);
103 if (result != UserAuth::ResultCode::SUCCESS) {
104 IAM_LOGE("OnSetData fail ret=%{public}d", result);
105 return result;
106 }
107 return UserAuth::ResultCode::SUCCESS;
108 }
109
Enroll(uint64_t scheduleId,const UserAuth::EnrollParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)110 UserAuth::ResultCode PinAuthAllInOneHdi::Enroll(uint64_t scheduleId, const UserAuth::EnrollParam ¶m,
111 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
112 {
113 if (allInOneProxy_ == nullptr) {
114 IAM_LOGE("allInOneProxy is null");
115 return UserAuth::ResultCode::GENERAL_ERROR;
116 }
117 if (callbackObj == nullptr) {
118 IAM_LOGE("callbackObj is null");
119 return UserAuth::ResultCode::GENERAL_ERROR;
120 }
121 if (!GetAuthType().has_value()) {
122 IAM_LOGE("authType is error");
123 return UserAuth::ResultCode::GENERAL_ERROR;
124 }
125 GetDataMode mode = GET_DATA_MODE_NONE;
126 if (GetAuthType().value() == AuthType::PIN) {
127 mode = GET_DATA_MODE_ALL_IN_ONE_PIN_ENROLL;
128 } else {
129 mode = GET_DATA_MODE_ALL_IN_ONE_PRIVATE_PIN_ENROLL;
130 }
131 UserAuth::ExecutorParam executorParam = {
132 .tokenId = param.tokenId,
133 .scheduleId = scheduleId,
134 .userId = param.userId,
135 };
136 auto callback = sptr<IExecutorCallback>(new (std::nothrow) PinAuthExecutorCallbackHdi(callbackObj,
137 shared_from_this(), executorParam, mode));
138 if (callback == nullptr) {
139 IAM_LOGE("callback is null");
140 return UserAuth::ResultCode::GENERAL_ERROR;
141 }
142 int32_t status = allInOneProxy_->Enroll(scheduleId, param.extraInfo, callback);
143 UserAuth::ResultCode result = ConvertHdiResultCode(status);
144 if (result != UserAuth::ResultCode::SUCCESS) {
145 IAM_LOGE("Enroll fail ret=%{public}d", result);
146 return result;
147 }
148 return UserAuth::ResultCode::SUCCESS;
149 }
150
Authenticate(uint64_t scheduleId,const UserAuth::AuthenticateParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)151 UserAuth::ResultCode PinAuthAllInOneHdi::Authenticate(
152 uint64_t scheduleId, const UserAuth::AuthenticateParam ¶m,
153 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
154 {
155 if (allInOneProxy_ == nullptr) {
156 IAM_LOGE("allInOneProxy is null");
157 return UserAuth::ResultCode::GENERAL_ERROR;
158 }
159 if (callbackObj == nullptr) {
160 IAM_LOGE("callbackObj is null");
161 return UserAuth::ResultCode::GENERAL_ERROR;
162 }
163 if (!GetAuthType().has_value()) {
164 IAM_LOGE("authType is error");
165 return UserAuth::ResultCode::GENERAL_ERROR;
166 }
167 GetDataMode mode = GET_DATA_MODE_NONE;
168 if (GetAuthType().value() == AuthType::PIN) {
169 mode = GET_DATA_MODE_ALL_IN_ONE_PIN_AUTH;
170 } else {
171 mode = GET_DATA_MODE_ALL_IN_ONE_PRIVATE_PIN_AUTH;
172 }
173 UserAuth::ExecutorParam executorParam = {
174 .tokenId = param.tokenId,
175 .authIntent = param.authIntent,
176 .scheduleId = scheduleId,
177 .userId = param.userId,
178 };
179 auto callback = sptr<IExecutorCallback>(new (std::nothrow) PinAuthExecutorCallbackHdi(callbackObj,
180 shared_from_this(), executorParam, mode));
181 if (callback == nullptr) {
182 IAM_LOGE("callback is null");
183 return UserAuth::ResultCode::GENERAL_ERROR;
184 }
185 if (param.templateIdList.size() == 0) {
186 IAM_LOGE("Error param");
187 return UserAuth::ResultCode::GENERAL_ERROR;
188 }
189 int32_t status = allInOneProxy_->Authenticate(scheduleId, param.templateIdList,
190 param.extraInfo, callback);
191 UserAuth::ResultCode result = ConvertHdiResultCode(status);
192 if (result != UserAuth::ResultCode::SUCCESS) {
193 IAM_LOGE("Authenticate fail ret=%{public}d", result);
194 return result;
195 }
196 return UserAuth::ResultCode::SUCCESS;
197 }
198
Delete(const std::vector<uint64_t> & templateIdList)199 UserAuth::ResultCode PinAuthAllInOneHdi::Delete(const std::vector<uint64_t> &templateIdList)
200 {
201 if (allInOneProxy_ == nullptr) {
202 IAM_LOGE("allInOneProxy is null");
203 return UserAuth::ResultCode::GENERAL_ERROR;
204 }
205 if (templateIdList.empty()) {
206 IAM_LOGE("templateIdList is empty");
207 return UserAuth::ResultCode::GENERAL_ERROR;
208 }
209 int32_t status = allInOneProxy_->Delete(templateIdList[0]);
210 UserAuth::ResultCode result = ConvertHdiResultCode(status);
211 if (result != UserAuth::ResultCode::SUCCESS) {
212 IAM_LOGE("Delete fail ret=%{public}d", result);
213 return result;
214 }
215 return UserAuth::ResultCode::SUCCESS;
216 }
217
Cancel(uint64_t scheduleId)218 UserAuth::ResultCode PinAuthAllInOneHdi::Cancel(uint64_t scheduleId)
219 {
220 if (allInOneProxy_ == nullptr) {
221 IAM_LOGE("allInOneProxy is null");
222 return UserAuth::ResultCode::GENERAL_ERROR;
223 }
224 int32_t status = allInOneProxy_->Cancel(scheduleId);
225 UserAuth::ResultCode result = ConvertHdiResultCode(status);
226 if (result != UserAuth::ResultCode::SUCCESS) {
227 IAM_LOGE("Cancel fail ret=%{public}d", result);
228 return result;
229 }
230 return UserAuth::ResultCode::SUCCESS;
231 }
232
GetProperty(const std::vector<uint64_t> & templateIdList,const std::vector<UserAuth::Attributes::AttributeKey> & keys,UserAuth::Property & property)233 UserAuth::ResultCode PinAuthAllInOneHdi::GetProperty(const std::vector<uint64_t> &templateIdList,
234 const std::vector<UserAuth::Attributes::AttributeKey> &keys, UserAuth::Property &property)
235 {
236 IF_FALSE_LOGE_AND_RETURN_VAL(allInOneProxy_ != nullptr, UserAuth::ResultCode::GENERAL_ERROR);
237
238 std::vector<int32_t> propertyTypes;
239 UserAuth::ResultCode result = ConvertAttributeKeyVectorToPropertyType(keys, propertyTypes);
240 IF_FALSE_LOGE_AND_RETURN_VAL(result == UserAuth::ResultCode::SUCCESS, UserAuth::ResultCode::GENERAL_ERROR);
241
242 Property hdiProperty;
243 int32_t status = allInOneProxy_->GetProperty(templateIdList, propertyTypes, hdiProperty);
244 result = ConvertHdiResultCode(status);
245 if (result != UserAuth::ResultCode::SUCCESS) {
246 IAM_LOGE("SendCommand fail result %{public}d", result);
247 return result;
248 }
249 MoveHdiProperty(hdiProperty, property);
250 return UserAuth::ResultCode::SUCCESS;
251 }
252
MoveHdiProperty(Property & in,UserAuth::Property & out)253 void PinAuthAllInOneHdi::MoveHdiProperty(Property &in, UserAuth::Property &out)
254 {
255 out.authSubType = in.authSubType;
256 out.lockoutDuration = in.lockoutDuration;
257 out.remainAttempts = in.remainAttempts;
258 out.nextFailLockoutDuration = in.nextFailLockoutDuration;
259 }
260
ConvertAttributeKeyVectorToPropertyType(const std::vector<UserAuth::Attributes::AttributeKey> inItems,std::vector<int32_t> & outItems)261 UserAuth::ResultCode PinAuthAllInOneHdi::ConvertAttributeKeyVectorToPropertyType(
262 const std::vector<UserAuth::Attributes::AttributeKey> inItems, std::vector<int32_t> &outItems)
263 {
264 outItems.clear();
265 for (auto &inItem : inItems) {
266 if (inItem == UserAuth::Attributes::ATTR_ENROLL_PROGRESS ||
267 inItem == UserAuth::Attributes::ATTR_SENSOR_INFO) {
268 continue;
269 }
270 int32_t outItem;
271 UserAuth::ResultCode result = ConvertAttributeKeyToPropertyType(inItem, outItem);
272 IF_FALSE_LOGE_AND_RETURN_VAL(result == UserAuth::ResultCode::SUCCESS, UserAuth::ResultCode::GENERAL_ERROR);
273 outItems.push_back(outItem);
274 }
275
276 return UserAuth::ResultCode::SUCCESS;
277 }
278
ConvertAttributeKeyToPropertyType(const UserAuth::Attributes::AttributeKey in,int32_t & out)279 UserAuth::ResultCode PinAuthAllInOneHdi::ConvertAttributeKeyToPropertyType(const UserAuth::Attributes::AttributeKey in,
280 int32_t &out)
281 {
282 static const std::map<UserAuth::Attributes::AttributeKey, GetPropertyType> data = {
283 { UserAuth::Attributes::ATTR_PIN_SUB_TYPE, GetPropertyType::AUTH_SUB_TYPE },
284 { UserAuth::Attributes::ATTR_FREEZING_TIME, GetPropertyType::LOCKOUT_DURATION },
285 { UserAuth::Attributes::ATTR_REMAIN_TIMES, GetPropertyType::REMAIN_ATTEMPTS },
286 { UserAuth::Attributes::ATTR_NEXT_FAIL_LOCKOUT_DURATION, GetPropertyType::NEXT_FAIL_LOCKOUT_DURATION },
287 };
288
289 auto iter = data.find(in);
290 if (iter == data.end()) {
291 IAM_LOGE("attribute %{public}d is invalid", in);
292 return UserAuth::ResultCode::GENERAL_ERROR;
293 } else {
294 out = static_cast<int32_t>(iter->second);
295 }
296 IAM_LOGI("covert hdi result code %{public}d to framework result code %{public}d", in, out);
297 return UserAuth::ResultCode::SUCCESS;
298 }
299
SetAuthType(int32_t authType)300 void PinAuthAllInOneHdi::SetAuthType(int32_t authType)
301 {
302 std::lock_guard<std::mutex> lock(mutex_);
303 switch (authType) {
304 case AuthType::PIN:
305 IAM_LOGI("set authType is pin");
306 authType_ = authType;
307 break;
308 case AuthType::PRIVATE_PIN:
309 IAM_LOGI("set authType is private pin");
310 authType_ = authType;
311 break;
312 default:
313 IAM_LOGE("authType value is error, set failed");
314 }
315 }
316
GetAuthType()317 std::optional<int32_t> PinAuthAllInOneHdi::GetAuthType()
318 {
319 std::lock_guard<std::mutex> lock(mutex_);
320 if (!authType_.has_value()) {
321 IAM_LOGE("authType_ not assigned a value");
322 return std::nullopt;
323 }
324
325 return authType_;
326 }
327
328 } // namespace PinAuth
329 } // namespace UserIam
330 } // namespace OHOS
331