From e482c17642633bb5859dde6071a13c9d9357b660 Mon Sep 17 00:00:00 2001 From: liuzhongming Date: Tue, 10 Jun 2025 20:49:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=90=86=E7=BB=91=E5=AE=9A=20Signed-o?= =?UTF-8?q?ff-by:=20liuzhongming=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/include/dm_constants.h | 5 + common/src/dm_constants.cpp | 5 + .../include/deviceprofile_connector.h | 2 + .../src/deviceprofile_connector.cpp | 12 + .../include/authentication_v2/auth_manager.h | 2 + .../authentication_v2/dm_auth_context.h | 50 ++ .../authentication_v2/dm_auth_manager_base.h | 1 + .../dm_auth_message_processor.h | 17 +- .../include/authentication_v2/dm_auth_state.h | 27 +- .../authentication_v2/dm_negotiate_process.h | 1 + .../hichain/hichain_auth_connector.h | 2 +- .../src/authentication_v2/auth_manager.cpp | 98 ++++ .../auth_stages/auth_acl.cpp | 91 +++- .../auth_stages/auth_confirm.cpp | 216 +++++++- .../auth_stages/auth_credential.cpp | 86 +++- .../auth_stages/auth_negotiate.cpp | 127 ++++- .../auth_stages/auth_pin_auth.cpp | 18 +- .../dm_auth_manager_base.cpp | 1 + .../dm_auth_message_processor.cpp | 480 +++++++++++++++++- .../src/authentication_v2/dm_auth_state.cpp | 255 +++++++++- .../dm_auth_state_machine.cpp | 3 + .../dm_negotiate_process.cpp | 52 +- .../hichain/hichain_auth_connector.cpp | 32 ++ 23 files changed, 1496 insertions(+), 87 deletions(-) diff --git a/common/include/dm_constants.h b/common/include/dm_constants.h index 0a2645f57..f22d5b97b 100755 --- a/common/include/dm_constants.h +++ b/common/include/dm_constants.h @@ -158,6 +158,11 @@ DM_EXPORT extern const char* PARAM_KEY_HML_ACTIONID; DM_EXPORT extern const char* CONN_SESSION_TYPE_HML; DM_EXPORT extern const char* CONN_SESSION_TYPE_BLE; DM_EXPORT extern const char* UN_BIND_PARAM_UDID_KEY; +DM_EXPORT extern const char* PARAM_KEY_IS_PROXY_BIND; +DM_EXPORT extern const char* PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT; +DM_EXPORT extern const char* PARAM_KEY_SUBJECT_PROXYED_APPS; +DM_EXPORT extern const char* DM_VAL_TRUE; +DM_EXPORT extern const char* DM_VAL_FALSE; // screen state enum ScreenState { diff --git a/common/src/dm_constants.cpp b/common/src/dm_constants.cpp index 9be2b9fb7..221943628 100644 --- a/common/src/dm_constants.cpp +++ b/common/src/dm_constants.cpp @@ -148,6 +148,11 @@ const char* PARAM_KEY_HML_ACTIONID = "hmlActionId"; const char* CONN_SESSION_TYPE_HML = "HML"; const char* CONN_SESSION_TYPE_BLE = "BLE"; const char* UN_BIND_PARAM_UDID_KEY = "udidKey"; +const char* PARAM_KEY_IS_PROXY_BIND = "isProxyBind"; +const char* PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT = "isCallingProxyAsSubject"; +const char* PARAM_KEY_SUBJECT_PROXYED_APPS = "subjectProxyedApps"; +const char* DM_VAL_TRUE = "true"; +const char* DM_VAL_FALSE = "false"; // errCode map const std::map MAP_ERROR_CODE = { diff --git a/commondependency/include/deviceprofile_connector.h b/commondependency/include/deviceprofile_connector.h index 1aa8990e1..f48abb6c6 100644 --- a/commondependency/include/deviceprofile_connector.h +++ b/commondependency/include/deviceprofile_connector.h @@ -254,6 +254,8 @@ public: const std::string &localUdid, int32_t localUserId, const std::string &localAccountId); DM_EXPORT int32_t DeleteSessionKey(int32_t userId, int32_t sessionKeyId); + DM_EXPORT int32_t GetSessionKey(int32_t userId, int32_t sessionKeyId, + std::vector &sessionKeyArray); DM_EXPORT int32_t SubscribeDeviceProfileInited( sptr dpInitedCallback); DM_EXPORT int32_t UnSubscribeDeviceProfileInited(); diff --git a/commondependency/src/deviceprofile_connector.cpp b/commondependency/src/deviceprofile_connector.cpp index aebb45459..076feb1ad 100644 --- a/commondependency/src/deviceprofile_connector.cpp +++ b/commondependency/src/deviceprofile_connector.cpp @@ -2774,6 +2774,18 @@ int32_t DeviceProfileConnector::DeleteSessionKey(int32_t userId, int32_t session return DM_OK; } +int32_t DeviceProfileConnector::GetSessionKey(int32_t userId, int32_t sessionKeyId, + std::vector &sessionKeyArray) +{ + int32_t ret = DistributedDeviceProfileClient::GetInstance().GetSessionKey(static_cast(userId), + sessionKeyId, sessionKeyArray); + if (ret != DM_OK) { + LOGE("failed: %{public}d", ret); + return ret; + } + return DM_OK; +} + bool DeviceProfileConnector::CheckAclStatusNotMatch(const DistributedDeviceProfile::AccessControlProfile &profile, const std::string &localUdid, const std::vector &foregroundUserIds, const std::vector &backgroundUserIds) diff --git a/services/implementation/include/authentication_v2/auth_manager.h b/services/implementation/include/authentication_v2/auth_manager.h index 2767c79b4..8acb6fd5c 100644 --- a/services/implementation/include/authentication_v2/auth_manager.h +++ b/services/implementation/include/authentication_v2/auth_manager.h @@ -133,6 +133,7 @@ protected: void GetRemoteDeviceId(std::string &deviceId); private: void ParseHmlInfoInJsonObject(const JsonObject &jsonObject); + void ParseProxyJsonObject(const JsonObject &jsonObject); void ParseJsonObject(const JsonObject &jsonObject); void GetAuthParam(const std::string &sessionName, int32_t authType, const std::string &deviceId, const std::string &extra); @@ -142,6 +143,7 @@ private: bool IsAuthCodeReady(const std::string &sessionName); int32_t CheckAuthParamVaild(const std::string &sessionName, int32_t authType, const std::string &deviceId, const std::string &extra); + int32_t CheckProxyAuthParamVaild(const std::string &extra); void InitAuthState(const std::string &sessionName, int32_t authType, const std::string &deviceId, const std::string &extra); int32_t AuthenticateDevice(const std::string &sessionName, int32_t authType, diff --git a/services/implementation/include/authentication_v2/dm_auth_context.h b/services/implementation/include/authentication_v2/dm_auth_context.h index faf47baa2..f13357fad 100644 --- a/services/implementation/include/authentication_v2/dm_auth_context.h +++ b/services/implementation/include/authentication_v2/dm_auth_context.h @@ -95,6 +95,51 @@ enum DmUltrasonicInfo { DM_Ultrasonic_Invalid = 2, }; +typedef struct DmProxyAccess { + std::string pkgName; + std::string bundleName; + std::string peerBundleName; + int64_t tokenId; + std::string tokenIdHash; + int32_t bindLevel; + std::string transmitCredentialId; + std::string transmitPublicKey; + std::string publicKey; + int32_t sessionKeyId; + int32_t transmitSessionKeyId; + int64_t transmitSkTimeStamp; + int64_t skTimeStamp; // Used for aging, time is 2 days + bool isAuthed; + std::string aclTypeList; // Trust relationship list, used for data aging, KV format + std::string credTypeList; + std::string aclStrList; + std::map credentialInfos; + std::map aclProfiles; + std::string credInfoJson; + std::string validCredInfoJson; + std::string aclTypeJson; +} DmProxyAccess; + +struct DmProxyAuthContext { + std::string proxyContextId; + std::string customData; + std::string pkgLabel; + bool needBind{true}; + bool needAgreeCredential{true}; + bool needAuth{true}; + DmProxyAccess proxyAccesser; + DmProxyAccess proxyAccessee; + bool operator==(const DmProxyAuthContext &other) const + { + return (proxyContextId == other.proxyContextId); + } + + bool operator<(const DmProxyAuthContext &other) const + { + return proxyContextId < other.proxyContextId; + } +}; + // Used for one-touch pairing struct DmPeerTargetAddress { // directly establish a Bluetooth connection @@ -152,6 +197,7 @@ struct DmAccess { int64_t lnnSkTimeStamp{0}; // Used for aging, time is 2 days, user-level credential timestamp int64_t skTimeStamp; // Used for aging, time is 2 days bool isAuthed; + bool isUserLevelAuthed; bool isOnline; bool isGenerateLnnCredential{true}; bool isPutLnnAcl{true}; @@ -219,6 +265,10 @@ struct DmAuthContext { DmAccess accesser; DmAccess accessee; std::multimap proxy; // Multimap where the key is the accessor and the value is the accesssee + bool IsProxyBind{false}; + bool IsCallingProxyAsSubject{true}; + std::vector subjectProxyApps; + std::string reUseCreId; std::shared_ptr authStateMachine; std::shared_ptr authUiStateMgr; diff --git a/services/implementation/include/authentication_v2/dm_auth_manager_base.h b/services/implementation/include/authentication_v2/dm_auth_manager_base.h index 923379717..01be5c0bd 100644 --- a/services/implementation/include/authentication_v2/dm_auth_manager_base.h +++ b/services/implementation/include/authentication_v2/dm_auth_manager_base.h @@ -56,6 +56,7 @@ extern const char* TAG_TOKENID; extern const char* TAG_HOST_PKGLABEL; extern const char* TAG_REMOTE_DEVICE_NAME; extern const char* TAG_HOST; +extern const char* TAG_PROXY_CONTEXT_ID; extern const char* APP_OPERATION_KEY; extern const char* TARGET_PKG_NAME_KEY; diff --git a/services/implementation/include/authentication_v2/dm_auth_message_processor.h b/services/implementation/include/authentication_v2/dm_auth_message_processor.h index 0183ac559..fa4738ff3 100644 --- a/services/implementation/include/authentication_v2/dm_auth_message_processor.h +++ b/services/implementation/include/authentication_v2/dm_auth_message_processor.h @@ -200,11 +200,15 @@ public: // Save the permanent session key to the data profile int32_t SaveSessionKeyToDP(int32_t userId, int32_t &skId); - + int32_t SaveDerivativeSessionKeyToDP(int32_t userId, const std::string &suffix, int32_t &skId); + int32_t GetSessionKey(int32_t userId, int32_t &skId); // Save the current access control list int32_t PutAccessControlList(std::shared_ptr context, DmAccess &access, std::string trustDeviceId); - + int32_t PutProxyAccessControlList(std::shared_ptr context, + DistributedDeviceProfile::AccessControlProfile &profile, DistributedDeviceProfile::Accesser &accesser, + DistributedDeviceProfile::Accessee &accessee); + void SetAclProxyRelate(std::shared_ptr context); // Extract the access control list (ACL) for message parsing and bus usage. // If no ACL is available, return an empty string. The returned string is in // JSON format: {dmversion:x,accesser:[{accesserDeviceId:y,...},...], accessee:{...}} @@ -217,17 +221,22 @@ private: // Used to encrypt the synchronization message int32_t EncryptSyncMessage(std::shared_ptr &context, DmAccess &accessSide, std::string &encSyncMsg); + int32_t CreateProxyAccessMessage(std::shared_ptr &context, JsonObject &syncMsgJson); // Parse the authentication start message int32_t ParseAuthStartMessage(const JsonObject &jsonObject, std::shared_ptr context); // Parse the 80 message int32_t ParseNegotiateMessage(const JsonObject &jsonObject, std::shared_ptr context); + int32_t ParseProxyNegotiateMessage(const JsonObject &jsonObject, std::shared_ptr context); // Parse the 90 message int32_t ParseMessageRespAclNegotiate(const JsonObject &json, std::shared_ptr context); + int32_t ParseMessageProxyRespAclNegotiate(const JsonObject &jsonObject, std::shared_ptr context); // Parse the 100 message int32_t ParseMessageReqUserConfirm(const JsonObject &json, std::shared_ptr context); + int32_t ParseMessageProxyReqUserConfirm(const JsonObject &json, std::shared_ptr context); // Parse the 110 message int32_t ParseMessageRespUserConfirm(const JsonObject &json, std::shared_ptr context); + int32_t ParseMessageProxyRespUserConfirm(const JsonObject &json, std::shared_ptr context); // Parse the 120 message int32_t ParseMessageReqPinAuthStart(const JsonObject &json, std::shared_ptr context); // Parse the 130 message @@ -262,10 +271,13 @@ private: // Create the 80 message int32_t CreateNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject); + int32_t CreateProxyNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject); // Create the 90 message int32_t CreateRespNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject); + int32_t CreateProxyRespNegotiateMessage(std::shared_ptr context, JsonObject &jsonObject); // Create the 100 message int32_t CreateMessageReqUserConfirm(std::shared_ptr context, JsonObject &json); + int32_t CreateMessageProxyReqUserConfirm(std::shared_ptr context, JsonObject &json); // Create the 110 message int32_t CreateMessageRespUserConfirm(std::shared_ptr context, JsonObject &json); // Create the 120 message @@ -304,6 +316,7 @@ private: // Parse the sync message int32_t ParseSyncMessage(std::shared_ptr &context, DmAccess &access, JsonObject &jsonObject); + int32_t ParseProxyAccessToSync(std::shared_ptr &context, JsonObject &jsonObject); int32_t CreateMessageForwardUltrasonicStart(std::shared_ptr context, JsonObject &jsonObject); int32_t CreateMessageReverseUltrasonicStart(std::shared_ptr context, JsonObject &jsonObject); int32_t CreateMessageForwardUltrasonicNegotiate(std::shared_ptr context, JsonObject &jsonObject); diff --git a/services/implementation/include/authentication_v2/dm_auth_state.h b/services/implementation/include/authentication_v2/dm_auth_state.h index e729ae5dd..e2408432f 100644 --- a/services/implementation/include/authentication_v2/dm_auth_state.h +++ b/services/implementation/include/authentication_v2/dm_auth_state.h @@ -155,6 +155,11 @@ public: void SetAclInfo(std::shared_ptr context); void FilterProfilesByContext(std::vector &profiles, std::shared_ptr context); + void UpdateCredInfo(std::shared_ptr context); + bool IsNeedBind(std::shared_ptr context); + bool GetSessionKey(std::shared_ptr context); + bool IsAclHasCredential(const DistributedDeviceProfile::AccessControlProfile &profile, + const std::string &credInfoJson, std::string &credId); int32_t GetAclBindType(std::shared_ptr context, std::string credId); int32_t GetOutputState(int32_t state); int32_t GetOutputReplay(const std::string &processName, int32_t replay); @@ -165,9 +170,14 @@ protected: bool NeedReqUserConfirm(std::shared_ptr context); bool NeedAgreeCredential(std::shared_ptr context); bool NeedAgreeAcl(std::shared_ptr context); + bool ProxyNeedAgreeAcl(std::shared_ptr context); + bool GetReuseSkId(std::shared_ptr context, int32_t &skId); + void GetReuseACL(std::shared_ptr context, DistributedDeviceProfile::AccessControlProfile &profile); uint32_t GetCredType(std::shared_ptr context, const JsonItemObject &credInfo); + int32_t GetProxyCredInfo(std::shared_ptr context, const JsonItemObject &credInfo, + const std::vector &tokenIdHashList); uint32_t GetCredentialType(std::shared_ptr context, const JsonItemObject &credInfo); - bool HaveSameTokenId(std::shared_ptr context, const std::vector &tokenList); + bool HaveSameTokenId(std::shared_ptr context, const std::vector &tokenIdHashList); void SetProcessInfo(std::shared_ptr context); }; @@ -178,7 +188,9 @@ public: int32_t Action(std::shared_ptr context) override; private: void NegotiateCredential(std::shared_ptr context, JsonObject &credTypeNegoRsult); + void NegotiateProxyCredential(std::shared_ptr context); void NegotiateAcl(std::shared_ptr context, JsonObject &aclNegoRsult); + void NegotiateProxyAcl(std::shared_ptr context); void GetSrcCredentialInfo(std::shared_ptr context, JsonObject &credInfo); void GetIdenticalCredentialInfo(std::shared_ptr context, JsonObject &credInfo); void GetShareCredentialInfo(std::shared_ptr context, JsonObject &credInfo); @@ -186,6 +198,8 @@ private: void GetSrcAclInfo(std::shared_ptr context, JsonObject &credInfo, JsonObject &aclInfo); void GetSrcAclInfoForP2P(std::shared_ptr context, const DistributedDeviceProfile::AccessControlProfile &profile, JsonObject &credInfo, JsonObject &aclInfo); + void GetSrcProxyAclInfoForP2P(std::shared_ptr context, + const DistributedDeviceProfile::AccessControlProfile &profile); bool IdenticalAccountAclCompare(std::shared_ptr context, const DistributedDeviceProfile::Accesser &accesser, const DistributedDeviceProfile::Accessee &accessee); bool ShareAclCompare(std::shared_ptr context, @@ -203,6 +217,7 @@ private: JsonObject &credTypeJson); void GetSrcCredTypeForP2P(std::shared_ptr context, const JsonItemObject &credObj, JsonObject &aclInfo, JsonObject &credTypeJson, int32_t credType, std::vector &deleteCredInfo); + void GetSrcProxyCredTypeForP2P(std::shared_ptr context, std::vector &deleteCredInfo); void GetCustomDescBySinkLanguage(std::shared_ptr context); }; @@ -224,7 +239,9 @@ public: int32_t Action(std::shared_ptr context) override; private: void NegotiateCredential(std::shared_ptr context, JsonObject &credTypeNegoRsult); + void NegotiateProxyCredential(std::shared_ptr context); void NegotiateAcl(std::shared_ptr context, JsonObject &aclNegoRsult); + void NegotiateProxyAcl(std::shared_ptr context); int32_t ShowConfigDialog(std::shared_ptr context); void ReadServiceInfo(std::shared_ptr context); void MatchFallBackCandidateList(std::shared_ptr context, DmAuthType authType); @@ -428,6 +445,8 @@ public: virtual ~AuthSrcCredentialAuthDoneState() {}; DmAuthStateType GetStateType() override; int32_t Action(std::shared_ptr context) override; + int32_t DerivativeSessionKey(std::shared_ptr context); + int32_t DerivativeProxySessionKey(std::shared_ptr context); }; class AuthSinkCredentialAuthStartState : public DmAuthState { @@ -452,6 +471,7 @@ public: private: int32_t RespQueryAcceseeIds(std::shared_ptr context); + int32_t RespQueryProxyAcceseeIds(std::shared_ptr context); int32_t ProcRespNegotiate5_1_0(std::shared_ptr context); void GetSinkCredentialInfo(std::shared_ptr context, JsonObject &credInfo); void GetIdenticalCredentialInfo(std::shared_ptr context, JsonObject &credInfo); @@ -460,6 +480,8 @@ private: void GetSinkAclInfo(std::shared_ptr context, JsonObject &credInfo, JsonObject &aclInfo); void GetSinkAclInfoForP2P(std::shared_ptr context, const DistributedDeviceProfile::AccessControlProfile &profile, JsonObject &credInfo, JsonObject &aclInfo); + void GetSinkProxyAclInfoForP2P(std::shared_ptr context, + const DistributedDeviceProfile::AccessControlProfile &profile); bool IdenticalAccountAclCompare(std::shared_ptr context, const DistributedDeviceProfile::Accesser &accesser, const DistributedDeviceProfile::Accessee &accessee); bool ShareAclCompare(std::shared_ptr context, @@ -477,6 +499,7 @@ private: JsonObject &credTypeJson); void GetSinkCredTypeForP2P(std::shared_ptr context, const JsonItemObject &credObj, JsonObject &aclInfo, JsonObject &credTypeJson, int32_t credType, std::vector &deleteCredInfo); + void GetSinkProxyCredTypeForP2P(std::shared_ptr context, std::vector &deleteCredInfo); }; class AuthSinkDataSyncState : public DmAuthState { @@ -484,6 +507,7 @@ public: virtual ~AuthSinkDataSyncState() {}; DmAuthStateType GetStateType() override; int32_t Action(std::shared_ptr context) override; + int32_t DerivativeSessionKey(std::shared_ptr context); }; class AuthSrcDataSyncState : public DmAuthState { @@ -491,6 +515,7 @@ public: virtual ~AuthSrcDataSyncState() {}; DmAuthStateType GetStateType() override; int32_t Action(std::shared_ptr context) override; + void GetPeerDeviceId(std::shared_ptr context, std::string &peerDeviceId); }; class AuthSinkFinishState : public DmAuthState { diff --git a/services/implementation/include/authentication_v2/dm_negotiate_process.h b/services/implementation/include/authentication_v2/dm_negotiate_process.h index 8a5938d40..6207f5987 100644 --- a/services/implementation/include/authentication_v2/dm_negotiate_process.h +++ b/services/implementation/include/authentication_v2/dm_negotiate_process.h @@ -180,6 +180,7 @@ public: NegotiateProcess(); ~NegotiateProcess(); int32_t HandleNegotiateResult(std::shared_ptr context); + int32_t HandleProxyNegotiateResult(std::shared_ptr context, int32_t result); private: CredType ConvertCredType(const std::string &credType); AclType ConvertAclType(const std::string &aclType); diff --git a/services/implementation/include/dependency/hichain/hichain_auth_connector.h b/services/implementation/include/dependency/hichain/hichain_auth_connector.h index 3a3fe46c6..cfe525463 100644 --- a/services/implementation/include/dependency/hichain/hichain_auth_connector.h +++ b/services/implementation/include/dependency/hichain/hichain_auth_connector.h @@ -75,7 +75,7 @@ public: int32_t AuthCredential(int32_t osAccountId, int64_t authReqId, const std::string &credId, const std::string &pinCode); int32_t AuthCredentialPinCode(int32_t osAccountId, int64_t authReqId, const std::string &pinCode); - + int32_t UpdateCredential(const std::string &credId, int32_t userId, std::vector &tokenIds); private: void FreeJsonString(char *jsonStr); static std::shared_ptr GetDeviceAuthCallback(int64_t id); diff --git a/services/implementation/src/authentication_v2/auth_manager.cpp b/services/implementation/src/authentication_v2/auth_manager.cpp index cf5a594b2..15d7dce91 100644 --- a/services/implementation/src/authentication_v2/auth_manager.cpp +++ b/services/implementation/src/authentication_v2/auth_manager.cpp @@ -47,6 +47,7 @@ constexpr int32_t MIN_PIN_CODE = 100000; constexpr int32_t MAX_PIN_CODE = 999999; constexpr int32_t DM_ULTRASONIC_FORWARD = 0; constexpr int32_t DM_ULTRASONIC_REVERSE = 1; +constexpr uint32_t MAX_PROXY_NUM = 10; int32_t GetCloseSessionDelaySeconds(std::string &delaySecondsStr) { @@ -460,6 +461,7 @@ void AuthManager::ParseJsonObject(const JsonObject &jsonObject) } ParseHmlInfoInJsonObject(jsonObject); + ParseProxyJsonObject(jsonObject); return; } @@ -604,6 +606,11 @@ int32_t AuthManager::AuthenticateDevice(const std::string &pkgName, int32_t auth LOGE("AuthManager::AuthenticateDevice failed, param is invaild."); return ret; } + ret = CheckProxyAuthParamVaild(extra); + if (ret != DM_OK) { + LOGE("CheckProxyAuthParamVaild failed."); + return ret; + } context_->isAuthenticateDevice = true; if (authType == AUTH_TYPE_CRE) { LOGI("AuthManager::AuthenticateDevice for credential type, joinLNN directly."); @@ -1103,5 +1110,96 @@ void AuthManager::DeleteTimer() } LOGI("end."); } + +int32_t AuthManager::CheckProxyAuthParamVaild(const std::string &extra) +{ + LOGI("start."); + JsonObject jsonObject(extra); + if (jsonObject.IsDiscarded() || !IsString(jsonObject, PARAM_KEY_IS_PROXY_BIND)) { + return DM_OK; + } + if (jsonObject[PARAM_KEY_IS_PROXY_BIND].Get() != DM_VAL_TRUE) { + return DM_OK; + } + if (!AppManager::GetInstance().IsSystemSA()) { + LOGE("no proxy permission"); + return ERR_DM_NO_PERMISSION; + } + if (!jsonObject.Contains(PARAM_KEY_SUBJECT_PROXYED_APPS) || + !jsonObject[PARAM_KEY_SUBJECT_PROXYED_APPS].IsArray()) { + LOGE("no subject proxyed apps"); + return ERR_DM_INPUT_PARA_INVALID; + } + std::vector apps = jsonObject[PARAM_KEY_SUBJECT_PROXYED_APPS].Items(); + if (apps.empty()) { + LOGE("apps empty."); + return ERR_DM_INPUT_PARA_INVALID; + } + if (apps.size() > MAX_PROXY_NUM) { + LOGE("apps to many."); + return ERR_DM_INPUT_PARA_INVALID; + } + for (const auto &object : apps) { + if (!object.Contains(TAG_BUNDLE_NAME) || !IsString(object, TAG_BUNDLE_NAME)) { + LOGE("bundleName invalid"); + return ERR_DM_INPUT_PARA_INVALID; + } + if (!object.Contains(TAG_TOKENID) || !IsInt64(object, TAG_TOKENID)) { + LOGE("tokenId invalid"); + return ERR_DM_INPUT_PARA_INVALID; + } + } + return DM_OK; +} + +void AuthManager::ParseProxyJsonObject(const JsonObject &jsonObject) +{ + if (context_ == nullptr || jsonObject.IsDiscarded() || !IsString(jsonObject, PARAM_KEY_IS_PROXY_BIND) || + jsonObject[PARAM_KEY_IS_PROXY_BIND].Get() != DM_VAL_TRUE) { + return; + } + context_->IsProxyBind = true; + if (IsString(jsonObject, PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT) && + jsonObject[PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT].Get() == DM_VAL_FALSE) { + context_->IsCallingProxyAsSubject = false; + } + if (!jsonObject.Contains(PARAM_KEY_SUBJECT_PROXYED_APPS) || + !jsonObject[PARAM_KEY_SUBJECT_PROXYED_APPS].IsArray()) { + LOGE("no subject proxyed apps"); + return; + } + std::vector apps = jsonObject[PARAM_KEY_SUBJECT_PROXYED_APPS].Items(); + if (apps.empty()) { + LOGE("apps empty."); + return; + } + for (const auto &object : apps) { + if (!object.Contains(TAG_BUNDLE_NAME) || !IsString(object, TAG_BUNDLE_NAME)) { + LOGE("bundleName invalid"); + return; + } + if (!object.Contains(TAG_TOKENID) || !IsInt64(object, TAG_TOKENID)) { + LOGE("tokenId invalid"); + return; + } + std::string bundleName = object[TAG_BUNDLE_NAME].Get(); + std::string peerBundleName = bundleName; + if (object.Contains(PARAM_KEY_PEER_BUNDLE_NAME) && IsString(object, PARAM_KEY_PEER_BUNDLE_NAME)) { + peerBundleName = object[PARAM_KEY_PEER_BUNDLE_NAME].Get(); + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = Crypto::Sha256(bundleName + peerBundleName); + if (std::find(context_->subjectProxyApps.begin(), context_->subjectProxyApps.end(), proxyAuthContext) == + context_->subjectProxyApps.end()) { + proxyAuthContext.pkgLabel = GetBundleLabel(bundleName); + proxyAuthContext.proxyAccesser.bundleName = bundleName; + proxyAuthContext.proxyAccesser.tokenId = object[TAG_TOKENID].Get(); + proxyAuthContext.proxyAccesser.tokenIdHash = + Crypto::GetTokenIdHash(std::to_string(proxyAuthContext.proxyAccesser.tokenId)); + proxyAuthContext.proxyAccessee.bundleName = peerBundleName; + context_->subjectProxyApps.push_back(proxyAuthContext); + } + } +} } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp index 73dedccd0..8bb79bbed 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_acl.cpp @@ -38,7 +38,7 @@ int32_t AuthSinkDataSyncState::Action(std::shared_ptr context) // Query the ACL of the sink end. Compare the ACLs at both ends. context->softbusConnector->SyncLocalAclListProcess({context->accessee.deviceId, context->accessee.userId}, {context->accesser.deviceId, context->accesser.userId}, context->accesser.aclStrList); - + DerivativeSessionKey(context); // Synchronize the local SP information, the format is uncertain, not done for now context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_RESP_DATA_SYNC, context); context->accessee.deviceName = context->softbusConnector->GetLocalDeviceName(); @@ -51,11 +51,43 @@ DmAuthStateType AuthSinkDataSyncState::GetStateType() return DmAuthStateType::AUTH_SINK_DATA_SYNC_STATE; } +int32_t AuthSinkDataSyncState::DerivativeSessionKey(std::shared_ptr context) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!GetSessionKey(context)) { + return DM_OK; + } + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return DM_OK; + } + for (auto &app : context->subjectProxyApps) { + if (app.proxyAccessee.isAuthed) { + continue; + } + int32_t skId = 0; + std::string suffix = context->accesser.deviceIdHash + context->accessee.deviceIdHash + + app.proxyAccesser.tokenIdHash + app.proxyAccessee.tokenIdHash; + int32_t ret = + context->authMessageProcessor->SaveDerivativeSessionKeyToDP(context->accessee.userId, suffix, skId); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialAuthDoneState::Action DP save user session key failed"); + return ret; + } + app.proxyAccessee.skTimeStamp = static_cast(DmAuthState::GetSysTimeMs()); + app.proxyAccessee.transmitSessionKeyId = skId; + if (!context->reUseCreId.empty()) { + app.proxyAccessee.transmitCredentialId = context->reUseCreId; + return DM_OK; + } + app.proxyAccessee.transmitCredentialId = context->accesser.transmitCredentialId; + } + return DM_OK; +} + // Received 190 message, sent 200 message int32_t AuthSrcDataSyncState::Action(std::shared_ptr context) { LOGI("AuthSrcDataSyncState::Action start"); - if (NeedAgreeAcl(context)) { // Query the ACL of the sink end. Compare the ACLs at both ends. context->softbusConnector->SyncLocalAclListProcess({context->accesser.deviceId, context->accesser.userId}, @@ -63,18 +95,13 @@ int32_t AuthSrcDataSyncState::Action(std::shared_ptr context) context->accesser.deviceName = context->softbusConnector->GetLocalDeviceName(); // Save this acl SetAclInfo(context); + UpdateCredInfo(context); context->authMessageProcessor->PutAccessControlList(context, context->accesser, context->accessee.deviceId); // Synchronize the local SP information, the format is uncertain, not done for now } std::string peerDeviceId = ""; - peerDeviceId = context->accesser.aclProfiles[DM_IDENTICAL_ACCOUNT].GetAccessee().GetAccesseeDeviceId(); - if (peerDeviceId.empty()) { - peerDeviceId = context->accesser.aclProfiles[DM_SHARE].GetAccessee().GetAccesseeDeviceId(); - } - if (peerDeviceId.empty()) { - peerDeviceId = context->accesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeDeviceId(); - } + GetPeerDeviceId(context, peerDeviceId); bool isNeedJoinLnn = context->softbusConnector->CheckIsNeedJoinLnn(peerDeviceId, context->accessee.addr); // Trigger networking if (!context->accesser.isOnline || isNeedJoinLnn) { @@ -106,6 +133,52 @@ DmAuthStateType AuthSrcDataSyncState::GetStateType() return DmAuthStateType::AUTH_SRC_DATA_SYNC_STATE; } +void AuthSrcDataSyncState::GetPeerDeviceId(std::shared_ptr context, std::string &peerDeviceId) +{ + if (context == nullptr) { + return; + } + if (context->accesser.aclProfiles.find(DM_IDENTICAL_ACCOUNT) != context->accesser.aclProfiles.end()) { + peerDeviceId = context->accesser.aclProfiles[DM_IDENTICAL_ACCOUNT].GetAccessee().GetAccesseeDeviceId(); + if (!peerDeviceId.empty()) { + return; + } + } + if (context->accesser.aclProfiles.find(DM_SHARE) != context->accesser.aclProfiles.end()) { + peerDeviceId = context->accesser.aclProfiles[DM_SHARE].GetAccessee().GetAccesseeDeviceId(); + if (peerDeviceId == context->accesser.deviceId) { + peerDeviceId = context->accesser.aclProfiles[DM_SHARE].GetAccesser().GetAccesserDeviceId(); + } + if (!peerDeviceId.empty()) { + return; + } + } + if (context->accesser.aclProfiles.find(DM_POINT_TO_POINT) != context->accesser.aclProfiles.end()) { + peerDeviceId = context->accesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeDeviceId(); + if (peerDeviceId == context->accesser.deviceId) { + peerDeviceId = context->accesser.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserDeviceId(); + } + if (!peerDeviceId.empty()) { + return; + } + } + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return; + } + for (auto &app : context->subjectProxyApps) { + if (app.proxyAccesser.aclProfiles.find(DM_POINT_TO_POINT) != app.proxyAccesser.aclProfiles.end()) { + peerDeviceId = app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeDeviceId(); + if (peerDeviceId == context->accesser.deviceId) { + peerDeviceId = app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserDeviceId(); + } + if (!peerDeviceId.empty()) { + return; + } + } + } + LOGE("failed"); +} + // Received 200 end message, send 201 int32_t AuthSinkFinishState::Action(std::shared_ptr context) { diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp index f9b71d6eb..63dbbbb28 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_confirm.cpp @@ -83,6 +83,35 @@ void AuthSrcConfirmState::NegotiateCredential(std::shared_ptr con } } +void AuthSrcConfirmState::NegotiateProxyCredential(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind) { + return; + } + if (context->subjectProxyApps.empty()) { + return; + } + for (auto item = context->subjectProxyApps.begin(); item != context->subjectProxyApps.end(); ++item) { + JsonObject credTypeNegoResult; + JsonObject accesseeCredTypeList; + accesseeCredTypeList.Parse(item->proxyAccessee.credTypeList); + JsonObject accesserCredTypeList; + accesserCredTypeList.Parse(item->proxyAccesser.credTypeList); + if (accesseeCredTypeList.IsDiscarded() || accesserCredTypeList.IsDiscarded()) { + item->proxyAccesser.credTypeList = credTypeNegoResult.Dump(); + continue; + } + if (accesseeCredTypeList.Contains("pointTopointCredType") && + accesserCredTypeList.Contains("pointTopointCredType")) { + credTypeNegoResult["pointTopointCredType"] = DM_POINT_TO_POINT; + item->proxyAccesser.credTypeList = credTypeNegoResult.Dump(); + continue; + } + item->proxyAccesser.credTypeList = credTypeNegoResult.Dump(); + } +} + void AuthSrcConfirmState::NegotiateAcl(std::shared_ptr context, JsonObject &aclNegoResult) { CHECK_NULL_VOID(context); @@ -98,12 +127,14 @@ void AuthSrcConfirmState::NegotiateAcl(std::shared_ptr context, J LOGI("have identical acl."); aclNegoResult["identicalAcl"] = DM_IDENTICAL_ACCOUNT; context->accesser.isAuthed = true; + context->accesser.isUserLevelAuthed = true; context->accesser.isPutLnnAcl = false; } if (accesseeAclList.Contains("shareAcl") && accesserAclList.Contains("shareAcl")) { LOGI("have share acl."); aclNegoResult["shareAcl"] = DM_SHARE; context->accesser.isAuthed = true; + context->accesser.isUserLevelAuthed = true; context->accesser.isPutLnnAcl = false; } if (accesseeAclList.Contains("pointTopointAcl") && accesserAclList.Contains("pointTopointAcl")) { @@ -118,6 +149,36 @@ void AuthSrcConfirmState::NegotiateAcl(std::shared_ptr context, J } } +void AuthSrcConfirmState::NegotiateProxyAcl(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind) { + return; + } + if (context->subjectProxyApps.empty()) { + return; + } + for (auto item = context->subjectProxyApps.begin(); item != context->subjectProxyApps.end(); ++item) { + JsonObject aclNegoResult; + JsonObject accesseeAclList; + accesseeAclList.Parse(item->proxyAccessee.aclTypeList); + JsonObject accesserAclList; + accesserAclList.Parse(item->proxyAccesser.aclTypeList); + if (accesseeAclList.IsDiscarded() || accesserAclList.IsDiscarded()) { + item->proxyAccesser.aclTypeList = aclNegoResult.Dump(); + continue; + } + if (accesseeAclList.Contains("pointTopointAcl") && accesserAclList.Contains("pointTopointAcl")) { + LOGI("have point_to_point acl bundleName: %{public}s.", item->proxyAccesser.bundleName.c_str()); + aclNegoResult["pointTopointAcl"] = DM_POINT_TO_POINT; + item->proxyAccesser.aclTypeList = aclNegoResult.Dump(); + item->proxyAccesser.isAuthed = true; + continue; + } + item->proxyAccesser.aclTypeList = aclNegoResult.Dump(); + } +} + void AuthSrcConfirmState::GetSrcCredType(std::shared_ptr context, JsonObject &credInfo, JsonObject &aclInfo, JsonObject &credTypeJson) { @@ -160,6 +221,7 @@ void AuthSrcConfirmState::GetSrcCredType(std::shared_ptr context, break; } } + GetSrcProxyCredTypeForP2P(context, deleteCredInfo); for (const auto &item : deleteCredInfo) { credInfo.Erase(item); context->hiChainAuthConnector->DeleteCredential(context->accesser.userId, item); @@ -182,6 +244,47 @@ void AuthSrcConfirmState::GetSrcCredTypeForP2P(std::shared_ptr co } } +void AuthSrcConfirmState::GetSrcProxyCredTypeForP2P(std::shared_ptr context, + std::vector &deleteCredInfo) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind) { + return; + } + if (context->subjectProxyApps.empty()) { + return; + } + for (auto item = context->subjectProxyApps.begin(); item != context->subjectProxyApps.end(); ++item) { + JsonObject credInfoJson(item->proxyAccesser.credInfoJson); + for (const auto &credItem : credInfoJson.Items()) { + if (!credItem.Contains(FILED_CRED_TYPE) || !credItem[FILED_CRED_TYPE].IsNumberInteger() || + !credItem.Contains(FILED_CRED_ID) || !credItem[FILED_CRED_ID].IsString()) { + deleteCredInfo.push_back(credItem[FILED_CRED_ID].Get()); + continue; + } + int32_t credType = credItem[FILED_CRED_TYPE].Get(); + if (credType != static_cast(DM_POINT_TO_POINT)) { + continue; + } + std::string credId = credItem[FILED_CRED_ID].Get(); + JsonObject aclTypeJson(item->proxyAccesser.aclTypeJson); + if (!aclTypeJson.Contains("pointTopointAcl") || + item->proxyAccesser.aclProfiles.find(DM_POINT_TO_POINT) == item->proxyAccesser.aclProfiles.end() || + (item->proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr() != + credItem[FILED_CRED_ID].Get() && + item->proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr() != + credItem[FILED_CRED_ID].Get())) { + deleteCredInfo.push_back(credItem[FILED_CRED_ID].Get()); + } else { + JsonObject validCredInfoJson(item->proxyAccesser.validCredInfoJson); + validCredInfoJson["pointTopointCredType"] = credType; + item->proxyAccesser.validCredInfoJson = validCredInfoJson.Dump(); + item->proxyAccesser.credentialInfos[credType] = credItem.Dump(); + } + } + } +} + void AuthSrcConfirmState::GetSrcAclInfo(std::shared_ptr context, JsonObject &credInfo, JsonObject &aclInfo) { @@ -242,6 +345,46 @@ void AuthSrcConfirmState::GetSrcAclInfoForP2P(std::shared_ptr con aclInfo["lnnAcl"] = DM_LNN; context->accesser.aclProfiles[DM_LNN] = profile; } + GetSrcProxyAclInfoForP2P(context, profile); +} + +void AuthSrcConfirmState::GetSrcProxyAclInfoForP2P(std::shared_ptr context, + const DistributedDeviceProfile::AccessControlProfile &profile) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return; + } + for (auto &app : context->subjectProxyApps) { + if ((profile.GetAccesser().GetAccesserTokenId() == app.proxyAccesser.tokenId && + Crypto::GetTokenIdHash(std::to_string(profile.GetAccessee().GetAccesseeTokenId())) == + app.proxyAccessee.tokenIdHash) || + (profile.GetAccessee().GetAccesseeTokenId() == app.proxyAccesser.tokenId && + Crypto::GetTokenIdHash(std::to_string(profile.GetAccesser().GetAccesserTokenId())) == + app.proxyAccessee.tokenIdHash)) { + std::string credId; + if (!IsAclHasCredential(profile, app.proxyAccesser.credInfoJson, credId)) { + DeleteAcl(context, profile); + return; + } + std::vector appList; + JsonObject credInfoJsonObj(app.proxyAccesser.credInfoJson); + credInfoJsonObj[credId][FILED_AUTHORIZED_APP_LIST].Get(appList); + const size_t APP_LIST_SIZE = 2; + if (appList.size() >= APP_LIST_SIZE && + std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccesser().GetAccesserTokenId())) + != appList.end() && + std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccessee().GetAccesseeTokenId())) + != appList.end()) { + JsonObject aclTypeJson(app.proxyAccesser.aclTypeJson); + aclTypeJson["pointTopointAcl"] = DM_POINT_TO_POINT; + app.proxyAccesser.aclTypeJson = aclTypeJson.Dump(); + app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT] = profile; + } else { + DeleteAcl(context, profile); + } + } + } } bool AuthSrcConfirmState::CheckCredIdInAcl(std::shared_ptr context, @@ -457,11 +600,12 @@ int32_t AuthSrcConfirmState::Action(std::shared_ptr context) JsonObject credTypeNegoResult; NegotiateCredential(context, credTypeNegoResult); context->accesser.credTypeList = credTypeNegoResult.Dump(); + NegotiateProxyCredential(context); // update acl negotiate result JsonObject aclNegoResult; NegotiateAcl(context, aclNegoResult); context->accesser.aclTypeList = aclNegoResult.Dump(); - + NegotiateProxyAcl(context); context->authMessageProcessor->CreateAndSendMsg(MSG_TYPE_REQ_USER_CONFIRM, context); context->listener->OnAuthResult(context->processInfo, context->peerTargetId.deviceId, context->accessee.tokenIdHash, static_cast(STATUS_DM_SHOW_AUTHORIZE_UI), DM_OK); @@ -568,6 +712,35 @@ void AuthSinkConfirmState::NegotiateCredential(std::shared_ptr co return; } +void AuthSinkConfirmState::NegotiateProxyCredential(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind) { + return; + } + if (context->subjectProxyApps.empty()) { + return; + } + for (auto item = context->subjectProxyApps.begin(); item != context->subjectProxyApps.end(); ++item) { + JsonObject credTypeNegoResult; + JsonObject accesseeCredTypeList; + accesseeCredTypeList.Parse(item->proxyAccessee.credTypeList); + JsonObject accesserCredTypeList; + accesserCredTypeList.Parse(item->proxyAccesser.credTypeList); + if (accesseeCredTypeList.IsDiscarded() || accesserCredTypeList.IsDiscarded()) { + item->proxyAccessee.credTypeList = credTypeNegoResult.Dump(); + continue; + } + if (accesseeCredTypeList.Contains("pointTopointCredType") && + accesserCredTypeList.Contains("pointTopointCredType")) { + credTypeNegoResult["pointTopointCredType"] = DM_POINT_TO_POINT; + item->proxyAccessee.credTypeList = credTypeNegoResult.Dump(); + continue; + } + item->proxyAccessee.credTypeList = credTypeNegoResult.Dump(); + } +} + void AuthSinkConfirmState::NegotiateAcl(std::shared_ptr context, JsonObject &aclNegoResult) { CHECK_NULL_VOID(context); @@ -584,12 +757,14 @@ void AuthSinkConfirmState::NegotiateAcl(std::shared_ptr context, aclNegoResult["identicalAcl"] = DM_IDENTICAL_ACCOUNT; context->accessee.isPutLnnAcl = false; context->accessee.isAuthed = true; + context->accessee.isUserLevelAuthed = true; } if (accesseeAclList.Contains("shareCredType") && accesserAclList.Contains("shareCredType")) { LOGI("have share acl."); aclNegoResult["shareAcl"] = DM_SHARE; context->accessee.isPutLnnAcl = false; context->accessee.isAuthed = true; + context->accessee.isUserLevelAuthed = true; } if (accesseeAclList.Contains("pointTopointAcl") && accesserAclList.Contains("pointTopointAcl")) { LOGI("have point_to_point acl."); @@ -603,6 +778,36 @@ void AuthSinkConfirmState::NegotiateAcl(std::shared_ptr context, } } +void AuthSinkConfirmState::NegotiateProxyAcl(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind) { + return; + } + if (context->subjectProxyApps.empty()) { + return; + } + for (auto item = context->subjectProxyApps.begin(); item != context->subjectProxyApps.end(); ++item) { + JsonObject aclNegoResult; + JsonObject accesseeAclList; + accesseeAclList.Parse(item->proxyAccessee.aclTypeList); + JsonObject accesserAclList; + accesserAclList.Parse(item->proxyAccesser.aclTypeList); + if (accesseeAclList.IsDiscarded() || accesserAclList.IsDiscarded()) { + item->proxyAccessee.aclTypeList = aclNegoResult.Dump(); + continue; + } + if (accesseeAclList.Contains("pointTopointAcl") && accesserAclList.Contains("pointTopointAcl")) { + LOGI("have point_to_point acl bundleName: %{public}s.", item->proxyAccesser.bundleName.c_str()); + aclNegoResult["pointTopointAcl"] = DM_POINT_TO_POINT; + item->proxyAccessee.aclTypeList = aclNegoResult.Dump(); + item->proxyAccessee.isAuthed = true; + continue; + } + item->proxyAccessee.aclTypeList = aclNegoResult.Dump(); + } +} + void AuthSinkConfirmState::MatchFallBackCandidateList( std::shared_ptr context, DmAuthType authType) { @@ -669,8 +874,10 @@ int32_t AuthSinkConfirmState::Action(std::shared_ptr context) JsonObject aclNegoResult; NegotiateCredential(context, credTypeNegoResult); context->accessee.credTypeList = credTypeNegoResult.Dump(); + NegotiateProxyCredential(context); NegotiateAcl(context, aclNegoResult); context->accessee.aclTypeList = aclNegoResult.Dump(); + NegotiateProxyAcl(context); if (credTypeNegoResult.Dump() != context->accesser.credTypeList || aclNegoResult.Dump() != context->accesser.aclTypeList) { LOGE("compability negotiate not match."); @@ -679,11 +886,14 @@ int32_t AuthSinkConfirmState::Action(std::shared_ptr context) } int32_t ret = NegotiateProcess::GetInstance().HandleNegotiateResult(context); if (ret != DM_OK) { + if (ret == ERR_DM_BIND_TRUST_TARGET) { + context->authMessageProcessor->SetAclProxyRelate(context); + } LOGE("HandleNegotiateResult failed ret %{public}d.", ret); - context->reason = ERR_DM_CAPABILITY_NEGOTIATE_FAILED; + context->reason = ret; return ret; } - if (context->needBind) { + if (IsNeedBind(context)) { return ProcessBindAuthorize(context); } else { return ProcessNoBindAuthorize(context); diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp index a483b4ad8..1f951ba65 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_credential.cpp @@ -110,6 +110,10 @@ DmAuthStateType AuthSrcCredentialAuthDoneState::GetStateType() int32_t AuthSrcCredentialAuthDoneState::Action(std::shared_ptr context) { + if (GetSessionKey(context)) { + DerivativeSessionKey(context); + return DM_OK; + } // decrypt and transmit transmitData int32_t ret = g_authCredentialTransmitDecryptProcess(context, ON_SESSION_KEY_RETURNED); if (ret != DM_OK) { @@ -122,18 +126,11 @@ int32_t AuthSrcCredentialAuthDoneState::Action(std::shared_ptr co return ERR_DM_FAILED; } DmMessageType msgType; - int32_t skId; - ret = context->authMessageProcessor->SaveSessionKeyToDP(context->accesser.userId, skId); - if (ret != DM_OK) { - LOGE("AuthSrcCredentialAuthDoneState::Action DP save user session key failed"); - return ret; - } // first time joinLnn, auth lnnCredential if (context->accesser.isGenerateLnnCredential == true && context->isAppCredentialVerified == false && context->accesser.bindLevel != USER) { context->isAppCredentialVerified = true; - SetAuthContext(skId, context->accesser.transmitSkTimeStamp, context->accesser.transmitSessionKeyId); msgType = MSG_TYPE_REQ_CREDENTIAL_AUTH_START; ret = context->hiChainAuthConnector->AuthCredential(context->accesser.userId, context->requestId, context->accesser.lnnCredentialId, std::string("")); @@ -149,12 +146,18 @@ int32_t AuthSrcCredentialAuthDoneState::Action(std::shared_ptr co } // First-time authentication and Lnn credential process } else if (context->accesser.isGenerateLnnCredential == true && context->accesser.bindLevel != USER) { + int32_t skId = 0; + int32_t ret = context->authMessageProcessor->SaveSessionKeyToDP(context->accesser.userId, skId); + if (ret != DM_OK) { + LOGE("DP save user session key failed"); + return false; + } SetAuthContext(skId, context->accesser.lnnSkTimeStamp, context->accesser.lnnSessionKeyId); msgType = MSG_TYPE_REQ_DATA_SYNC; } else { // Non-first-time authentication transport credential process - SetAuthContext(skId, context->accesser.transmitSkTimeStamp, context->accesser.transmitSessionKeyId); msgType = MSG_TYPE_REQ_DATA_SYNC; } + DerivativeSessionKey(context); std::string message = context->authMessageProcessor->CreateMessage(msgType, context); if (message.empty()) { @@ -165,6 +168,65 @@ int32_t AuthSrcCredentialAuthDoneState::Action(std::shared_ptr co return context->softbusConnector->GetSoftbusSession()->SendData(context->sessionId, message); } +int32_t AuthSrcCredentialAuthDoneState::DerivativeSessionKey(std::shared_ptr context) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + int32_t skId = 0; + int32_t ret = context->authMessageProcessor->SaveSessionKeyToDP(context->accesser.userId, skId); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialAuthDoneState::Action DP save user session key failed"); + return ret; + } + SetAuthContext(skId, context->accesser.transmitSkTimeStamp, context->accesser.transmitSessionKeyId); + return DM_OK; + } + return DerivativeProxySessionKey(context); +} + +int32_t AuthSrcCredentialAuthDoneState::DerivativeProxySessionKey(std::shared_ptr context) +{ + if (context->IsCallingProxyAsSubject) { + if (!context->accesser.isAuthed) { + int32_t skId = 0; + std::string suffix = context->accesser.deviceIdHash + context->accessee.deviceIdHash + + context->accesser.tokenIdHash + context->accessee.tokenIdHash; + int32_t ret = + context->authMessageProcessor->SaveDerivativeSessionKeyToDP(context->accesser.userId, suffix, skId); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialAuthDoneState::Action DP save user session key failed"); + return ret; + } + if (!context->reUseCreId.empty()) { + context->accesser.transmitCredentialId = context->reUseCreId; + } + SetAuthContext(skId, context->accesser.transmitSkTimeStamp, context->accesser.transmitSessionKeyId); + } + } + for (auto &app : context->subjectProxyApps) { + if (app.proxyAccesser.isAuthed) { + continue; + } + int32_t skId = 0; + std::string suffix = context->accesser.deviceIdHash + context->accessee.deviceIdHash + + app.proxyAccesser.tokenIdHash + app.proxyAccessee.tokenIdHash; + int32_t ret = + context->authMessageProcessor->SaveDerivativeSessionKeyToDP(context->accesser.userId, suffix, skId); + if (ret != DM_OK) { + LOGE("AuthSrcCredentialAuthDoneState::Action DP save user session key failed"); + return ret; + } + app.proxyAccesser.skTimeStamp = static_cast(DmAuthState::GetSysTimeMs()); + app.proxyAccesser.transmitSessionKeyId = skId; + if (!context->reUseCreId.empty()) { + app.proxyAccesser.transmitCredentialId = context->reUseCreId; + return DM_OK; + } + app.proxyAccesser.transmitCredentialId = context->accesser.transmitCredentialId; + } + return DM_OK; +} + DmAuthStateType AuthSinkCredentialAuthStartState::GetStateType() { return DmAuthStateType::AUTH_SINK_CREDENTIAL_AUTH_START_STATE; @@ -366,17 +428,20 @@ int32_t AuthSrcCredentialExchangeState::Action(std::shared_ptr co LOGI("AuthSrcCredentialExchangeState::Action() start."); int32_t ret = ERR_DM_FAILED; context->isAppCredentialVerified = false; - if (!NeedAgreeAcl(context)) { + context->authMessageProcessor->SetAclProxyRelate(context); context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } + if (GetSessionKey(context)) { + context->authStateMachine->TransitionTo(std::make_shared()); + return DM_OK; + } if (!NeedAgreeCredential(context)) { context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } - // First authentication, generate LNN credentials and public key if (context->accesser.isGenerateLnnCredential && context->accesser.bindLevel != USER) { ret = GenerateCredIdAndPublicKey(DM_AUTH_SCOPE_LNN, context); @@ -417,7 +482,6 @@ int32_t AuthSinkCredentialExchangeState::Action(std::shared_ptr c std::string tmpCredId; int32_t osAccountId = context->accessee.userId; context->isAppCredentialVerified = false; - if (context == nullptr || context->hiChainAuthConnector == nullptr || context->authMessageProcessor == nullptr || context->softbusConnector == nullptr) { return ret; diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp index 0639821f5..eb1ec2f13 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp @@ -151,7 +151,7 @@ int32_t AuthSinkNegotiateStateMachine::RespQueryAcceseeIds(std::shared_ptraccessee.bundleName.c_str()); return ERR_DM_GET_TOKENID_FAILED; } - if (AuthManagerBase::CheckProcessNameInWhiteList(context->accessee.bundleName)) { + if (!context->IsProxyBind && AuthManagerBase::CheckProcessNameInWhiteList(context->accessee.bundleName)) { context->accessee.bindLevel = DmRole::DM_ROLE_USER; } context->accessee.tokenIdHash = Crypto::GetTokenIdHash(std::to_string(context->accessee.tokenId)); @@ -160,6 +160,30 @@ int32_t AuthSinkNegotiateStateMachine::RespQueryAcceseeIds(std::shared_ptraccessee.deviceName = context->listener->GetLocalDisplayDeviceNameForPrivacy(); context->accessee.networkId = context->softbusConnector->GetLocalDeviceNetworkId(); context->accessee.deviceType = context->softbusConnector->GetLocalDeviceTypeId(); + return RespQueryProxyAcceseeIds(context); +} + +int32_t AuthSinkNegotiateStateMachine::RespQueryProxyAcceseeIds(std::shared_ptr context) +{ + if (!context->IsProxyBind) { + return DM_OK; + } + if (context->subjectProxyApps.empty()) { + return ERR_DM_INPUT_PARA_INVALID; + } + for (auto item = context->subjectProxyApps.begin(); item != context->subjectProxyApps.end(); ++item) { + if (AppManager::GetInstance().GetNativeTokenIdByName(item->proxyAccessee.bundleName, + item->proxyAccessee.tokenId) == DM_OK) { + item->proxyAccessee.bindLevel = DmRole::DM_ROLE_SA; + } else if (AppManager::GetInstance().GetHapTokenIdByName(context->accessee.userId, + item->proxyAccessee.bundleName, 0, item->proxyAccessee.tokenId) == DM_OK) { + item->proxyAccessee.bindLevel = DmRole::DM_ROLE_FA; + } else { + LOGE("sink not contain the bundlename %{public}s.", item->proxyAccessee.bundleName.c_str()); + return ERR_DM_GET_TOKENID_FAILED; + } + item->proxyAccessee.tokenIdHash = Crypto::GetTokenIdHash(std::to_string(item->proxyAccessee.tokenId)); + } return DM_OK; } @@ -311,10 +335,11 @@ void AuthSinkNegotiateStateMachine::GetSinkCredType(std::shared_ptrhiChainAuthConnector->DeleteCredential(context->accessee.userId, item); - } + GetSinkProxyCredTypeForP2P(context, deleteCredInfo); + for (const auto &item : deleteCredInfo) { + credInfo.Erase(item); + context->hiChainAuthConnector->DeleteCredential(context->accessee.userId, item); + } } void AuthSinkNegotiateStateMachine::GetSinkCredTypeForP2P(std::shared_ptr context, @@ -334,6 +359,47 @@ void AuthSinkNegotiateStateMachine::GetSinkCredTypeForP2P(std::shared_ptr context, + std::vector &deleteCredInfo) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind) { + return; + } + if (context->subjectProxyApps.empty()) { + return; + } + for (auto item = context->subjectProxyApps.begin(); item != context->subjectProxyApps.end(); ++item) { + JsonObject credInfoJson(item->proxyAccessee.credInfoJson); + for (const auto &credItem : credInfoJson.Items()) { + if (!credItem.Contains(FILED_CRED_TYPE) || !credItem[FILED_CRED_TYPE].IsNumberInteger() || + !credItem.Contains(FILED_CRED_ID) || !credItem[FILED_CRED_ID].IsString()) { + deleteCredInfo.push_back(credItem[FILED_CRED_ID].Get()); + continue; + } + int32_t credType = credItem[FILED_CRED_TYPE].Get(); + if (credType != static_cast(DM_POINT_TO_POINT)) { + continue; + } + std::string credId = credItem[FILED_CRED_ID].Get(); + JsonObject aclTypeJson(item->proxyAccessee.aclTypeJson); + if (!aclTypeJson.Contains("pointTopointAcl") || + item->proxyAccessee.aclProfiles.find(DM_POINT_TO_POINT) == item->proxyAccessee.aclProfiles.end() || + (item->proxyAccessee.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr() != + credItem[FILED_CRED_ID].Get() && + item->proxyAccessee.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr() != + credItem[FILED_CRED_ID].Get())) { + deleteCredInfo.push_back(credItem[FILED_CRED_ID].Get()); + } else { + JsonObject validCredInfoJson(item->proxyAccessee.validCredInfoJson); + validCredInfoJson["pointTopointCredType"] = credType; + item->proxyAccessee.validCredInfoJson = validCredInfoJson.Dump(); + item->proxyAccessee.credentialInfos[credType] = credItem.Dump(); + } + } + } +} + void AuthSinkNegotiateStateMachine::GetSinkAclInfo(std::shared_ptr context, JsonObject &credInfo, JsonObject &aclInfo) { @@ -394,6 +460,49 @@ void AuthSinkNegotiateStateMachine::GetSinkAclInfoForP2P(std::shared_ptraccessee.aclProfiles[DM_LNN] = profile; } + GetSinkProxyAclInfoForP2P(context, profile); +} + +void AuthSinkNegotiateStateMachine::GetSinkProxyAclInfoForP2P(std::shared_ptr context, + const DistributedDeviceProfile::AccessControlProfile &profile) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind) { + return; + } + if (context->subjectProxyApps.empty()) { + return; + } + for (auto &app : context->subjectProxyApps) { + if ((profile.GetAccessee().GetAccesseeTokenId() == app.proxyAccessee.tokenId && + Crypto::GetTokenIdHash(std::to_string(profile.GetAccesser().GetAccesserTokenId())) == + app.proxyAccesser.tokenIdHash) || + (profile.GetAccesser().GetAccesserTokenId() == app.proxyAccessee.tokenId && + Crypto::GetTokenIdHash(std::to_string(profile.GetAccessee().GetAccesseeTokenId())) == + app.proxyAccesser.tokenIdHash)) { + std::string credId; + if (!IsAclHasCredential(profile, app.proxyAccessee.credInfoJson, credId)) { + DeleteAcl(context, profile); + return; + } + std::vector appList; + JsonObject credInfoJsonObj(app.proxyAccessee.credInfoJson); + credInfoJsonObj[credId][FILED_AUTHORIZED_APP_LIST].Get(appList); + const size_t APP_LIST_SIZE = 2; + if (appList.size() >= APP_LIST_SIZE && + std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccesser().GetAccesserTokenId())) + != appList.end() && + std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccessee().GetAccesseeTokenId())) + != appList.end()) { + JsonObject aclTypeJson(app.proxyAccessee.aclTypeJson); + aclTypeJson["pointTopointAcl"] = DM_POINT_TO_POINT; + app.proxyAccessee.aclTypeJson = aclTypeJson.Dump(); + app.proxyAccessee.aclProfiles[DM_POINT_TO_POINT] = profile; + } else { + DeleteAcl(context, profile); + } + } + } } bool AuthSinkNegotiateStateMachine::CheckCredIdInAcl(std::shared_ptr context, @@ -445,10 +554,10 @@ void AuthSinkNegotiateStateMachine::CheckCredIdInAclForP2P(std::shared_ptr= APP_LIST_SIZE && - ((std::to_string(profile.GetAccesser().GetAccesserTokenId()) == appList[0] && - std::to_string(profile.GetAccessee().GetAccesseeTokenId()) == appList[1]) || - (std::to_string(profile.GetAccessee().GetAccesseeTokenId()) == appList[0] && - std::to_string(profile.GetAccesser().GetAccesserTokenId()) == appList[1]))) { + std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccesser().GetAccesserTokenId())) + != appList.end() && + std::find(appList.begin(), appList.end(), std::to_string(profile.GetAccessee().GetAccesseeTokenId())) + != appList.end()) { checkResult = true; } else { DeleteAcl(context, profile); diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp index 913e6cd11..2c98e35d6 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_pin_auth.cpp @@ -115,7 +115,7 @@ bool AuthSinkStatePinAuthComm::IsAuthCodeReady(std::shared_ptr co return false; } if (context->pkgName != context->importPkgName) { - LOGE("AuthSinkNegotiateStateMachine::IsAuthCodeReady pkgName %{public}s not supported with " + LOGE("AuthSinkStatePinAuthComm::IsAuthCodeReady pkgName %{public}s not supported with " "import pkgName %{public}s.", context->pkgName.c_str(), context->importPkgName.c_str()); return false; } @@ -264,6 +264,10 @@ int32_t AuthSinkPinAuthMsgNegotiateState::Action(std::shared_ptr retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_SESSION_KEY_RETURNED); if (retEvent == DmEventType::ON_SESSION_KEY_RETURNED) { + if (!NeedAgreeAcl(context)) { + context->authMessageProcessor->SetAclProxyRelate(context); + return DM_OK; + } retEvent = context->authStateMachine->WaitExpectEvent(DmEventType::ON_FINISH); if (retEvent == DmEventType::ON_FINISH || retEvent == DmEventType::ON_ERROR) { context->authStateMachine->TransitionTo(std::make_shared()); @@ -273,7 +277,6 @@ int32_t AuthSinkPinAuthMsgNegotiateState::Action(std::shared_ptr LOGI("AuthSinkPinAuthMsgNegotiateState::AuthDevice WAIT ON_SESSION_KEY_RETURNED ON_ERROR failed, maybe retry."); return DM_OK; } - LOGE("AuthSinkPinAuthMsgNegotiateState::AuthDevice failed."); return STOP_BIND; } @@ -394,18 +397,21 @@ int32_t AuthSrcPinNegotiateStartState::Action(std::shared_ptr con if (!context->pinNegotiateStarted) { int32_t ret = NegotiateProcess::GetInstance().HandleNegotiateResult(context); if (ret != DM_OK) { + if (ret == ERR_DM_BIND_TRUST_TARGET) { + context->authMessageProcessor->SetAclProxyRelate(context); + } LOGE("HandleNegotiateResult failed ret %{public}d", ret); - context->reason = ERR_DM_CAPABILITY_NEGOTIATE_FAILED; + context->reason = ret; return ret; } } - if (!context->needBind && !context->needAgreeCredential && context->needAuth) { + if (!IsNeedBind(context) && !context->needAgreeCredential && context->needAuth) { return ProcessCredAuth(context); } - if (context->needBind) { + if (IsNeedBind(context)) { return ProcessPinBind(context); } - if (!context->needBind && !context->needAgreeCredential && !context->needAuth) { + if (!IsNeedBind(context) && !context->needAgreeCredential && !context->needAuth) { context->reason = ERR_DM_BIND_TRUST_TARGET; context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; diff --git a/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp b/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp index f2d4fd466..80d4aca64 100644 --- a/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp @@ -57,6 +57,7 @@ const char* TAG_TOKENID = "tokenId"; const char* TAG_HOST_PKGLABEL = "hostPkgLabel"; const char* TAG_REMOTE_DEVICE_NAME = "REMOTE_DEVICE_NAME"; const char* TAG_HOST = "HOST"; +const char* TAG_PROXY_CONTEXT_ID = "proxyContextId"; const char* APP_OPERATION_KEY = "appOperation"; const char* TARGET_PKG_NAME_KEY = "targetPkgName"; diff --git a/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp b/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp index 043302bf8..7498e0f86 100644 --- a/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp @@ -107,6 +107,7 @@ constexpr const int32_t DM_HASH_LEN = 32; const char* TAG_DEVICE_TYPE = "DEVICETYPE"; constexpr int32_t DM_ULTRASONIC_FORWARD = 0; constexpr int32_t DM_ULTRASONIC_REVERSE = 1; +constexpr uint32_t MAX_SESSION_KEY_LENGTH = 512; void ParseDmAccessToSync(const std::string &jsonString, DmAccess &access, bool isUseDeviceFullName) { @@ -193,7 +194,6 @@ bool IsMessageValid(const JsonItemObject &jsonObject) } return true; } - } int32_t DmAuthMessageProcessor::SaveSessionKey(const uint8_t *sessionKey, const uint32_t keyLen) @@ -214,6 +214,60 @@ int32_t DmAuthMessageProcessor::SaveSessionKeyToDP(int32_t userId, int32_t &skId return DeviceProfileConnector::GetInstance().PutSessionKey(userId, cryptoMgr_->GetSessionKey(), skId); } +int32_t DmAuthMessageProcessor::SaveDerivativeSessionKeyToDP(int32_t userId, const std::string &suffix, int32_t &skId) +{ + if (cryptoMgr_ == nullptr) { + LOGE("DmAuthMessageProcessor::SaveSessionKeyToDP failed, cryptoMgr_ is nullptr."); + return ERR_DM_FAILED; + } + std::vector sessionKey = cryptoMgr_->GetSessionKey(); + size_t keyLen = sessionKey.size(); + std::string keyStr(reinterpret_cast(sessionKey.data())); + std::string newKeyStr = Crypto::Sha256(keyStr + suffix); + DMSessionKey newSessionKey; + size_t newKeyLen = std::min(keyLen, newKeyStr.size()); + if (newKeyLen == 0 || newKeyLen > MAX_SESSION_KEY_LENGTH) { + LOGE("newKeyLen invaild, cannot allocate memory."); + return ERR_DM_FAILED; + } + newSessionKey.key = (uint8_t*)calloc(newKeyLen, sizeof(uint8_t)); + if (memcpy_s(newSessionKey.key, newKeyLen, newKeyStr.c_str(), newKeyLen) != DM_OK) { + LOGE("copy key data failed."); + if (newSessionKey.key != nullptr) { + (void)memset_s(newSessionKey.key, newSessionKey.keyLen, 0, newSessionKey.keyLen); + free(newSessionKey.key); + newSessionKey.key = nullptr; + newSessionKey.keyLen = 0; + } + return ERR_DM_FAILED; + } + newSessionKey.keyLen = newKeyLen; + int ret = DeviceProfileConnector::GetInstance().PutSessionKey(userId, + std::vector(newSessionKey.key, newSessionKey.key + newSessionKey.keyLen), skId); + if (newSessionKey.key != nullptr) { + (void)memset_s(newSessionKey.key, newSessionKey.keyLen, 0, newSessionKey.keyLen); + free(newSessionKey.key); + newSessionKey.key = nullptr; + newSessionKey.keyLen = 0; + } + return ret; +} + +int32_t DmAuthMessageProcessor::GetSessionKey(int32_t userId, int32_t &skId) +{ + std::vector sessionKey; + int32_t ret = DeviceProfileConnector::GetInstance().GetSessionKey(userId, skId, sessionKey); + if (ret != DM_OK) { + LOGE("failed: %{public}d", ret); + return ret; + } + if (cryptoMgr_ == nullptr) { + LOGE("failed, cryptoMgr_ is nullptr."); + return ERR_DM_FAILED; + } + return cryptoMgr_->ProcessSessionKey(sessionKey.data(), sessionKey.size()); +} + int32_t DmAuthMessageProcessor::DeleteSessionKeyToDP(int32_t userId, int32_t skId) { return DeviceProfileConnector::GetInstance().DeleteSessionKey(userId, skId); @@ -307,21 +361,79 @@ int32_t DmAuthMessageProcessor::PutAccessControlList(std::shared_ptrdirection == DM_AUTH_SOURCE ? context->accesser.isAuthed : context->accessee.isAuthed; + if (!context->IsProxyBind || context->subjectProxyApps.empty() || (context->IsCallingProxyAsSubject && !isAuthed)) { + std::string isLnnAclFalse = std::string(ACL_IS_LNN_ACL_VAL_FALSE); + extraData[ACL_IS_LNN_ACL_KEY] = isLnnAclFalse; + profile.SetExtraData(extraData.Dump()); + profile.SetBindLevel(access.bindLevel); + SetTransmitAccessControlList(context, accesser, accessee); + profile.SetBindLevel(access.bindLevel); + profile.SetBindType(access.transmitBindType); + profile.SetAccessee(accessee); + profile.SetAccesser(accesser); + int32_t ret = + DistributedDeviceProfile::DistributedDeviceProfileClient::GetInstance().PutAccessControlProfile(profile); + if (ret != DM_OK) { + LOGE("PutAccessControlProfile failed."); + } + return ret; } - return ret; + return PutProxyAccessControlList(context, profile, accesser, accessee); +} + +int32_t DmAuthMessageProcessor::PutProxyAccessControlList(std::shared_ptr context, + DistributedDeviceProfile::AccessControlProfile &profile, DistributedDeviceProfile::Accesser &accesser, + DistributedDeviceProfile::Accessee &accessee) +{ + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return DM_OK; + } + for (auto &app : context->subjectProxyApps) { + if (context->direction == DM_AUTH_SOURCE ? app.proxyAccesser.isAuthed : app.proxyAccessee.isAuthed) { + continue; + } + accesser.SetAccesserTokenId(app.proxyAccesser.tokenId); + accesser.SetAccesserBundleName(app.proxyAccesser.pkgName); + accesser.SetAccesserCredentialIdStr(app.proxyAccesser.transmitCredentialId); + accesser.SetAccesserSessionKeyId(app.proxyAccesser.transmitSessionKeyId); + accesser.SetAccesserSKTimeStamp(app.proxyAccesser.transmitSkTimeStamp); + JsonObject accesserProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + accesserProxyObj.PushBack(context->accesser.pkgName); + JsonObject accesserExtObj(context->accesser.extraInfo); + accesserExtObj[TAG_PROXY] = accesserProxyObj.Dump(); + accesser.SetAccesserExtraData(accesserExtObj.Dump()); + + accessee.SetAccesseeTokenId(app.proxyAccessee.tokenId); + accessee.SetAccesseeBundleName(app.proxyAccessee.pkgName); + accessee.SetAccesseeCredentialIdStr(app.proxyAccessee.transmitCredentialId); + accessee.SetAccesseeSessionKeyId(app.proxyAccessee.transmitSessionKeyId); + accessee.SetAccesseeSKTimeStamp(app.proxyAccessee.transmitSkTimeStamp); + JsonObject accesseeProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + accesseeProxyObj.PushBack(context->accessee.pkgName); + JsonObject accesseeExtObj(context->accessee.extraInfo); + accesseeExtObj[TAG_PROXY] = accesseeProxyObj.Dump(); + accessee.SetAccesseeExtraData(accesseeExtObj.Dump()); + + JsonObject extraData; + std::string isLnnAclFalse = std::string(ACL_IS_LNN_ACL_VAL_FALSE); + extraData[ACL_IS_LNN_ACL_KEY] = isLnnAclFalse; + profile.SetExtraData(extraData.Dump()); + profile.SetBindLevel(context->direction == DM_AUTH_SOURCE ? app.proxyAccesser.bindLevel : + app.proxyAccessee.bindLevel); + profile.SetBindType(context->direction == DM_AUTH_SOURCE ? context->accesser.transmitBindType : + context->accessee.transmitBindType); + profile.SetAccessee(accessee); + profile.SetAccesser(accesser); + int32_t ret = + DistributedDeviceProfile::DistributedDeviceProfileClient::GetInstance().PutAccessControlProfile(profile); + if (ret != DM_OK) { + LOGE("PutAccessControlProfile failed."); + return ret; + } + } + SetAclProxyRelate(context); + return DM_OK; } DmAuthMessageProcessor::DmAuthMessageProcessor() @@ -654,7 +766,28 @@ int32_t DmAuthMessageProcessor::CreateNegotiateMessage(std::shared_ptraccessee.displayId; jsonObject[TAG_PEER_PKG_NAME] = context->accessee.pkgName; jsonObject[TAG_HOST_PKGLABEL] = context->pkgLabel; + CreateProxyNegotiateMessage(context, jsonObject); + return DM_OK; +} +int32_t DmAuthMessageProcessor::CreateProxyNegotiateMessage(std::shared_ptr context, + JsonObject &jsonObject) +{ + jsonObject[PARAM_KEY_IS_PROXY_BIND] = context->IsProxyBind; + jsonObject[PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT] = context->IsCallingProxyAsSubject; + if (context != nullptr && context->IsProxyBind && !context->subjectProxyApps.empty()) { + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyApps) { + JsonObject object; + object[TAG_PROXY_CONTEXT_ID] = app.proxyContextId; + object[TAG_HOST_PKGLABEL] = app.pkgLabel; + object[TAG_BUNDLE_NAME] = app.proxyAccesser.bundleName; + object[TAG_PEER_BUNDLE_NAME] = app.proxyAccessee.bundleName; + object[TAG_TOKEN_ID_HASH] = app.proxyAccesser.tokenIdHash; + allProxyObj.PushBack(object); + } + jsonObject[PARAM_KEY_SUBJECT_PROXYED_APPS] = allProxyObj.Dump(); + } return DM_OK; } @@ -676,7 +809,26 @@ int32_t DmAuthMessageProcessor::CreateRespNegotiateMessage(std::shared_ptraccessee.networkId; jsonObject[TAG_IS_ONLINE] = context->accesser.isOnline; + CreateProxyRespNegotiateMessage(context, jsonObject); + return DM_OK; +} +int32_t DmAuthMessageProcessor::CreateProxyRespNegotiateMessage(std::shared_ptr context, + JsonObject &jsonObject) +{ + jsonObject[PARAM_KEY_IS_PROXY_BIND] = context->IsProxyBind; + if (context != nullptr && context->IsProxyBind && !context->subjectProxyApps.empty()) { + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyApps) { + JsonObject object; + object[TAG_PROXY_CONTEXT_ID] = app.proxyContextId; + object[TAG_TOKEN_ID_HASH] = app.proxyAccessee.tokenIdHash; + object[TAG_ACL_TYPE_LIST] = app.proxyAccessee.aclTypeJson; + object[TAG_CERT_TYPE_LIST] = app.proxyAccessee.validCredInfoJson; + allProxyObj.PushBack(object); + } + jsonObject[PARAM_KEY_SUBJECT_PROXYED_APPS] = allProxyObj.Dump(); + } return DM_OK; } @@ -813,6 +965,10 @@ int32_t DmAuthMessageProcessor::ParseSyncMessage(std::shared_ptr // Parse into access ParseDmAccessToSync(srcAccessStr, accessTmp, false); // check access validity + if (ParseProxyAccessToSync(context, jsonObject) != DM_OK) { + LOGE("ParseProxyAccessToSync error, stop auth."); + return ERR_DM_FAILED; + } if (!CheckAccessValidityAndAssign(context, access, accessTmp)) { LOGE("ParseSyncMessage CheckAccessValidityAndAssign error, data between two stages different, stop auth."); return ERR_DM_FAILED; @@ -823,7 +979,6 @@ int32_t DmAuthMessageProcessor::ParseSyncMessage(std::shared_ptr return ERR_DM_FAILED; } access.aclStrList = jsonObject[TAG_ACL_CHECKSUM].Get(); - if (context->direction == DmAuthDirection::DM_AUTH_SOURCE) { LOGI("Source parse sink user confirm opt"); int32_t userConfirmOpt = static_cast(USER_OPERATION_TYPE_CANCEL_AUTH); @@ -839,27 +994,64 @@ int32_t DmAuthMessageProcessor::ParseSyncMessage(std::shared_ptr return DM_OK; } +int32_t DmAuthMessageProcessor::ParseProxyAccessToSync(std::shared_ptr &context, + JsonObject &jsonObject) +{ + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return DM_OK; + } + if (!IsString(jsonObject, PARAM_KEY_SUBJECT_PROXYED_APPS)) { + LOGE("no subjectProxyedApps"); + return ERR_DM_FAILED; + } + std::string subjectProxyAppsStr = jsonObject[PARAM_KEY_SUBJECT_PROXYED_APPS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyAppsStr); + for (auto const &item : allProxyObj.Items()) { + if (!IsString(item, TAG_PROXY_CONTEXT_ID)) { + continue; + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = item[TAG_PROXY_CONTEXT_ID].Get(); + auto it = std::find(context->subjectProxyApps.begin(), context->subjectProxyApps.end(), proxyAuthContext); + if (it != context->subjectProxyApps.end()) { + if (!IsInt64(item, TAG_TOKEN_ID) || !IsInt32(item, TAG_TRANSMIT_SK_ID) || + !IsInt64(item, TAG_TRANSMIT_SK_TIMESTAMP) || !IsString(item, TAG_TRANSMIT_CREDENTIAL_ID)) { + LOGE("no subjectProxyedApps"); + return ERR_DM_FAILED; + } + + DmProxyAccess &access = (context->direction == DM_AUTH_SOURCE) ? it->proxyAccesser : it->proxyAccessee; + access.tokenId = item[TAG_TOKEN_ID].Get(); + access.transmitSessionKeyId = item[TAG_TRANSMIT_SK_ID].Get(); + access.skTimeStamp = item[TAG_TRANSMIT_SK_TIMESTAMP].Get(); + access.transmitCredentialId = item[TAG_TRANSMIT_CREDENTIAL_ID].Get(); + } + } + return DM_OK; +} + int32_t DmAuthMessageProcessor::DecryptSyncMessage(std::shared_ptr &context, DmAccess &access, std::string &enSyncMsg) { std::string syncMsgCompress = ""; int32_t ret = cryptoMgr_->DecryptMessage(enSyncMsg, syncMsgCompress); if (ret != DM_OK) { - LOGE("DecryptSyncMessage syncMsg error"); + LOGE("syncMsg error"); return ret; } JsonObject plainJson(syncMsgCompress); if (plainJson.IsDiscarded()) { - LOGE("DecryptSyncMessage plainJson error"); + LOGE("plainJson error"); return ERR_DM_FAILED; } if (!plainJson[TAG_COMPRESS_ORI_LEN].IsNumberInteger()) { - LOGE("DecryptSyncMessage TAG_COMPRESS_ORI_LEN json error"); + LOGE("TAG_COMPRESS_ORI_LEN json error"); return ERR_DM_FAILED; } int32_t dataLen = plainJson[TAG_COMPRESS_ORI_LEN].Get(); if (!plainJson[TAG_COMPRESS].IsString()) { - LOGE("DecryptSyncMessage TAG_COMPRESS_ORI_LEN json error"); + LOGE("TAG_COMPRESS_ORI_LEN json error"); return ERR_DM_FAILED; } std::string compressMsg = plainJson[TAG_COMPRESS].Get(); @@ -867,13 +1059,13 @@ int32_t DmAuthMessageProcessor::DecryptSyncMessage(std::shared_ptrauthStateMachine->TransitionTo(std::make_shared()); return DM_OK; } @@ -1032,6 +1225,42 @@ void DmAuthMessageProcessor::ParseCert(const JsonObject &jsonObject, } } +int32_t DmAuthMessageProcessor::ParseProxyNegotiateMessage( + const JsonObject &jsonObject, std::shared_ptr context) +{ + if (IsBool(jsonObject, PARAM_KEY_IS_PROXY_BIND)) { + context->IsProxyBind = jsonObject[PARAM_KEY_IS_PROXY_BIND].Get(); + } + if (IsBool(jsonObject, PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT)) { + context->IsCallingProxyAsSubject = jsonObject[PARAM_KEY_IS_CALLING_PROXY_AS_SUBJECT].Get(); + } + if (!context->IsProxyBind) { + return DM_OK; + } + if (!IsString(jsonObject, PARAM_KEY_SUBJECT_PROXYED_APPS)) { + return ERR_DM_INPUT_PARA_INVALID; + } + std::string subjectProxyAppsStr = jsonObject[PARAM_KEY_SUBJECT_PROXYED_APPS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyAppsStr); + for (auto const &item : allProxyObj.Items()) { + if (!IsString(item, TAG_PROXY_CONTEXT_ID) || !IsString(item, TAG_BUNDLE_NAME) || + !IsString(item, TAG_PEER_BUNDLE_NAME) || !IsString(item, TAG_TOKEN_ID_HASH)) { + continue; + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = item[TAG_PROXY_CONTEXT_ID].Get(); + proxyAuthContext.proxyAccesser.bundleName = item[TAG_BUNDLE_NAME].Get(); + proxyAuthContext.proxyAccessee.bundleName = item[TAG_PEER_BUNDLE_NAME].Get(); + proxyAuthContext.proxyAccesser.tokenIdHash = item[TAG_TOKEN_ID_HASH].Get(); + if (IsString(item, TAG_HOST_PKGLABEL)) { + proxyAuthContext.pkgLabel = item[TAG_HOST_PKGLABEL].Get(); + } + context->subjectProxyApps.push_back(proxyAuthContext); + } + return DM_OK; +} + void DmAuthMessageProcessor::ParseUltrasonicSide( const JsonObject &jsonObject, std::shared_ptr context) { @@ -1099,10 +1328,45 @@ int32_t DmAuthMessageProcessor::ParseMessageRespAclNegotiate(const JsonObject &j if (jsonObject[TAG_EXTRA_INFO].IsString()) { context->accessee.extraInfo = jsonObject[TAG_EXTRA_INFO].Get(); } + ParseMessageProxyRespAclNegotiate(jsonObject, context); context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } +int32_t DmAuthMessageProcessor::ParseMessageProxyRespAclNegotiate(const JsonObject &jsonObject, + std::shared_ptr context) +{ + if (!IsBool(jsonObject, PARAM_KEY_IS_PROXY_BIND)) { + context->IsProxyBind = false; + LOGE("sink does not support proxy"); + return DM_OK; + } + if (!context->IsProxyBind) { + return DM_OK; + } + if (!IsString(jsonObject, PARAM_KEY_SUBJECT_PROXYED_APPS)) { + return ERR_DM_INPUT_PARA_INVALID; + } + std::string subjectProxyAppsStr = jsonObject[PARAM_KEY_SUBJECT_PROXYED_APPS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyAppsStr); + for (auto const &item : allProxyObj.Items()) { + if (!IsString(item, TAG_PROXY_CONTEXT_ID) || !IsString(item, TAG_TOKEN_ID_HASH) || + !IsString(item, TAG_ACL_TYPE_LIST) || !IsString(item, TAG_CERT_TYPE_LIST)) { + continue; + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = item[TAG_PROXY_CONTEXT_ID].Get(); + auto it = std::find(context->subjectProxyApps.begin(), context->subjectProxyApps.end(), proxyAuthContext); + if (it != context->subjectProxyApps.end()) { + it->proxyAccessee.tokenIdHash = item[TAG_TOKEN_ID_HASH].Get(); + it->proxyAccessee.aclTypeList = item[TAG_ACL_TYPE_LIST].Get(); + it->proxyAccessee.credTypeList = item[TAG_CERT_TYPE_LIST].Get(); + } + } + return DM_OK; +} + int32_t DmAuthMessageProcessor::ParseMessageReqUserConfirm(const JsonObject &json, std::shared_ptr context) { @@ -1127,10 +1391,39 @@ int32_t DmAuthMessageProcessor::ParseMessageReqUserConfirm(const JsonObject &jso if (IsString(json, TAG_CUSTOM_DESCRIPTION)) { context->customData = json[TAG_CUSTOM_DESCRIPTION].Get(); } + ParseMessageProxyReqUserConfirm(json, context); context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } +int32_t DmAuthMessageProcessor::ParseMessageProxyReqUserConfirm(const JsonObject &json, + std::shared_ptr context) +{ + if (!context->IsProxyBind) { + return DM_OK; + } + if (!IsString(json, PARAM_KEY_SUBJECT_PROXYED_APPS)) { + return ERR_DM_INPUT_PARA_INVALID; + } + std::string subjectProxyAppsStr = json[PARAM_KEY_SUBJECT_PROXYED_APPS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyAppsStr); + for (auto const &item : allProxyObj.Items()) { + if (!IsString(item, TAG_PROXY_CONTEXT_ID) || !IsString(item, TAG_ACL_TYPE_LIST) || + !IsString(item, TAG_CERT_TYPE_LIST)) { + continue; + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = item[TAG_PROXY_CONTEXT_ID].Get(); + auto it = std::find(context->subjectProxyApps.begin(), context->subjectProxyApps.end(), proxyAuthContext); + if (it != context->subjectProxyApps.end()) { + it->proxyAccesser.aclTypeList = item[TAG_ACL_TYPE_LIST].Get(); + it->proxyAccesser.credTypeList = item[TAG_CERT_TYPE_LIST].Get(); + } + } + return DM_OK; +} + int32_t DmAuthMessageProcessor::ParseMessageRespUserConfirm(const JsonObject &json, std::shared_ptr context) { @@ -1141,10 +1434,43 @@ int32_t DmAuthMessageProcessor::ParseMessageRespUserConfirm(const JsonObject &js if (json[TAG_EXTRA_INFO].IsString()) { context->accessee.extraInfo = json[TAG_EXTRA_INFO].Get(); } + ParseMessageProxyRespUserConfirm(json, context); context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } +int32_t DmAuthMessageProcessor::ParseMessageProxyRespUserConfirm(const JsonObject &json, + std::shared_ptr context) +{ + if (!context->IsProxyBind) { + return DM_OK; + } + if (!IsString(json, PARAM_KEY_SUBJECT_PROXYED_APPS)) { + context->subjectProxyApps.clear(); + return ERR_DM_INPUT_PARA_INVALID; + } + std::string subjectProxyAppsStr = json[PARAM_KEY_SUBJECT_PROXYED_APPS].Get(); + JsonObject allProxyObj; + allProxyObj.Parse(subjectProxyAppsStr); + std::vector sinkSubjectProxyApps; + for (auto const &item : allProxyObj.Items()) { + if (!IsString(item, TAG_PROXY_CONTEXT_ID)) { + continue; + } + DmProxyAuthContext proxyAuthContext; + proxyAuthContext.proxyContextId = item[TAG_PROXY_CONTEXT_ID].Get(); + sinkSubjectProxyApps.push_back(proxyAuthContext); + } + for (auto item = context->subjectProxyApps.begin(); item != context->subjectProxyApps.end();) { + if (std::find(sinkSubjectProxyApps.begin(), sinkSubjectProxyApps.end(), *item) != sinkSubjectProxyApps.end()) { + item = context->subjectProxyApps.erase(item); + } else { + item++; + } + } + return DM_OK; +} + int32_t DmAuthMessageProcessor::ParseMessageReqPinAuthStart(const JsonObject &json, std::shared_ptr context) { @@ -1223,7 +1549,24 @@ int32_t DmAuthMessageProcessor::CreateMessageReqUserConfirm(std::shared_ptraccesser.deviceName; json[TAG_EXTRA_INFO] = context->accesser.extraInfo; json[TAG_CUSTOM_DESCRIPTION] = context->customData; + CreateMessageProxyReqUserConfirm(context, json); + return DM_OK; +} +int32_t DmAuthMessageProcessor::CreateMessageProxyReqUserConfirm(std::shared_ptr context, + JsonObject &json) +{ + if (context != nullptr && context->IsProxyBind && !context->subjectProxyApps.empty()) { + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyApps) { + JsonObject object; + object[TAG_PROXY_CONTEXT_ID] = app.proxyContextId; + object[TAG_ACL_TYPE_LIST] = app.proxyAccesser.aclTypeList; + object[TAG_CERT_TYPE_LIST] = app.proxyAccesser.credTypeList; + allProxyObj.PushBack(object); + } + json[PARAM_KEY_SUBJECT_PROXYED_APPS] = allProxyObj.Dump(); + } return DM_OK; } @@ -1231,6 +1574,15 @@ int32_t DmAuthMessageProcessor::CreateMessageRespUserConfirm(std::shared_ptrauthTypeList); json[TAG_EXTRA_INFO] = context->accessee.extraInfo; + if (context != nullptr && context->IsProxyBind && !context->subjectProxyApps.empty()) { + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyApps) { + JsonObject object; + object[TAG_PROXY_CONTEXT_ID] = app.proxyContextId; + allProxyObj.PushBack(object); + } + json[PARAM_KEY_SUBJECT_PROXYED_APPS] = allProxyObj.Dump(); + } return DM_OK; } @@ -1421,7 +1773,7 @@ int32_t DmAuthMessageProcessor::EncryptSyncMessage(std::shared_ptrconfirmOperation; } - + CreateProxyAccessMessage(context, syncMsgJson); std::string syncMsg = syncMsgJson.Dump(); std::string compressMsg = CompressSyncMsg(syncMsg); if (compressMsg.empty()) { @@ -1434,6 +1786,38 @@ int32_t DmAuthMessageProcessor::EncryptSyncMessage(std::shared_ptrEncryptMessage(plainJson.Dump(), encSyncMsg); } +int32_t DmAuthMessageProcessor::CreateProxyAccessMessage(std::shared_ptr &context, + JsonObject &syncMsgJson) +{ + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return DM_OK; + } + JsonObject allProxyObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (const auto &app : context->subjectProxyApps) { + DmProxyAccess access; + if (context->direction == DM_AUTH_SINK) { + access = app.proxyAccesser; + } else { + access = app.proxyAccessee; + } + if (access.isAuthed) { + continue; + } + JsonObject object; + object[TAG_PROXY_CONTEXT_ID] = app.proxyContextId; + object[TAG_TOKEN_ID] = access.tokenId; + object[TAG_BUNDLE_NAME] = access.bundleName; + object[TAG_BIND_LEVEL] = access.bindLevel; + object[TAG_PKG_NAME] = access.pkgName; + object[TAG_TRANSMIT_SK_ID] = std::to_string(access.transmitSessionKeyId); + object[TAG_TRANSMIT_SK_TIMESTAMP] = access.skTimeStamp; + object[TAG_TRANSMIT_CREDENTIAL_ID] = access.transmitCredentialId; + allProxyObj.PushBack(object); + } + syncMsgJson[PARAM_KEY_SUBJECT_PROXYED_APPS] = allProxyObj.Dump(); + return DM_OK; +} + int32_t DmAuthMessageProcessor::ACLToStr(DistributedDeviceProfile::AccessControlProfile acl, std::string aclStr) { DmAccessControlTable dmAcl; @@ -1492,6 +1876,56 @@ int32_t DmAuthMessageProcessor::ParseAuthStartMessage(const JsonObject &jsonObje return DM_OK; } +void DmAuthMessageProcessor::SetAclProxyRelate(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return; + } + for (auto &app : context->subjectProxyApps) { + if (context->direction == DM_AUTH_SOURCE) { + if (!app.proxyAccesser.isAuthed) { + continue; + } + if (app.proxyAccesser.aclProfiles.find(DM_POINT_TO_POINT) == app.proxyAccesser.aclProfiles.end()) { + continue; + } + JsonObject accessExtObj(app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT]. + GetAccesser().GetAccesserExtraData()); + JsonObject accessProxyObj; + if (IsString(accessExtObj, TAG_PROXY)) { + std::string proxyStr = accessExtObj[TAG_PROXY].Get(); + accessProxyObj.Parse(proxyStr); + } + accessProxyObj.PushBack(context->accesser.pkgName); + accessExtObj[TAG_PROXY] = accessProxyObj.Dump(); + app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT]. + GetAccesser().SetAccesserExtraData(accessExtObj.Dump()); + DistributedDeviceProfile::DistributedDeviceProfileClient::GetInstance(). + UpdateAccessControlProfile(app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT]); + continue; + } + if (!app.proxyAccessee.isAuthed) { + continue; + } + if (app.proxyAccessee.aclProfiles.find(DM_POINT_TO_POINT) == app.proxyAccessee.aclProfiles.end()) { + continue; + } + JsonObject accessExtObj(app.proxyAccessee.aclProfiles[DM_POINT_TO_POINT]. + GetAccessee().GetAccesseeExtraData()); + JsonObject accessProxyObj; + if (IsString(accessExtObj, TAG_PROXY)) { + std::string proxyStr = accessExtObj[TAG_PROXY].Get(); + accessProxyObj.Parse(proxyStr); + } + accessProxyObj.PushBack(context->accessee.pkgName); + accessExtObj[TAG_PROXY] = accessProxyObj.Dump(); + app.proxyAccessee.aclProfiles[DM_POINT_TO_POINT]. + GetAccessee().SetAccesseeExtraData(accessExtObj.Dump()); + DistributedDeviceProfile::DistributedDeviceProfileClient::GetInstance(). + UpdateAccessControlProfile(app.proxyAccessee.aclProfiles[DM_POINT_TO_POINT]); + } +} void ToJson(JsonItemObject &itemObject, const DmAccessControlTable &table) { diff --git a/services/implementation/src/authentication_v2/dm_auth_state.cpp b/services/implementation/src/authentication_v2/dm_auth_state.cpp index 7ab8d7a8c..c590fe96d 100644 --- a/services/implementation/src/authentication_v2/dm_auth_state.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_state.cpp @@ -167,6 +167,7 @@ void DmAuthState::SinkFinish(std::shared_ptr context) } else { SetAclInfo(context); if (NeedAgreeAcl(context)) { + UpdateCredInfo(context); context->authMessageProcessor->PutAccessControlList(context, context->accessee, context->accesser.deviceId); } @@ -230,7 +231,123 @@ bool DmAuthState::NeedAgreeCredential(std::shared_ptr context) bool DmAuthState::NeedAgreeAcl(std::shared_ptr context) { - return (context->direction == DM_AUTH_SOURCE) ? !context->accesser.isAuthed : !context->accessee.isAuthed; + if (context == nullptr) { + return true; + } + if (context->direction == DM_AUTH_SOURCE) { + if (context->accesser.isUserLevelAuthed) { + return false; + } + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return !context->accesser.isAuthed; + } + if (context->IsCallingProxyAsSubject && !context->accesser.isAuthed) { + return true; + } + return ProxyNeedAgreeAcl(context); + } + if (context->accessee.isUserLevelAuthed) { + return false; + } + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return !context->accessee.isAuthed; + } + if (context->IsCallingProxyAsSubject && !context->accessee.isAuthed) { + return true; + } + return ProxyNeedAgreeAcl(context); +} + +bool DmAuthState::ProxyNeedAgreeAcl(std::shared_ptr context) +{ + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return false; + } + if (context->direction == DM_AUTH_SOURCE) { + for (const auto &app : context->subjectProxyApps) { + if (!app.proxyAccesser.isAuthed) { + return true; + } + } + return false; + } + for (const auto &app : context->subjectProxyApps) { + if (!app.proxyAccessee.isAuthed) { + return true; + } + } + return false; +} + +bool DmAuthState::GetReuseSkId(std::shared_ptr context, int32_t &skId) +{ + DistributedDeviceProfile::AccessControlProfile profile; + GetReuseACL(context, profile); + if (!profile.GetAccesser().GetAccesserCredentialIdStr().empty() && + !profile.GetAccessee().GetAccesseeCredentialIdStr().empty()) { + if (context->direction == DM_AUTH_SOURCE) { + if (context->accesser.deviceId == profile.GetAccesser().GetAccesserDeviceId()) { + skId = profile.GetAccesser().GetAccesserSessionKeyId(); + context->reUseCreId = profile.GetAccesser().GetAccesserCredentialIdStr(); + return true; + } + skId = profile.GetAccessee().GetAccesseeSessionKeyId(); + context->reUseCreId = profile.GetAccessee().GetAccesseeCredentialIdStr(); + return true; + } + if (context->accessee.deviceId == profile.GetAccessee().GetAccesseeDeviceId()) { + skId = profile.GetAccessee().GetAccesseeSessionKeyId(); + context->reUseCreId = profile.GetAccessee().GetAccesseeCredentialIdStr(); + return true; + } + skId = profile.GetAccesser().GetAccesserSessionKeyId(); + context->reUseCreId = profile.GetAccesser().GetAccesserCredentialIdStr(); + return true; + } + return false; +} + +void DmAuthState::GetReuseACL(std::shared_ptr context, + DistributedDeviceProfile::AccessControlProfile &profile) +{ + if (context == nullptr) { + return; + } + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return; + } + + if (context->direction == DM_AUTH_SOURCE) { + if (context->accesser.aclProfiles.find(DM_POINT_TO_POINT) != context->accesser.aclProfiles.end() && + !context->accesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr().empty() && + !context->accesser.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr().empty()) { + profile = context->accesser.aclProfiles[DM_POINT_TO_POINT]; + return; + } + for (auto &app : context->subjectProxyApps) { + if (app.proxyAccesser.aclProfiles.find(DM_POINT_TO_POINT) != app.proxyAccesser.aclProfiles.end() && + !app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr().empty() && + !app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr().empty()) { + profile = app.proxyAccesser.aclProfiles[DM_POINT_TO_POINT]; + return; + } + } + return; + } + if (context->accessee.aclProfiles.find(DM_POINT_TO_POINT) != context->accessee.aclProfiles.end() && + !context->accessee.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr().empty() && + !context->accessee.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr().empty()) { + profile = context->accessee.aclProfiles[DM_POINT_TO_POINT]; + return; + } + for (auto &app : context->subjectProxyApps) { + if (app.proxyAccessee.aclProfiles.find(DM_POINT_TO_POINT) != app.proxyAccessee.aclProfiles.end() && + !app.proxyAccessee.aclProfiles[DM_POINT_TO_POINT].GetAccessee().GetAccesseeCredentialIdStr().empty() && + !app.proxyAccessee.aclProfiles[DM_POINT_TO_POINT].GetAccesser().GetAccesserCredentialIdStr().empty()) { + profile = app.proxyAccessee.aclProfiles[DM_POINT_TO_POINT]; + return; + } + } } bool DmAuthState::IsImportAuthCodeCompatibility(DmAuthType authType) @@ -308,9 +425,15 @@ uint32_t DmAuthState::GetCredType(std::shared_ptr context, const context->direction == DM_AUTH_SINK && subject == SUBJECT_SECONDARY) { return DM_SHARE; } - if (credType == ACCOUNT_UNRELATED && (authorizedScope == SCOPE_APP || authorizedScope == SCOPE_USER) && - HaveSameTokenId(context, appList)) { - return DM_POINT_TO_POINT; + if (credType == ACCOUNT_UNRELATED && (authorizedScope == SCOPE_APP || authorizedScope == SCOPE_USER)) { + std::vector tokenIdHashList; + for (std::string tokenId : appList) { + tokenIdHashList.push_back(Crypto::GetTokenIdHash(tokenId)); + } + GetProxyCredInfo(context, credInfo, tokenIdHashList); + if (HaveSameTokenId(context, tokenIdHashList)) { + return DM_POINT_TO_POINT; + } } if (credType == ACCOUNT_UNRELATED && authorizedScope == SCOPE_USER && appList.empty()) { return DM_LNN; @@ -318,6 +441,39 @@ uint32_t DmAuthState::GetCredType(std::shared_ptr context, const return DM_INVALIED_TYPE; } +int32_t DmAuthState::GetProxyCredInfo(std::shared_ptr context, const JsonItemObject &credInfo, + const std::vector &tokenIdHashList) +{ + if (!context->IsProxyBind) { + return DM_OK; + } + if (context->subjectProxyApps.empty()) { + return ERR_DM_INPUT_PARA_INVALID; + } + if (!credInfo.Contains(FILED_CRED_ID) || !credInfo[FILED_CRED_ID].IsString()) { + return static_cast(DM_INVALIED_TYPE); + } + for (auto &app : context->subjectProxyApps) { + if (std::find(tokenIdHashList.begin(), tokenIdHashList.end(), app.proxyAccesser.tokenIdHash) + != tokenIdHashList.end() && + std::find(tokenIdHashList.begin(), tokenIdHashList.end(), app.proxyAccessee.tokenIdHash) + != tokenIdHashList.end()) { + JsonItemObject appCredInfo = credInfo; + appCredInfo[FILED_CRED_TYPE] = DM_POINT_TO_POINT; + if (context->direction == DM_AUTH_SOURCE) { + JsonObject credInfoJson(app.proxyAccesser.credInfoJson); + credInfoJson.Insert(appCredInfo[FILED_CRED_ID].Get(), appCredInfo); + app.proxyAccesser.credInfoJson = credInfoJson.Dump(); + } else { + JsonObject credInfoJson(app.proxyAccessee.credInfoJson); + credInfoJson.Insert(appCredInfo[FILED_CRED_ID].Get(), appCredInfo); + app.proxyAccessee.credInfoJson = credInfoJson.Dump(); + } + } + } + return DM_OK; +} + uint32_t DmAuthState::GetCredentialType(std::shared_ptr context, const JsonItemObject &credInfo) { CHECK_NULL_RETURN(context, DM_INVALIED_TYPE); @@ -330,22 +486,18 @@ uint32_t DmAuthState::GetCredentialType(std::shared_ptr context, return GetCredType(context, credInfo); } -bool DmAuthState::HaveSameTokenId(std::shared_ptr context, const std::vector &tokenList) +bool DmAuthState::HaveSameTokenId(std::shared_ptr context, + const std::vector &tokenIdHashList) { - // Store the token of src and sink. The size must be 2. - if (tokenList.size() != 2) { + // Store the token of src and sink. The size must be greater than or equal to 2. + if (tokenIdHashList.size() < 2) { LOGE("HaveSameTokenId invalid tokenList size."); return false; } - - // tokenIdList = [srcTokenId, sinkTokenId] - std::string srcTokenIdHash = Crypto::GetTokenIdHash(tokenList[0]); - std::string sinkTokenIdHash = Crypto::GetTokenIdHash(tokenList[1]); - - return ((srcTokenIdHash == context->accesser.tokenIdHash) && - (sinkTokenIdHash == context->accessee.tokenIdHash)) || - ((sinkTokenIdHash == context->accesser.tokenIdHash) && - (srcTokenIdHash == context->accessee.tokenIdHash)); + return std::find(tokenIdHashList.begin(), tokenIdHashList.end(), context->accesser.tokenIdHash) + != tokenIdHashList.end() && + std::find(tokenIdHashList.begin(), tokenIdHashList.end(), context->accessee.tokenIdHash) + != tokenIdHashList.end(); } int32_t DmAuthState::GetOutputState(int32_t state) @@ -419,6 +571,7 @@ void DmAuthState::SetProcessInfo(std::shared_ptr context) CHECK_NULL_VOID(context); DmAccess localAccess = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? context->accesser : context->accessee; + std::vector processInfoVec; ProcessInfo processInfo; processInfo.userId = localAccess.userId; uint32_t bindLevel = static_cast(localAccess.bindLevel); @@ -430,7 +583,17 @@ void DmAuthState::SetProcessInfo(std::shared_ptr context) LOGE("bindlevel error %{public}d.", bindLevel); return; } - context->softbusConnector->SetProcessInfo(processInfo); + processInfoVec.push_back(processInfo); + if (context->IsProxyBind && !context->subjectProxyApps.empty()) { + for (const auto &app : context->subjectProxyApps) { + ProcessInfo processInfo; + processInfo.userId = localAccess.userId; + processInfo.pkgName = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? app.proxyAccesser.pkgName : + app.proxyAccessee.pkgName; + processInfoVec.push_back(processInfo); + } + } + context->softbusConnector->SetProcessInfoVec(processInfoVec); } void DmAuthState::FilterProfilesByContext( @@ -455,5 +618,63 @@ void DmAuthState::FilterProfilesByContext( profiles.clear(); profiles.assign(aclProfilesVec.begin(), aclProfilesVec.end()); } + +bool DmAuthState::GetSessionKey(std::shared_ptr context) +{ + int32_t skId = 0; + if (!GetReuseSkId(context, skId)) { + return false; + } + return context->authMessageProcessor->GetSessionKey(context->accesser.userId, skId); +} + +bool DmAuthState::IsAclHasCredential(const DistributedDeviceProfile::AccessControlProfile &profile, + const std::string &credInfoJson, std::string &credId) +{ + JsonObject credInfoJsonObj(credInfoJson); + credId = profile.GetAccesser().GetAccesserCredentialIdStr(); + if (credInfoJsonObj.Contains(credId)) { + return true; + } + credId = profile.GetAccessee().GetAccesseeCredentialIdStr(); + if (credInfoJsonObj.Contains(credId)) { + return true; + } + return false; +} + +void DmAuthState::UpdateCredInfo(std::shared_ptr context) +{ + CHECK_NULL_VOID(context); + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return; + } + std::vector tokenIds; + for (auto &app : context->subjectProxyApps) { + if (context->direction == DM_AUTH_SOURCE ? app.proxyAccesser.isAuthed : app.proxyAccessee.isAuthed) { + continue; + } + tokenIds.push_back(std::to_string(app.proxyAccesser.tokenId)); + tokenIds.push_back(std::to_string(app.proxyAccessee.tokenId)); + } + if (tokenIds.empty()) { + return; + } + context->hiChainAuthConnector->UpdateCredential(context->reUseCreId, context->direction == DM_AUTH_SOURCE ? + context->accesser.userId : context->accessee.userId, tokenIds); +} + +bool DmAuthState::IsNeedBind(std::shared_ptr context) +{ + if (!context->IsProxyBind || context->subjectProxyApps.empty() || context->needBind) { + return context->needBind; + } + for (const auto &app : context->subjectProxyApps) { + if (context->needBind) { + return true; + } + } + return false; +} } // namespace DistributedHardware } // namespace OHOS diff --git a/services/implementation/src/authentication_v2/dm_auth_state_machine.cpp b/services/implementation/src/authentication_v2/dm_auth_state_machine.cpp index 74bba53bb..e172926a8 100644 --- a/services/implementation/src/authentication_v2/dm_auth_state_machine.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_state_machine.cpp @@ -87,6 +87,7 @@ void DmAuthStateMachine::InsertSrcTransTable() {DmAuthStateType::AUTH_SRC_CREDENTIAL_EXCHANGE_STATE, { DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_START_STATE, DmAuthStateType::AUTH_SRC_DATA_SYNC_STATE, + DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_DONE_STATE, }}, {DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_START_STATE, {DmAuthStateType::AUTH_SRC_CREDENTIAL_AUTH_NEGOTIATE_STATE}}, @@ -165,6 +166,8 @@ void DmAuthStateMachine::InsertSinkTransTable() {DmAuthStateType::AUTH_SINK_PIN_AUTH_MSG_NEGOTIATE_STATE, { DmAuthStateType::AUTH_SINK_PIN_AUTH_DONE_STATE, DmAuthStateType::AUTH_SINK_PIN_NEGOTIATE_START_STATE, + DmAuthStateType::AUTH_SINK_DATA_SYNC_STATE, + DmAuthStateType::AUTH_SINK_FINISH_STATE, }}, {DmAuthStateType::AUTH_SINK_PIN_AUTH_DONE_STATE, { DmAuthStateType::AUTH_SINK_CREDENTIAL_EXCHANGE_STATE, diff --git a/services/implementation/src/authentication_v2/dm_negotiate_process.cpp b/services/implementation/src/authentication_v2/dm_negotiate_process.cpp index f882e584a..f75611e91 100644 --- a/services/implementation/src/authentication_v2/dm_negotiate_process.cpp +++ b/services/implementation/src/authentication_v2/dm_negotiate_process.cpp @@ -108,12 +108,48 @@ int32_t NegotiateProcess::HandleNegotiateResult(std::shared_ptr c AuthType authType = ConvertAuthType(context->authType); LOGI("credType %{public}d, aclType %{public}d, authType %{public}d.", static_cast(credType), static_cast(aclType), static_cast(authType)); + int32_t ret = ERR_DM_CAPABILITY_NEGOTIATE_FAILED; NegotiateSpec negotiateSpec(credType, aclType, authType); auto handler = handlers_.find(negotiateSpec); if (handler != handlers_.end()) { - return handler->second->NegotiateHandle(context); + ret = handler->second->NegotiateHandle(context); + } else { + return ret; + } + if (!context->IsProxyBind || context->subjectProxyApps.empty() || + (credType == CredType::DM_IDENTICAL_CREDTYPE && aclType == AclType::DM_IDENTICAL_ACL) || + (credType == CredType::DM_SHARE_CREDTYPE && aclType == AclType::DM_SHARE_ACL)) { + return ret; } - return ERR_DM_CAPABILITY_NEGOTIATE_FAILED; + return HandleProxyNegotiateResult(context, ret); +} + +int32_t NegotiateProcess::HandleProxyNegotiateResult(std::shared_ptr context, int32_t result) +{ + CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); + if (!context->IsProxyBind || context->subjectProxyApps.empty()) { + return DM_OK; + } + bool isTrust = true; + for (auto &app : context->subjectProxyApps) { + std::string credTypeList = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? + app.proxyAccesser.credTypeList : app.proxyAccessee.credTypeList; + std::string aclTypeList = context->direction == DmAuthDirection::DM_AUTH_SOURCE ? + app.proxyAccesser.aclTypeList : app.proxyAccessee.aclTypeList; + CredType credType = ConvertCredType(credTypeList); + AclType aclType = ConvertAclType(aclTypeList); + if (credType == CredType::DM_P2P_CREDTYPE && aclType == AclType::DM_P2P_ACL) { + app.needBind = false; + app.needAgreeCredential = false; + app.needAuth = false; + } else { + isTrust = false; + } + } + if ((!context->IsCallingProxyAsSubject || result == ERR_DM_BIND_TRUST_TARGET) && isTrust) { + return ERR_DM_BIND_TRUST_TARGET; + } + return DM_OK; } CredType NegotiateProcess::ConvertCredType(const std::string &credType) @@ -131,10 +167,13 @@ CredType NegotiateProcess::ConvertCredType(const std::string &credType) } if (credTypeJson.Contains("identicalCredType")) { credTypeTemp = CredType::DM_IDENTICAL_CREDTYPE; + return credTypeTemp; } else if (credTypeJson.Contains("shareCredType")) { credTypeTemp = CredType::DM_SHARE_CREDTYPE; + return credTypeTemp; } else if (credTypeJson.Contains("pointTopointCredType")) { credTypeTemp = CredType::DM_P2P_CREDTYPE; + return credTypeTemp; } else { credTypeTemp = CredType::DM_NO_CRED; } @@ -156,10 +195,13 @@ AclType NegotiateProcess::ConvertAclType(const std::string &aclType) } if (aclTypeJson.Contains("identicalAcl")) { aclTypeTemp = AclType::DM_IDENTICAL_ACL; + return aclTypeTemp; } else if (aclTypeJson.Contains("shareAcl")) { aclTypeTemp = AclType::DM_SHARE_ACL; + return aclTypeTemp; } else if (aclTypeJson.Contains("pointTopointAcl")) { aclTypeTemp = AclType::DM_P2P_ACL; + return aclTypeTemp; } else { aclTypeTemp = AclType::DM_NO_ACL; } @@ -211,7 +253,7 @@ int32_t IdentCredIdentAclInputAuthType::NegotiateHandle(std::shared_ptr context) { CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); - return OnlyPinBind(context); + return EndBind(context); } int32_t IdentCredP2pAclInputAuthType::NegotiateHandle(std::shared_ptr context) @@ -247,7 +289,7 @@ int32_t ShareCredShareAclInputAuthType::NegotiateHandle(std::shared_ptr context) { CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); - return OnlyPinBind(context); + return EndBind(context); } int32_t ShareCredP2pAclInputAuthType::NegotiateHandle(std::shared_ptr context) @@ -283,7 +325,7 @@ int32_t P2pCredP2pAclInputAuthType::NegotiateHandle(std::shared_ptr context) { CHECK_NULL_RETURN(context, ERR_DM_POINT_NULL); - return OnlyPinBind(context); + return EndBind(context); } } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp b/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp index 28759e22c..e041a8996 100644 --- a/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp +++ b/services/implementation/src/dependency/hichain/hichain_auth_connector.cpp @@ -26,6 +26,7 @@ namespace OHOS { namespace DistributedHardware { +const char* const FILED_AUTHORIZED_APP_LIST = "authorizedAppList"; std::shared_ptr HiChainAuthConnector::dmDeviceAuthCallback_ = nullptr; std::map> HiChainAuthConnector::dmDeviceAuthCallbackMap_; std::mutex HiChainAuthConnector::dmDeviceAuthCallbackMutex_; @@ -530,5 +531,36 @@ int32_t HiChainAuthConnector::DeleteCredential(const std::string &deviceId, int3 FreeJsonString(returnData); return DM_OK; } + +int32_t HiChainAuthConnector::UpdateCredential(const std::string &credId, int32_t userId, + std::vector &tokenIds) +{ + const CredManager *cm = GetCredMgrInstance(); + char *returnCredInfo = nullptr; + int32_t ret = cm->queryCredInfoByCredId(userId, credId.c_str(), &returnCredInfo); + if (ret != DM_OK) { + LOGE("[HICHAIN]::QueryCredInfoByCredId failed, ret: %{public}d.", ret); + return ret; + } + JsonObject credInfoJson(returnCredInfo); + FreeJsonString(returnCredInfo); + if (credInfoJson.IsDiscarded()) { + LOGE("QueryCredInfoByCredId credential info jsonStr error"); + return ERR_DM_FAILED; + } + std::vector appList; + if (IsString(credInfoJson, FILED_AUTHORIZED_APP_LIST)) { + credInfoJson[FILED_AUTHORIZED_APP_LIST].Get(appList); + } + appList.insert(appList.end(), tokenIds.begin(), tokenIds.end()); + JsonObject jsonObj; + jsonObj[FILED_AUTHORIZED_APP_LIST] = appList; + ret = cm->updateCredInfo(userId, credId.c_str(), jsonObj.Dump().c_str()); + if (ret != DM_OK) { + LOGE("[HICHAIN]::updateCredInfo failed, ret: %{public}d.", ret); + return ret; + } + return DM_OK; +} } // namespace DistributedHardware } // namespace OHOS -- Gitee