• 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 
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