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
22 #include "publish_event_adapter.h"
23 #include "credential_info_impl.h"
24 #include "schedule_node_helper.h"
25 #include "user_idm_database.h"
26
27 #define LOG_LABEL UserIam::Common::LABEL_USER_AUTH_SA
28
29 namespace OHOS {
30 namespace UserIam {
31 namespace UserAuth {
EnrollmentImpl(EnrollmentPara enrollPara)32 EnrollmentImpl::EnrollmentImpl(EnrollmentPara enrollPara)
33 : enrollPara_(enrollPara)
34 {
35 }
36
~EnrollmentImpl()37 EnrollmentImpl::~EnrollmentImpl()
38 {
39 Cancel();
40 }
41
SetLatestError(int32_t error)42 void EnrollmentImpl::SetLatestError(int32_t error)
43 {
44 if (error != ResultCode::SUCCESS) {
45 latestError_ = error;
46 }
47 }
48
GetLatestError() const49 int32_t EnrollmentImpl::GetLatestError() const
50 {
51 return latestError_;
52 }
53
SetExecutorSensorHint(uint32_t executorSensorHint)54 void EnrollmentImpl::SetExecutorSensorHint(uint32_t executorSensorHint)
55 {
56 executorSensorHint_ = executorSensorHint;
57 }
58
SetAuthToken(const std::vector<uint8_t> & authToken)59 void EnrollmentImpl::SetAuthToken(const std::vector<uint8_t> &authToken)
60 {
61 authToken_ = authToken;
62 }
63
SetAccessTokenId(uint32_t tokenId)64 void EnrollmentImpl::SetAccessTokenId(uint32_t tokenId)
65 {
66 tokenId_ = tokenId;
67 }
68
GetAccessTokenId() const69 uint32_t EnrollmentImpl::GetAccessTokenId() const
70 {
71 return tokenId_;
72 }
73
SetPinSubType(PinSubType pinSubType)74 void EnrollmentImpl::SetPinSubType(PinSubType pinSubType)
75 {
76 pinSubType_ = pinSubType;
77 }
78
SetIsUpdate(bool isUpdate)79 void EnrollmentImpl::SetIsUpdate(bool isUpdate)
80 {
81 isUpdate_ = isUpdate;
82 }
83
Start(std::vector<std::shared_ptr<ScheduleNode>> & scheduleList,std::shared_ptr<ScheduleNodeCallback> callback)84 bool EnrollmentImpl::Start(std::vector<std::shared_ptr<ScheduleNode>> &scheduleList,
85 std::shared_ptr<ScheduleNodeCallback> callback)
86 {
87 IAM_LOGE("UserId:%{public}d AuthType:%{public}d", enrollPara_.userId, enrollPara_.authType);
88 auto hdi = HdiWrapper::GetHdiInstance();
89 if (!hdi) {
90 IAM_LOGE("bad hdi");
91 return false;
92 }
93 // cache secUserId first in case of update
94 if (isUpdate_ && !GetSecUserId(secUserId_)) {
95 IAM_LOGE("get and cache secUserId fail");
96 return false;
97 }
98
99 HdiScheduleInfo info = {};
100 HdiEnrollParam param = {
101 .authType = static_cast<HdiAuthType>(enrollPara_.authType),
102 .executorSensorHint = executorSensorHint_,
103 .callerName = enrollPara_.callerName,
104 .apiVersion = enrollPara_.sdkVersion,
105 };
106 IamHitraceHelper traceHelper("hdi BeginEnrollment");
107 auto result = hdi->BeginEnrollmentV1_2(enrollPara_.userId, authToken_, param, info);
108 if (result != HDF_SUCCESS) {
109 IAM_LOGE("hdi BeginEnrollment failed, err is %{public}d", result);
110 SetLatestError(result);
111 return false;
112 }
113
114 std::vector<HdiScheduleInfo> infos = {};
115 infos.emplace_back(info);
116
117 ScheduleNodeHelper::NodeOptionalPara para;
118 para.tokenId = tokenId_;
119
120 if (!ScheduleNodeHelper::BuildFromHdi(infos, callback, scheduleList, para)) {
121 IAM_LOGE("BuildFromHdi failed");
122 return false;
123 }
124 if (scheduleList.size() == 0 || scheduleList[0] == nullptr) {
125 IAM_LOGE("Bad Parameter!");
126 return false;
127 }
128 scheduleId_ = scheduleList[0]->GetScheduleId();
129
130 running_ = true;
131 return true;
132 }
133
GetSecUserId(std::optional<uint64_t> & secUserId)134 bool EnrollmentImpl::GetSecUserId(std::optional<uint64_t> &secUserId)
135 {
136 secUserId = std::nullopt;
137 if (enrollPara_.authType != PIN) {
138 IAM_LOGI("no need return sec user id");
139 return true;
140 }
141 auto userInfo = UserIdmDatabase::Instance().GetSecUserInfo(enrollPara_.userId);
142 if (userInfo != nullptr) {
143 secUserId = userInfo->GetSecUserId();
144 return true;
145 }
146
147 // do not delete users in case of updates
148 if (isUpdate_) {
149 return false;
150 }
151
152 IAM_LOGE("current user id %{public}d get fail", enrollPara_.userId);
153 std::vector<std::shared_ptr<CredentialInfoInterface>> credInfos;
154 if (UserIdmDatabase::Instance().DeleteUserEnforce(enrollPara_.userId, credInfos) != SUCCESS) {
155 IAM_LOGE("failed to enforce delete user");
156 }
157 return false;
158 }
159
Update(const std::vector<uint8_t> & scheduleResult,uint64_t & credentialId,std::shared_ptr<CredentialInfoInterface> & info,std::vector<uint8_t> & rootSecret,std::optional<uint64_t> & secUserId)160 bool EnrollmentImpl::Update(const std::vector<uint8_t> &scheduleResult, uint64_t &credentialId,
161 std::shared_ptr<CredentialInfoInterface> &info, std::vector<uint8_t> &rootSecret,
162 std::optional<uint64_t> &secUserId)
163 {
164 auto hdi = HdiWrapper::GetHdiInstance();
165 if (!hdi) {
166 IAM_LOGE("bad hdi");
167 return false;
168 }
169
170 HdiEnrollResultInfo resultInfo = {};
171 auto result = hdi->UpdateEnrollmentResult(enrollPara_.userId, scheduleResult, resultInfo);
172 if (result != HDF_SUCCESS) {
173 IAM_LOGE("hdi UpdateEnrollmentResult failed, err is %{public}d, userId is %{public}d", result,
174 enrollPara_.userId);
175 SetLatestError(result);
176 return false;
177 }
178 IAM_LOGI("hdi UpdateEnrollmentResult success, userId is %{public}d", enrollPara_.userId);
179
180 credentialId = resultInfo.credentialId;
181 rootSecret = resultInfo.rootSecret;
182 if (isUpdate_) {
183 secUserId = secUserId_;
184 info = Common::MakeShared<CredentialInfoImpl>(enrollPara_.userId, resultInfo.oldInfo);
185 if (info == nullptr) {
186 IAM_LOGE("bad alloc");
187 return false;
188 }
189 } else {
190 if (!GetSecUserId(secUserId)) {
191 IAM_LOGE("enroll get secUserId fail");
192 return false;
193 }
194 IAM_LOGI("enroll not need to delete old cred");
195 info = nullptr;
196 }
197 PublishPinEvent();
198 return true;
199 }
200
PublishPinEvent()201 void EnrollmentImpl::PublishPinEvent()
202 {
203 if (enrollPara_.authType != PIN) {
204 return;
205 }
206 IAM_LOGI("begin to publish pin event");
207 if (isUpdate_) {
208 PublishEventAdapter::PublishUpdatedEvent(enrollPara_.userId, scheduleId_);
209 } else {
210 PublishEventAdapter::PublishCreatedEvent(enrollPara_.userId, scheduleId_);
211 }
212 }
213
Cancel()214 bool EnrollmentImpl::Cancel()
215 {
216 if (!running_) {
217 return false;
218 }
219 running_ = false;
220
221 auto hdi = HdiWrapper::GetHdiInstance();
222 if (!hdi) {
223 IAM_LOGE("bad hdi");
224 return false;
225 }
226
227 auto result = hdi->CancelEnrollment(enrollPara_.userId);
228 if (result != HDF_SUCCESS) {
229 IAM_LOGE("hdi CancelEnrollment failed, err is %{public}d", result);
230 SetLatestError(result);
231 return false;
232 }
233 return true;
234 }
235 } // namespace UserAuth
236 } // namespace UserIam
237 } // namespace OHOS