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 if (GetAuthType().value() == AuthType::PRIVATE_PIN) {
129 mode = GET_DATA_MODE_ALL_IN_ONE_PRIVATE_PIN_ENROLL;
130 } else {
131 mode = GET_DATA_MODE_ALL_IN_ONE_RECOVERY_KEY_ENROLL;
132 }
133 UserAuth::ExecutorParam executorParam = {
134 .tokenId = param.tokenId,
135 .scheduleId = scheduleId,
136 .userId = param.userId,
137 };
138 auto callback = sptr<IExecutorCallback>(new (std::nothrow) PinAuthExecutorCallbackHdi(callbackObj,
139 shared_from_this(), executorParam, mode));
140 if (callback == nullptr) {
141 IAM_LOGE("callback is null");
142 return UserAuth::ResultCode::GENERAL_ERROR;
143 }
144 int32_t status = allInOneProxy_->Enroll(scheduleId, param.extraInfo, callback);
145 UserAuth::ResultCode result = ConvertHdiResultCode(status);
146 if (result != UserAuth::ResultCode::SUCCESS) {
147 IAM_LOGE("Enroll fail ret=%{public}d", result);
148 return result;
149 }
150 return UserAuth::ResultCode::SUCCESS;
151 }
152
Authenticate(uint64_t scheduleId,const UserAuth::AuthenticateParam & param,const std::shared_ptr<UserAuth::IExecuteCallback> & callbackObj)153 UserAuth::ResultCode PinAuthAllInOneHdi::Authenticate(
154 uint64_t scheduleId, const UserAuth::AuthenticateParam ¶m,
155 const std::shared_ptr<UserAuth::IExecuteCallback> &callbackObj)
156 {
157 if (allInOneProxy_ == nullptr) {
158 IAM_LOGE("allInOneProxy is null");
159 return UserAuth::ResultCode::GENERAL_ERROR;
160 }
161 if (callbackObj == nullptr) {
162 IAM_LOGE("callbackObj is null");
163 return UserAuth::ResultCode::GENERAL_ERROR;
164 }
165 if (!GetAuthType().has_value()) {
166 IAM_LOGE("authType is error");
167 return UserAuth::ResultCode::GENERAL_ERROR;
168 }
169 GetDataMode mode = GET_DATA_MODE_NONE;
170 if (GetAuthType().value() == AuthType::PIN) {
171 mode = GET_DATA_MODE_ALL_IN_ONE_PIN_AUTH;
172 } else if (GetAuthType().value() == AuthType::PRIVATE_PIN) {
173 mode = GET_DATA_MODE_ALL_IN_ONE_PRIVATE_PIN_AUTH;
174 } else {
175 mode = GET_DATA_MODE_ALL_IN_ONE_RECOVERY_KEY_AUTH;
176 }
177 UserAuth::ExecutorParam executorParam = {
178 .tokenId = param.tokenId,
179 .authIntent = param.authIntent,
180 .scheduleId = scheduleId,
181 .userId = param.userId,
182 };
183 auto callback = sptr<IExecutorCallback>(new (std::nothrow) PinAuthExecutorCallbackHdi(callbackObj,
184 shared_from_this(), executorParam, mode));
185 if (callback == nullptr) {
186 IAM_LOGE("callback is null");
187 return UserAuth::ResultCode::GENERAL_ERROR;
188 }
189 if (param.templateIdList.size() == 0) {
190 IAM_LOGE("Error param");
191 return UserAuth::ResultCode::GENERAL_ERROR;
192 }
193 int32_t status = allInOneProxy_->Authenticate(scheduleId, param.templateIdList,
194 param.extraInfo, callback);
195 UserAuth::ResultCode result = ConvertHdiResultCode(status);
196 if (result != UserAuth::ResultCode::SUCCESS) {
197 IAM_LOGE("Authenticate fail ret=%{public}d", result);
198 return result;
199 }
200 return UserAuth::ResultCode::SUCCESS;
201 }
202
Delete(const std::vector<uint64_t> & templateIdList)203 UserAuth::ResultCode PinAuthAllInOneHdi::Delete(const std::vector<uint64_t> &templateIdList)
204 {
205 if (allInOneProxy_ == nullptr) {
206 IAM_LOGE("allInOneProxy is null");
207 return UserAuth::ResultCode::GENERAL_ERROR;
208 }
209 if (templateIdList.empty()) {
210 IAM_LOGE("templateIdList is empty");
211 return UserAuth::ResultCode::GENERAL_ERROR;
212 }
213 int32_t status = allInOneProxy_->Delete(templateIdList[0]);
214 UserAuth::ResultCode result = ConvertHdiResultCode(status);
215 if (result != UserAuth::ResultCode::SUCCESS) {
216 IAM_LOGE("Delete fail ret=%{public}d", result);
217 return result;
218 }
219 return UserAuth::ResultCode::SUCCESS;
220 }
221
Cancel(uint64_t scheduleId)222 UserAuth::ResultCode PinAuthAllInOneHdi::Cancel(uint64_t scheduleId)
223 {
224 if (allInOneProxy_ == nullptr) {
225 IAM_LOGE("allInOneProxy is null");
226 return UserAuth::ResultCode::GENERAL_ERROR;
227 }
228 int32_t status = allInOneProxy_->Cancel(scheduleId);
229 UserAuth::ResultCode result = ConvertHdiResultCode(status);
230 if (result != UserAuth::ResultCode::SUCCESS) {
231 IAM_LOGE("Cancel fail ret=%{public}d", result);
232 return result;
233 }
234 return UserAuth::ResultCode::SUCCESS;
235 }
236
GetProperty(const std::vector<uint64_t> & templateIdList,const std::vector<UserAuth::Attributes::AttributeKey> & keys,UserAuth::Property & property)237 UserAuth::ResultCode PinAuthAllInOneHdi::GetProperty(const std::vector<uint64_t> &templateIdList,
238 const std::vector<UserAuth::Attributes::AttributeKey> &keys, UserAuth::Property &property)
239 {
240 IF_FALSE_LOGE_AND_RETURN_VAL(allInOneProxy_ != nullptr, UserAuth::ResultCode::GENERAL_ERROR);
241
242 std::vector<int32_t> propertyTypes;
243 UserAuth::ResultCode result = ConvertAttributeKeyVectorToPropertyType(keys, propertyTypes);
244 IF_FALSE_LOGE_AND_RETURN_VAL(result == UserAuth::ResultCode::SUCCESS, UserAuth::ResultCode::GENERAL_ERROR);
245
246 Property hdiProperty;
247 int32_t status = allInOneProxy_->GetProperty(templateIdList, propertyTypes, hdiProperty);
248 result = ConvertHdiResultCode(status);
249 if (result != UserAuth::ResultCode::SUCCESS) {
250 IAM_LOGE("SendCommand fail result %{public}d", result);
251 return result;
252 }
253 MoveHdiProperty(hdiProperty, property);
254 return UserAuth::ResultCode::SUCCESS;
255 }
256
MoveHdiProperty(Property & in,UserAuth::Property & out)257 void PinAuthAllInOneHdi::MoveHdiProperty(Property &in, UserAuth::Property &out)
258 {
259 out.authSubType = in.authSubType;
260 out.lockoutDuration = in.lockoutDuration;
261 out.remainAttempts = in.remainAttempts;
262 out.nextFailLockoutDuration = in.nextFailLockoutDuration;
263 }
264
ConvertAttributeKeyVectorToPropertyType(const std::vector<UserAuth::Attributes::AttributeKey> inItems,std::vector<int32_t> & outItems)265 UserAuth::ResultCode PinAuthAllInOneHdi::ConvertAttributeKeyVectorToPropertyType(
266 const std::vector<UserAuth::Attributes::AttributeKey> inItems, std::vector<int32_t> &outItems)
267 {
268 outItems.clear();
269 for (auto &inItem : inItems) {
270 if (inItem == UserAuth::Attributes::ATTR_ENROLL_PROGRESS ||
271 inItem == UserAuth::Attributes::ATTR_SENSOR_INFO) {
272 continue;
273 }
274 int32_t outItem;
275 UserAuth::ResultCode result = ConvertAttributeKeyToPropertyType(inItem, outItem);
276 IF_FALSE_LOGE_AND_RETURN_VAL(result == UserAuth::ResultCode::SUCCESS, UserAuth::ResultCode::GENERAL_ERROR);
277 outItems.push_back(outItem);
278 }
279
280 return UserAuth::ResultCode::SUCCESS;
281 }
282
ConvertAttributeKeyToPropertyType(const UserAuth::Attributes::AttributeKey in,int32_t & out)283 UserAuth::ResultCode PinAuthAllInOneHdi::ConvertAttributeKeyToPropertyType(const UserAuth::Attributes::AttributeKey in,
284 int32_t &out)
285 {
286 static const std::map<UserAuth::Attributes::AttributeKey, GetPropertyType> data = {
287 { UserAuth::Attributes::ATTR_PIN_SUB_TYPE, GetPropertyType::AUTH_SUB_TYPE },
288 { UserAuth::Attributes::ATTR_FREEZING_TIME, GetPropertyType::LOCKOUT_DURATION },
289 { UserAuth::Attributes::ATTR_REMAIN_TIMES, GetPropertyType::REMAIN_ATTEMPTS },
290 { UserAuth::Attributes::ATTR_NEXT_FAIL_LOCKOUT_DURATION, GetPropertyType::NEXT_FAIL_LOCKOUT_DURATION },
291 };
292
293 auto iter = data.find(in);
294 if (iter == data.end()) {
295 IAM_LOGE("attribute %{public}d is invalid", in);
296 return UserAuth::ResultCode::GENERAL_ERROR;
297 } else {
298 out = static_cast<int32_t>(iter->second);
299 }
300 IAM_LOGI("covert hdi result code %{public}d to framework result code %{public}d", in, out);
301 return UserAuth::ResultCode::SUCCESS;
302 }
303
SetAuthType(int32_t authType)304 void PinAuthAllInOneHdi::SetAuthType(int32_t authType)
305 {
306 std::lock_guard<std::mutex> lock(mutex_);
307 switch (authType) {
308 case AuthType::PIN:
309 IAM_LOGI("set authType is pin");
310 authType_ = authType;
311 break;
312 case AuthType::RECOVERY_KEY:
313 IAM_LOGI("set authType is recovery key");
314 authType_ = authType;
315 break;
316 case AuthType::PRIVATE_PIN:
317 IAM_LOGI("set authType is private pin");
318 authType_ = authType;
319 break;
320 default:
321 IAM_LOGE("authType value is error, set failed");
322 }
323 }
324
GetAuthType()325 std::optional<int32_t> PinAuthAllInOneHdi::GetAuthType()
326 {
327 std::lock_guard<std::mutex> lock(mutex_);
328 if (!authType_.has_value()) {
329 IAM_LOGE("authType_ not assigned a value");
330 return std::nullopt;
331 }
332
333 return authType_;
334 }
335
336 } // namespace PinAuth
337 } // namespace UserIam
338 } // namespace OHOS
339