1 /*
2 * Copyright (c) 2025 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 "dm_crypto.h"
16 #include "dm_negotiate_process.h"
17
18 namespace OHOS {
19 namespace DistributedHardware {
20 DM_IMPLEMENT_SINGLE_INSTANCE(NegotiateProcess);
21
OnlyPinBind(std::shared_ptr<DmAuthContext> context)22 int32_t OnlyPinBind(std::shared_ptr<DmAuthContext> context)
23 {
24 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
25 context->needBind = true;
26 context->needAgreeCredential = false;
27 context->needAuth = false;
28 return DM_OK;
29 }
30
EndBind(std::shared_ptr<DmAuthContext> context)31 int32_t EndBind(std::shared_ptr<DmAuthContext> context)
32 {
33 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
34 context->needBind = false;
35 context->needAgreeCredential = false;
36 context->needAuth = false;
37 context->reason = DM_BIND_TRUST_TARGET;
38 return DM_BIND_TRUST_TARGET;
39 }
40
OnlyCredAuth(std::shared_ptr<DmAuthContext> context)41 int32_t OnlyCredAuth(std::shared_ptr<DmAuthContext> context)
42 {
43 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
44 context->needBind = false;
45 context->needAgreeCredential = false;
46 context->needAuth = true;
47 return DM_OK;
48 }
49
PinBindAndCredAuth(std::shared_ptr<DmAuthContext> context)50 int32_t PinBindAndCredAuth(std::shared_ptr<DmAuthContext> context)
51 {
52 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
53 context->needBind = true;
54 context->needAgreeCredential = true;
55 context->needAuth = true;
56 return DM_OK;
57 }
58
NegotiateProcess()59 NegotiateProcess::NegotiateProcess()
60 {
61 LOGI("start.");
62 handlers_[NegotiateSpec(CredType::DM_NO_CRED, AclType::DM_NO_ACL, AuthType::DM_INPUT_PINCODE)] =
63 std::make_unique<NoCredNoAclInputAuthType>();
64 handlers_[NegotiateSpec(CredType::DM_NO_CRED, AclType::DM_NO_ACL, AuthType::DM_IMPORT_AUTHTYPE)] =
65 std::make_unique<NoCredNoAclImportAuthType>();
66 handlers_[NegotiateSpec(CredType::DM_IDENTICAL_CREDTYPE, AclType::DM_NO_ACL, AuthType::DM_INPUT_PINCODE)] =
67 std::make_unique<IdentCredNoAclInputAuthType>();
68 handlers_[NegotiateSpec(CredType::DM_IDENTICAL_CREDTYPE, AclType::DM_NO_ACL, AuthType::DM_IMPORT_AUTHTYPE)] =
69 std::make_unique<IdentCredNoAclImportAuthType>();
70 handlers_[NegotiateSpec(CredType::DM_IDENTICAL_CREDTYPE, AclType::DM_IDENTICAL_ACL, AuthType::DM_INPUT_PINCODE)] =
71 std::make_unique<IdentCredIdentAclInputAuthType>();
72 handlers_[NegotiateSpec(CredType::DM_IDENTICAL_CREDTYPE, AclType::DM_IDENTICAL_ACL, AuthType::DM_IMPORT_AUTHTYPE)] =
73 std::make_unique<IdentCredIdentAclImportAuthType>();
74 handlers_[NegotiateSpec(CredType::DM_IDENTICAL_CREDTYPE, AclType::DM_P2P_ACL, AuthType::DM_INPUT_PINCODE)] =
75 std::make_unique<IdentCredP2pAclInputAuthType>();
76 handlers_[NegotiateSpec(CredType::DM_IDENTICAL_CREDTYPE, AclType::DM_P2P_ACL, AuthType::DM_IMPORT_AUTHTYPE)] =
77 std::make_unique<IdentCredP2pAclImportAuthType>();
78 handlers_[NegotiateSpec(CredType::DM_SHARE_CREDTYPE, AclType::DM_NO_ACL, AuthType::DM_INPUT_PINCODE)] =
79 std::make_unique<ShareCredNoAclInputAuthType>();
80 handlers_[NegotiateSpec(CredType::DM_SHARE_CREDTYPE, AclType::DM_NO_ACL, AuthType::DM_IMPORT_AUTHTYPE)] =
81 std::make_unique<ShareCredNoAclImportAuthType>();
82 handlers_[NegotiateSpec(CredType::DM_SHARE_CREDTYPE, AclType::DM_SHARE_ACL, AuthType::DM_INPUT_PINCODE)] =
83 std::make_unique<ShareCredShareAclInputAuthType>();
84 handlers_[NegotiateSpec(CredType::DM_SHARE_CREDTYPE, AclType::DM_SHARE_ACL, AuthType::DM_IMPORT_AUTHTYPE)] =
85 std::make_unique<ShareCredShareAclImportAuthType>();
86 handlers_[NegotiateSpec(CredType::DM_SHARE_CREDTYPE, AclType::DM_P2P_ACL, AuthType::DM_INPUT_PINCODE)] =
87 std::make_unique<ShareCredP2pAclInputAuthType>();
88 handlers_[NegotiateSpec(CredType::DM_SHARE_CREDTYPE, AclType::DM_P2P_ACL, AuthType::DM_IMPORT_AUTHTYPE)] =
89 std::make_unique<ShareCredP2pAclImportAuthType>();
90 handlers_[NegotiateSpec(CredType::DM_P2P_CREDTYPE, AclType::DM_NO_ACL, AuthType::DM_INPUT_PINCODE)] =
91 std::make_unique<P2pCredNoAclInputAuthType>();
92 handlers_[NegotiateSpec(CredType::DM_P2P_CREDTYPE, AclType::DM_NO_ACL, AuthType::DM_IMPORT_AUTHTYPE)] =
93 std::make_unique<P2pCredNoAclImportAuthType>();
94 handlers_[NegotiateSpec(CredType::DM_P2P_CREDTYPE, AclType::DM_P2P_ACL, AuthType::DM_INPUT_PINCODE)] =
95 std::make_unique<P2pCredP2pAclInputAuthType>();
96 handlers_[NegotiateSpec(CredType::DM_P2P_CREDTYPE, AclType::DM_P2P_ACL, AuthType::DM_IMPORT_AUTHTYPE)] =
97 std::make_unique<P2pCredP2pAclImportAuthType>();
98 }
99
HandleNegotiateResult(std::shared_ptr<DmAuthContext> context)100 int32_t NegotiateProcess::HandleNegotiateResult(std::shared_ptr<DmAuthContext> context)
101 {
102 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
103 std::string credTypeList = context->direction == DmAuthDirection::DM_AUTH_SOURCE ?
104 context->accesser.credTypeList : context->accessee.credTypeList;
105 std::string aclTypeList = context->direction == DmAuthDirection::DM_AUTH_SOURCE ?
106 context->accesser.aclTypeList : context->accessee.aclTypeList;
107 CredType credType = ConvertCredType(credTypeList);
108 AclType aclType = ConvertAclType(aclTypeList);
109 AuthType authType = ConvertAuthType(context->authType);
110 LOGI("credType %{public}d, aclType %{public}d, authType %{public}d.",
111 static_cast<int32_t>(credType), static_cast<int32_t>(aclType), static_cast<int32_t>(authType));
112 int32_t ret = ERR_DM_CAPABILITY_NEGOTIATE_FAILED;
113 NegotiateSpec negotiateSpec(credType, aclType, authType);
114 auto handler = handlers_.find(negotiateSpec);
115 if (handler != handlers_.end() && handler->second != nullptr) {
116 ret = handler->second->NegotiateHandle(context);
117 } else {
118 return ret;
119 }
120 if (!context->IsProxyBind || context->subjectProxyOnes.empty() ||
121 (credType == CredType::DM_IDENTICAL_CREDTYPE && aclType == AclType::DM_IDENTICAL_ACL) ||
122 (credType == CredType::DM_SHARE_CREDTYPE && aclType == AclType::DM_SHARE_ACL)) {
123 return ret;
124 }
125 return HandleProxyNegotiateResult(context, ret);
126 }
127
HandleProxyNegotiateResult(std::shared_ptr<DmAuthContext> context,int32_t result)128 int32_t NegotiateProcess::HandleProxyNegotiateResult(std::shared_ptr<DmAuthContext> context, int32_t result)
129 {
130 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
131 if (!context->IsProxyBind || context->subjectProxyOnes.empty()) {
132 return DM_OK;
133 }
134 bool isTrust = true;
135 for (auto &app : context->subjectProxyOnes) {
136 std::string credTypeList = context->direction == DmAuthDirection::DM_AUTH_SOURCE ?
137 app.proxyAccesser.credTypeList : app.proxyAccessee.credTypeList;
138 std::string aclTypeList = context->direction == DmAuthDirection::DM_AUTH_SOURCE ?
139 app.proxyAccesser.aclTypeList : app.proxyAccessee.aclTypeList;
140 CredType credType = ConvertCredType(credTypeList);
141 AclType aclType = ConvertAclType(aclTypeList);
142 if (credType == CredType::DM_P2P_CREDTYPE && aclType == AclType::DM_P2P_ACL) {
143 app.needBind = false;
144 app.needAgreeCredential = false;
145 app.needAuth = false;
146 app.IsNeedSetProxyRelationShip = IsNeedSetProxyRelationShip(context, app);
147 }
148 }
149 return DM_OK;
150 }
151
IsNeedSetProxyRelationShip(std::shared_ptr<DmAuthContext> context,DmProxyAuthContext & proxyContext)152 bool NegotiateProcess::IsNeedSetProxyRelationShip(std::shared_ptr<DmAuthContext> context,
153 DmProxyAuthContext &proxyContext)
154 {
155 DmProxyAccess &access = context->direction == DmAuthDirection::DM_AUTH_SOURCE ?
156 proxyContext.proxyAccesser : proxyContext.proxyAccessee;
157 if (access.aclProfiles.find(DM_POINT_TO_POINT) == access.aclProfiles.end()) {
158 return true;
159 }
160 std::string accesserExtraData = access.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserExtraData();
161 std::string accesseeExtraData = access.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeExtraData();
162 if ((IsExistTheTokenId(accesserExtraData, proxyContext.proxyAccesser.tokenIdHash) &&
163 IsExistTheTokenId(accesseeExtraData, proxyContext.proxyAccessee.tokenIdHash)) ||
164 (IsExistTheTokenId(accesserExtraData, proxyContext.proxyAccessee.tokenIdHash) &&
165 IsExistTheTokenId(accesseeExtraData, proxyContext.proxyAccesser.tokenIdHash))) {
166 return false;
167 }
168 return true;
169 }
170
IsExistTheTokenId(const std::string extraData,const std::string tokenIdHash)171 bool NegotiateProcess::IsExistTheTokenId(const std::string extraData, const std::string tokenIdHash)
172 {
173 if (extraData.empty()) {
174 return false;
175 }
176 JsonObject extObj;
177 extObj.Parse(extraData);
178 if (extObj.IsDiscarded()) {
179 return false;
180 }
181 JsonObject proxyObj;
182 if (IsString(extObj, TAG_PROXY)) {
183 std::string proxyStr = extObj[TAG_PROXY].Get<std::string>();
184 proxyObj.Parse(proxyStr);
185 }
186 if (proxyObj.IsDiscarded()) {
187 return false;
188 }
189 for (auto const &item : proxyObj.Items()) {
190 if (item.IsNumber() && tokenIdHash == Crypto::GetTokenIdHash(std::to_string(item.Get<int64_t>()))) {
191 return true;
192 }
193 }
194 return false;
195 }
196
ConvertCredType(const std::string & credType)197 CredType NegotiateProcess::ConvertCredType(const std::string &credType)
198 {
199 LOGI("start credType %{public}s.", credType.c_str());
200 CredType credTypeTemp = CredType::DM_NO_CRED;
201 if (credType.empty()) {
202 return credTypeTemp;
203 }
204 JsonObject credTypeJson;
205 credTypeJson.Parse(credType);
206 if (credTypeJson.IsDiscarded()) {
207 LOGE("Parse credType str failed.");
208 return credTypeTemp;
209 }
210 if (credTypeJson.Contains("identicalCredType")) {
211 credTypeTemp = CredType::DM_IDENTICAL_CREDTYPE;
212 return credTypeTemp;
213 } else if (credTypeJson.Contains("shareCredType")) {
214 credTypeTemp = CredType::DM_SHARE_CREDTYPE;
215 return credTypeTemp;
216 } else if (credTypeJson.Contains("pointTopointCredType")) {
217 credTypeTemp = CredType::DM_P2P_CREDTYPE;
218 return credTypeTemp;
219 } else {
220 credTypeTemp = CredType::DM_NO_CRED;
221 }
222 return credTypeTemp;
223 }
224
ConvertAclType(const std::string & aclType)225 AclType NegotiateProcess::ConvertAclType(const std::string &aclType)
226 {
227 LOGI("start credType %{public}s.", aclType.c_str());
228 AclType aclTypeTemp = AclType::DM_NO_ACL;
229 if (aclType.empty()) {
230 return aclTypeTemp;
231 }
232 JsonObject aclTypeJson;
233 aclTypeJson.Parse(aclType);
234 if (aclTypeJson.IsDiscarded()) {
235 LOGE("Parse credType str failed.");
236 return aclTypeTemp;
237 }
238 if (aclTypeJson.Contains("identicalAcl")) {
239 aclTypeTemp = AclType::DM_IDENTICAL_ACL;
240 return aclTypeTemp;
241 } else if (aclTypeJson.Contains("shareAcl")) {
242 aclTypeTemp = AclType::DM_SHARE_ACL;
243 return aclTypeTemp;
244 } else if (aclTypeJson.Contains("pointTopointAcl")) {
245 aclTypeTemp = AclType::DM_P2P_ACL;
246 return aclTypeTemp;
247 } else {
248 aclTypeTemp = AclType::DM_NO_ACL;
249 }
250 return aclTypeTemp;
251 }
252
ConvertAuthType(const DmAuthType & authType)253 AuthType NegotiateProcess::ConvertAuthType(const DmAuthType &authType)
254 {
255 LOGI("start authType %{public}d.", static_cast<int32_t>(authType));
256 AuthType authTypeTemp = AuthType::DM_INVALIED_AUTHTYPE;
257 if (authType == DmAuthType::AUTH_TYPE_IMPORT_AUTH_CODE || authType == DmAuthType::AUTH_TYPE_NFC) {
258 authTypeTemp = AuthType::DM_IMPORT_AUTHTYPE;
259 } else {
260 authTypeTemp = AuthType::DM_INPUT_PINCODE;
261 }
262 return authTypeTemp;
263 }
264
NegotiateHandle(std::shared_ptr<DmAuthContext> context)265 int32_t NoCredNoAclInputAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
266 {
267 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
268 return PinBindAndCredAuth(context);
269 }
270
NegotiateHandle(std::shared_ptr<DmAuthContext> context)271 int32_t NoCredNoAclImportAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
272 {
273 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
274 return PinBindAndCredAuth(context);
275 }
276
NegotiateHandle(std::shared_ptr<DmAuthContext> context)277 int32_t IdentCredNoAclInputAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
278 {
279 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
280 return OnlyCredAuth(context);
281 }
282
NegotiateHandle(std::shared_ptr<DmAuthContext> context)283 int32_t IdentCredNoAclImportAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
284 {
285 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
286 return PinBindAndCredAuth(context);
287 }
288
NegotiateHandle(std::shared_ptr<DmAuthContext> context)289 int32_t IdentCredIdentAclInputAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
290 {
291 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
292 return EndBind(context);
293 }
294
NegotiateHandle(std::shared_ptr<DmAuthContext> context)295 int32_t IdentCredIdentAclImportAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
296 {
297 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
298 return OnlyPinBind(context);
299 }
300
NegotiateHandle(std::shared_ptr<DmAuthContext> context)301 int32_t IdentCredP2pAclInputAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
302 {
303 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
304 return OnlyCredAuth(context);
305 }
306
NegotiateHandle(std::shared_ptr<DmAuthContext> context)307 int32_t IdentCredP2pAclImportAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
308 {
309 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
310 return OnlyPinBind(context);
311 }
312
NegotiateHandle(std::shared_ptr<DmAuthContext> context)313 int32_t ShareCredNoAclInputAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
314 {
315 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
316 return OnlyCredAuth(context);
317 }
318
NegotiateHandle(std::shared_ptr<DmAuthContext> context)319 int32_t ShareCredNoAclImportAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
320 {
321 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
322 return PinBindAndCredAuth(context);
323 }
324
NegotiateHandle(std::shared_ptr<DmAuthContext> context)325 int32_t ShareCredShareAclInputAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
326 {
327 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
328 return EndBind(context);
329 }
330
NegotiateHandle(std::shared_ptr<DmAuthContext> context)331 int32_t ShareCredShareAclImportAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
332 {
333 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
334 return OnlyPinBind(context);
335 }
336
NegotiateHandle(std::shared_ptr<DmAuthContext> context)337 int32_t ShareCredP2pAclInputAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
338 {
339 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
340 return OnlyCredAuth(context);
341 }
342
NegotiateHandle(std::shared_ptr<DmAuthContext> context)343 int32_t ShareCredP2pAclImportAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
344 {
345 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
346 return OnlyPinBind(context);
347 }
348
NegotiateHandle(std::shared_ptr<DmAuthContext> context)349 int32_t P2pCredNoAclInputAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
350 {
351 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
352 return PinBindAndCredAuth(context);
353 }
354
NegotiateHandle(std::shared_ptr<DmAuthContext> context)355 int32_t P2pCredNoAclImportAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
356 {
357 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
358 return PinBindAndCredAuth(context);
359 }
360
NegotiateHandle(std::shared_ptr<DmAuthContext> context)361 int32_t P2pCredP2pAclInputAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
362 {
363 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
364 return EndBind(context);
365 }
366
NegotiateHandle(std::shared_ptr<DmAuthContext> context)367 int32_t P2pCredP2pAclImportAuthType::NegotiateHandle(std::shared_ptr<DmAuthContext> context)
368 {
369 CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL);
370 return OnlyPinBind(context);
371 }
372 } // namespace DistributedHardware
373 } // namespace OHOS