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 "schedule_node_helper.h"
16 
17 #include <cinttypes>
18 
19 #include "iam_check.h"
20 #include "iam_logger.h"
21 #include "resource_node_pool.h"
22 
23 #define LOG_TAG "USER_AUTH_SA"
24 namespace OHOS {
25 namespace UserIam {
26 namespace UserAuth {
BuildFromHdi(const std::vector<HdiScheduleInfo> & infos,std::shared_ptr<ScheduleNodeCallback> callback,std::vector<std::shared_ptr<ScheduleNode>> & nodes)27 bool ScheduleNodeHelper::BuildFromHdi(const std::vector<HdiScheduleInfo> &infos,
28     std::shared_ptr<ScheduleNodeCallback> callback, std::vector<std::shared_ptr<ScheduleNode>> &nodes)
29 {
30     NodeOptionalPara para;
31     return BuildFromHdi(infos, callback, nodes, para);
32 }
33 
BuildFromHdi(const std::vector<HdiScheduleInfo> & infos,std::shared_ptr<ScheduleNodeCallback> callback,std::vector<std::shared_ptr<ScheduleNode>> & nodes,const NodeOptionalPara & para)34 bool ScheduleNodeHelper::BuildFromHdi(const std::vector<HdiScheduleInfo> &infos,
35     std::shared_ptr<ScheduleNodeCallback> callback, std::vector<std::shared_ptr<ScheduleNode>> &nodes,
36     const NodeOptionalPara &para)
37 {
38     std::vector<std::shared_ptr<ScheduleNode>> outputs;
39 
40     for (const auto &info : infos) {
41         std::shared_ptr<ScheduleNode> node;
42         if (!ScheduleInfoToScheduleNode(info, node, para, callback)) {
43             IAM_LOGE("ScheduleInfoToScheduleNode error");
44             return false;
45         }
46         outputs.push_back(node);
47     }
48 
49     nodes.swap(outputs);
50     return true;
51 }
52 
ScheduleInfoToScheduleNode(const HdiScheduleInfo & info,std::shared_ptr<ScheduleNode> & node,const NodeOptionalPara & para,const std::shared_ptr<ScheduleNodeCallback> & callback)53 bool ScheduleNodeHelper::ScheduleInfoToScheduleNode(const HdiScheduleInfo &info, std::shared_ptr<ScheduleNode> &node,
54     const NodeOptionalPara &para, const std::shared_ptr<ScheduleNodeCallback> &callback)
55 {
56     if (info.executorIndexes.empty()) {
57         IAM_LOGE("executors empty");
58         return false;
59     }
60     std::shared_ptr<ResourceNode> collector;
61     std::shared_ptr<ResourceNode> verifier;
62 
63     std::vector<uint8_t> collectorMessage;
64     std::vector<uint8_t> verifierMessage;
65     if (!ScheduleInfoToExecutors(info, collector, verifier, collectorMessage, verifierMessage)) {
66         IAM_LOGE("ScheduleInfoToExecutors error");
67         return false;
68     }
69 
70     IAM_LOGI("collectorMessage size: %{public}zu, verifierMessage size  %{public}zu",
71         collectorMessage.size(), verifierMessage.size());
72 
73     auto builder = ScheduleNode::Builder::New(collector, verifier);
74     if (builder == nullptr) {
75         IAM_LOGE("invalid builder");
76         return false;
77     }
78 
79     if (para.tokenId.has_value()) {
80         builder->SetAccessTokenId(para.tokenId.value());
81     }
82 
83     node = builder->SetAuthType(static_cast<AuthType>(info.authType))
84         ->SetExecutorMatcher(info.executorMatcher)
85         ->SetScheduleId(info.scheduleId)
86         ->SetTemplateIdList(info.templateIds)
87         ->SetScheduleMode(static_cast<ScheduleMode>(info.scheduleMode))
88         ->SetExpiredTime(para.expire.value_or(0))
89         ->SetPinSubType(para.pinSubType.value_or(PinSubType::PIN_MAX))
90         ->SetScheduleCallback(callback)
91         ->SetEndAfterFirstFail(para.endAfterFirstFail.value_or(false))
92         ->SetCollectorTokenId(para.collectorTokenId)
93         ->SetCollectorMessage(collectorMessage)
94         ->SetVerifierMessage(verifierMessage)
95         ->SetAuthIntent(para.authIntent)
96         ->SetUserId(para.userId)
97         ->Build();
98     if (node == nullptr) {
99         IAM_LOGE("builder failed");
100         return false;
101     }
102     return true;
103 }
104 
ScheduleInfoToExecutors(const HdiScheduleInfo & info,std::shared_ptr<ResourceNode> & collector,std::shared_ptr<ResourceNode> & verifier,std::vector<uint8_t> & collectorMessage,std::vector<uint8_t> & verifierMessage)105 bool ScheduleNodeHelper::ScheduleInfoToExecutors(const HdiScheduleInfo &info, std::shared_ptr<ResourceNode> &collector,
106     std::shared_ptr<ResourceNode> &verifier, std::vector<uint8_t> &collectorMessage,
107     std::vector<uint8_t> &verifierMessage)
108 {
109     IF_FALSE_LOGE_AND_RETURN_VAL(info.executorIndexes.size() == info.executorMessages.size(), false);
110     IF_FALSE_LOGE_AND_RETURN_VAL(info.executorIndexes.size() > 0, false);
111 
112     for (uint32_t i = 0; i < info.executorIndexes.size(); i++) {
113         uint64_t executorIndex = info.executorIndexes[i];
114         auto resource = ResourceNodePool::Instance().Select(executorIndex).lock();
115         if (resource == nullptr) {
116             IAM_LOGE("invalid executorId ****%{public}hx", static_cast<uint16_t>(executorIndex));
117             return false;
118         }
119         IAM_LOGI("executor role %{public}d", resource->GetExecutorRole());
120         switch (resource->GetExecutorRole()) {
121             case COLLECTOR: {
122                 collector = resource;
123                 collectorMessage = info.executorMessages[i];
124                 break;
125             }
126             case VERIFIER: {
127                 verifier = resource;
128                 verifierMessage = info.executorMessages[i];
129                 break;
130             }
131             case ALL_IN_ONE: {
132                 collector = resource;
133                 verifier = resource;
134                 verifierMessage = info.executorMessages[i];
135                 break;
136             }
137             default: {
138                 IAM_LOGE("invalid executor role");
139                 break;
140             }
141         }
142     }
143     if (collector == nullptr) {
144         IAM_LOGE("invalid executor collector");
145         return false;
146     }
147     if (verifier == nullptr) {
148         IAM_LOGE("invalid executor verifier");
149         return false;
150     }
151     return true;
152 }
153 } // namespace UserAuth
154 } // namespace UserIam
155 } // namespace OHOS