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