• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 #include "enrollment_impl.h"
16 
17 #include "credential_info_impl.h"
18 #include "event_listener_manager.h"
19 #include "hdi_wrapper.h"
20 #include "iam_hitrace_helper.h"
21 #include "iam_logger.h"
22 #include "iam_ptr.h"
23 #include "ipc_common.h"
24 #include "load_mode_handler.h"
25 #include "publish_event_adapter.h"
26 #include "schedule_node_helper.h"
27 #include "update_pin_param_impl.h"
28 #include "user_idm_database.h"
29 
30 #define LOG_TAG "USER_AUTH_SA"
31 
32 namespace OHOS {
33 namespace UserIam {
34 namespace UserAuth {
EnrollmentImpl(EnrollmentPara enrollPara)35 EnrollmentImpl::EnrollmentImpl(EnrollmentPara enrollPara) : enrollPara_(enrollPara)
36 {
37 }
38 
~EnrollmentImpl()39 EnrollmentImpl::~EnrollmentImpl()
40 {
41     Cancel();
42 }
43 
SetLatestError(int32_t error)44 void EnrollmentImpl::SetLatestError(int32_t error)
45 {
46     if (error != ResultCode::SUCCESS) {
47         latestError_ = error;
48     }
49 }
50 
GetLatestError() const51 int32_t EnrollmentImpl::GetLatestError() const
52 {
53     return latestError_;
54 }
55 
SetExecutorSensorHint(uint32_t executorSensorHint)56 void EnrollmentImpl::SetExecutorSensorHint(uint32_t executorSensorHint)
57 {
58     executorSensorHint_ = executorSensorHint;
59 }
60 
SetAuthToken(const std::vector<uint8_t> & authToken)61 void EnrollmentImpl::SetAuthToken(const std::vector<uint8_t> &authToken)
62 {
63     authToken_ = authToken;
64 }
65 
SetAccessTokenId(uint32_t tokenId)66 void EnrollmentImpl::SetAccessTokenId(uint32_t tokenId)
67 {
68     tokenId_ = tokenId;
69 }
70 
GetAccessTokenId() const71 uint32_t EnrollmentImpl::GetAccessTokenId() const
72 {
73     return tokenId_;
74 }
75 
SetPinSubType(PinSubType pinSubType)76 void EnrollmentImpl::SetPinSubType(PinSubType pinSubType)
77 {
78     pinSubType_ = pinSubType;
79 }
80 
SetIsUpdate(bool isUpdate)81 void EnrollmentImpl::SetIsUpdate(bool isUpdate)
82 {
83     isUpdate_ = isUpdate;
84 }
85 
GetUserId() const86 int32_t EnrollmentImpl::GetUserId() const
87 {
88     return enrollPara_.userId;
89 }
90 
Start(std::vector<std::shared_ptr<ScheduleNode>> & scheduleList,std::shared_ptr<ScheduleNodeCallback> callback)91 bool EnrollmentImpl::Start(std::vector<std::shared_ptr<ScheduleNode>> &scheduleList,
92     std::shared_ptr<ScheduleNodeCallback> callback)
93 {
94     IAM_LOGE("UserId:%{public}d, AuthType:%{public}d, pinSubType:%{public}d", enrollPara_.userId, enrollPara_.authType,
95         enrollPara_.pinType);
96     auto hdi = HdiWrapper::GetHdiInstance();
97     if (!hdi) {
98         IAM_LOGE("bad hdi");
99         return false;
100     }
101     // cache secUserId first in case of update
102     if (isUpdate_ && !GetSecUserId(secUserId_)) {
103         IAM_LOGE("get and cache secUserId fail");
104         return false;
105     }
106 
107     HdiScheduleInfo info = {};
108     int32_t userType;
109     if (IpcCommon::GetUserTypeByUserId(enrollPara_.userId, userType) != SUCCESS) {
110         IAM_LOGE("failed to get userType");
111         return false;
112     }
113     HdiCallerType callerType = ConvertATokenTypeToCallerType(enrollPara_.callerType);
114     if (callerType == HDI_CALLER_TYPE_INVALID) {
115         IAM_LOGE("ConvertATokenTypeToCallerType failed, ATokenType:%{public}d", enrollPara_.callerType);
116         return false;
117     }
118     HdiEnrollParam param = {
119         .authType = static_cast<HdiAuthType>(enrollPara_.authType),
120         .executorSensorHint = executorSensorHint_,
121         .callerName = enrollPara_.callerName,
122         .callerType = callerType,
123         .apiVersion = enrollPara_.sdkVersion,
124         .userId = enrollPara_.userId,
125         .userType = userType,
126         .authSubType = enrollPara_.pinType,
127     };
128     IamHitraceHelper traceHelper("hdi BeginEnrollment");
129     auto result = hdi->BeginEnrollment(authToken_, param, info);
130     if (result != HDF_SUCCESS) {
131         IAM_LOGE("hdi BeginEnrollment failed, err is %{public}d", result);
132         SetLatestError(result);
133         return false;
134     }
135 
136     return StartSchedule(enrollPara_.userId, info, scheduleList, callback);
137 }
138 
GetSecUserId(std::optional<uint64_t> & secUserId)139 bool EnrollmentImpl::GetSecUserId(std::optional<uint64_t> &secUserId)
140 {
141     secUserId = std::nullopt;
142     if (enrollPara_.authType != PIN) {
143         IAM_LOGI("no need return sec user id");
144         return true;
145     }
146     std::shared_ptr<SecureUserInfoInterface> userInfo = nullptr;
147     int32_t ret = UserIdmDatabase::Instance().GetSecUserInfo(enrollPara_.userId, userInfo);
148     if (ret != SUCCESS) {
149         IAM_LOGE("get secUserInfo fail, ret:%{public}d, userId:%{public}d", ret, enrollPara_.userId);
150         return false;
151     }
152     if (userInfo != nullptr) {
153         secUserId = userInfo->GetSecUserId();
154         return true;
155     }
156 
157     // do not delete users in case of updates
158     if (isUpdate_) {
159         return false;
160     }
161 
162     IAM_LOGE("current user id %{public}d get fail", enrollPara_.userId);
163     std::vector<std::shared_ptr<CredentialInfoInterface>> credInfos;
164     if (UserIdmDatabase::Instance().DeleteUserEnforce(enrollPara_.userId, credInfos) != SUCCESS) {
165         IAM_LOGE("failed to enforce delete user");
166     }
167     return false;
168 }
169 
Update(const std::vector<uint8_t> & scheduleResult,uint64_t & credentialId,std::shared_ptr<CredentialInfoInterface> & info,std::shared_ptr<UpdatePinParamInterface> & pinInfo,std::optional<uint64_t> & secUserId)170 bool EnrollmentImpl::Update(const std::vector<uint8_t> &scheduleResult, uint64_t &credentialId,
171     std::shared_ptr<CredentialInfoInterface> &info, std::shared_ptr<UpdatePinParamInterface> &pinInfo,
172     std::optional<uint64_t> &secUserId)
173 {
174     auto hdi = HdiWrapper::GetHdiInstance();
175     if (!hdi) {
176         IAM_LOGE("bad hdi");
177         return false;
178     }
179 
180     HdiEnrollResultInfo resultInfo = {};
181     auto result = hdi->UpdateEnrollmentResult(enrollPara_.userId, scheduleResult, resultInfo);
182     if (result != HDF_SUCCESS) {
183         IAM_LOGE("hdi UpdateEnrollmentResult failed, err is %{public}d, userId is %{public}d", result,
184             enrollPara_.userId);
185         SetLatestError(result);
186         return false;
187     }
188     IAM_LOGI("hdi UpdateEnrollmentResult success, userId is %{public}d", enrollPara_.userId);
189 
190     credentialId = resultInfo.credentialId;
191     pinInfo = Common::MakeShared<UpdatePinParamImpl>(resultInfo.oldInfo.credentialId, resultInfo.oldRootSecret,
192         resultInfo.rootSecret, resultInfo.authToken);
193     if (pinInfo == nullptr) {
194         IAM_LOGE("pinInfo bad alloc");
195         return false;
196     }
197 
198     if (isUpdate_) {
199         secUserId = secUserId_;
200         info = Common::MakeShared<CredentialInfoImpl>(enrollPara_.userId, resultInfo.oldInfo);
201         if (info == nullptr) {
202             IAM_LOGE("bad alloc");
203             return false;
204         }
205     } else {
206         if (!GetSecUserId(secUserId)) {
207             IAM_LOGE("enroll get secUserId fail");
208             return false;
209         }
210         IAM_LOGI("enroll not need to delete old cred");
211         info = nullptr;
212     }
213     PublishCredentialChangeEvent(resultInfo);
214     return true;
215 }
216 
PublishCredentialChangeEvent(const HdiEnrollResultInfo & resultInfo)217 void EnrollmentImpl::PublishCredentialChangeEvent(const HdiEnrollResultInfo &resultInfo)
218 {
219     CredChangeEventInfo changeInfo = {
220         enrollPara_.callerName, enrollPara_.callerType, resultInfo.credentialId, 0, false};
221     if (isUpdate_ && enrollPara_.authType == PIN) {
222         changeInfo.lastCredentialId = resultInfo.oldInfo.credentialId;
223         PublishEventAdapter::GetInstance().CachePinUpdateParam(enrollPara_.userId, scheduleId_, changeInfo);
224         return;
225     }
226 
227     std::vector<std::shared_ptr<CredentialInfoInterface>> credentialInfos;
228     if (UserIdmDatabase::Instance().GetCredentialInfo(
229         enrollPara_.userId, enrollPara_.authType, credentialInfos) != SUCCESS) {
230         IAM_LOGE("get credential fail");
231         return;
232     }
233     PublishEventAdapter::GetInstance().PublishCredentialUpdatedEvent(enrollPara_.userId,
234         static_cast<int32_t>(enrollPara_.authType), credentialInfos.size());
235 
236     if (isUpdate_ && enrollPara_.authType != PIN) {
237         changeInfo.lastCredentialId = resultInfo.oldInfo.credentialId;
238         CredChangeEventListenerManager::GetInstance().OnNotifyCredChangeEvent(enrollPara_.userId,
239             enrollPara_.authType, UPDATE_CRED, changeInfo);
240     } else if (!isUpdate_ && enrollPara_.authType != PIN) {
241         CredChangeEventListenerManager::GetInstance().OnNotifyCredChangeEvent(enrollPara_.userId,
242             enrollPara_.authType, ADD_CRED, changeInfo);
243     } else {
244         PublishEventAdapter::GetInstance().PublishCreatedEvent(enrollPara_.userId, scheduleId_);
245         CredChangeEventListenerManager::GetInstance().OnNotifyCredChangeEvent(enrollPara_.userId,
246             enrollPara_.authType, ADD_CRED, changeInfo);
247     }
248 }
249 
Cancel()250 bool EnrollmentImpl::Cancel()
251 {
252     if (!running_) {
253         return false;
254     }
255     running_ = false;
256 
257     auto hdi = HdiWrapper::GetHdiInstance();
258     if (!hdi) {
259         IAM_LOGE("bad hdi");
260         return false;
261     }
262 
263     auto result = hdi->CancelEnrollment(enrollPara_.userId);
264     if (result != HDF_SUCCESS) {
265         IAM_LOGE("hdi CancelEnrollment failed, err is %{public}d", result);
266         SetLatestError(result);
267         return false;
268     }
269     return true;
270 }
271 
StartSchedule(int32_t userId,HdiScheduleInfo & info,std::vector<std::shared_ptr<ScheduleNode>> & scheduleList,std::shared_ptr<ScheduleNodeCallback> callback)272 bool EnrollmentImpl::StartSchedule(int32_t userId, HdiScheduleInfo &info,
273     std::vector<std::shared_ptr<ScheduleNode>> &scheduleList, std::shared_ptr<ScheduleNodeCallback> callback)
274 {
275     IAM_LOGI("start");
276     std::vector<HdiScheduleInfo> infos = {};
277     infos.emplace_back(info);
278 
279     ScheduleNodeHelper::NodeOptionalPara para;
280     para.tokenId = tokenId_;
281     para.userId = userId;
282 
283     if (!ScheduleNodeHelper::BuildFromHdi(infos, callback, scheduleList, para)) {
284         IAM_LOGE("BuildFromHdi failed");
285         return false;
286     }
287     if (scheduleList.size() == 0 || scheduleList[0] == nullptr) {
288         IAM_LOGE("Bad Parameter!");
289         return false;
290     }
291 
292     scheduleId_ = scheduleList[0]->GetScheduleId();
293     running_ = true;
294     return true;
295 }
296 } // namespace UserAuth
297 } // namespace UserIam
298 } // namespace OHOS