• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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