1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "session_key_manager.h"
17 #include "asset_adapter.h"
18
19 #include "distributed_device_profile_errors.h"
20 #include "distributed_device_profile_log.h"
21
22 namespace OHOS {
23 namespace DistributedDeviceProfile {
24 IMPLEMENT_SINGLE_INSTANCE(SessionKeyManager);
25 namespace {
26 const std::string TAG = "SessionKeyManager";
27 }
28
PutSessionKey(uint32_t userId,const std::vector<uint8_t> & sessionKey,int32_t & sessionKeyId)29 int32_t SessionKeyManager::PutSessionKey(uint32_t userId,
30 const std::vector<uint8_t>& sessionKey, int32_t& sessionKeyId)
31 {
32 if (userId == 0 || sessionKey.empty() || sessionKey.size() > MAX_SESSIONKEY_SIZE) {
33 HILOGE("params is invalid");
34 return DP_INVALID_PARAMS;
35 }
36 GeneratedSessionKeyId(userId, sessionKeyId);
37 AssetValue aliasValue = { .blob = { static_cast<uint32_t>(sizeof(sessionKeyId)),
38 const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(&sessionKeyId)) } };
39 AssetValue userIdValue = { .u32 = userId };
40 AssetValue secretValue = { .blob = { static_cast<uint32_t>(sessionKey.size()),
41 const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(sessionKey.data())) } };
42 AssetValue accessibilityValue = { .u32 = SEC_ASSET_ACCESSIBILITY_DEVICE_FIRST_UNLOCKED };
43
44 AssetAttr attr[] = {
45 { .tag = SEC_ASSET_TAG_ALIAS, .value = aliasValue },
46 { .tag = SEC_ASSET_TAG_USER_ID, .value = userIdValue },
47 { .tag = SEC_ASSET_TAG_SECRET, .value = secretValue },
48 { .tag = SEC_ASSET_TAG_ACCESSIBILITY, .value = accessibilityValue }
49 };
50
51 int32_t ret = AssetAdapter::GetInstance().PutAsset(attr, sizeof(attr) / sizeof(attr[0]));
52 if (ret != DP_SUCCESS) {
53 HILOGE("PutSessionKey failed");
54 return ret;
55 }
56 HILOGI("userId : %{public}u, sessionKeyId : %{public}d", userId, sessionKeyId);
57 return DP_SUCCESS;
58 }
59
GetSessionKey(uint32_t userId,int32_t sessionKeyId,std::vector<uint8_t> & sessionKey)60 int32_t SessionKeyManager::GetSessionKey(uint32_t userId,
61 int32_t sessionKeyId, std::vector<uint8_t>& sessionKey)
62 {
63 HILOGI("call! userId : %{public}u, sessionKeyId : %{public}d", userId, sessionKeyId);
64 if (userId == 0) {
65 HILOGE("params is invalid");
66 return DP_INVALID_PARAMS;
67 }
68 AssetValue aliasValue = { .blob = { static_cast<uint32_t>(sizeof(sessionKeyId)),
69 const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(&sessionKeyId)) } };
70 AssetValue userIdValue = { .u32 = userId };
71 AssetValue returnValue = { .u32 = SEC_ASSET_RETURN_ALL };
72 AssetAttr attr[] = {
73 { .tag = SEC_ASSET_TAG_ALIAS, .value = aliasValue },
74 { .tag = SEC_ASSET_TAG_USER_ID, .value = userIdValue },
75 { .tag = SEC_ASSET_TAG_RETURN_TYPE, .value = returnValue }
76 };
77
78 AssetResultSet resultSet = {0};
79 int32_t ret = AssetAdapter::GetInstance().GetAsset(attr, sizeof(attr) / sizeof(attr[0]), &resultSet);
80 if (ret != DP_SUCCESS) {
81 HILOGE("GetAsset failed");
82 AssetAdapter::GetInstance().FreeResultSet(&resultSet);
83 return ret;
84 }
85
86 AssetAttr* secret = AssetAdapter::GetInstance().ParseAttr(resultSet.results, SEC_ASSET_TAG_SECRET);
87 if (secret == nullptr) {
88 HILOGE("ParseAttr failed");
89 AssetAdapter::GetInstance().FreeResultSet(&resultSet);
90 return DP_GET_ASSET_ERROE;
91 }
92 uint32_t length = secret->value.blob.size;
93 uint8_t* data = secret->value.blob.data;
94 if (data == nullptr || length == 0 || length > MAX_SESSIONKEY_SIZE) {
95 HILOGE("result invalid");
96 data = nullptr;
97 AssetAdapter::GetInstance().FreeResultSet(&resultSet);
98 return DP_GET_ASSET_ERROE;
99 }
100 sessionKey = std::vector<uint8_t>(data, data + length);
101 AssetAdapter::GetInstance().FreeResultSet(&resultSet);
102 HILOGI("success!");
103 return DP_SUCCESS;
104 }
105
UpdateSessionKey(uint32_t userId,int32_t sessionKeyId,const std::vector<uint8_t> & sessionKey)106 int32_t SessionKeyManager::UpdateSessionKey(uint32_t userId,
107 int32_t sessionKeyId, const std::vector<uint8_t>& sessionKey)
108 {
109 HILOGI("call! userId : %{public}u, sessionKeyId : %{public}d", userId, sessionKeyId);
110 if (userId == 0) {
111 HILOGE("params is invalid");
112 return DP_INVALID_PARAMS;
113 }
114 AssetValue aliasValue = { .blob = { static_cast<uint32_t>(sizeof(sessionKeyId)),
115 const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(&sessionKeyId)) } };
116 AssetValue userIdValue = { .u32 = userId };
117 AssetValue secretValue = { .blob = { static_cast<uint32_t>(sessionKey.size()),
118 const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(sessionKey.data())) } };
119
120 AssetAttr attrQuery[] = {
121 { .tag = SEC_ASSET_TAG_ALIAS, .value = aliasValue },
122 { .tag = SEC_ASSET_TAG_USER_ID, .value = userIdValue }
123 };
124 AssetAttr attrUpdate[] = {
125 { .tag = SEC_ASSET_TAG_SECRET, .value = secretValue }
126 };
127
128 int32_t ret = AssetAdapter::GetInstance().UpdateAsset(attrQuery, sizeof(attrQuery) / sizeof(attrQuery[0]),
129 attrUpdate, sizeof(attrUpdate) / sizeof(attrUpdate[0]));
130 if (ret != DP_SUCCESS) {
131 HILOGE("UpdateSessionKey failed");
132 return ret;
133 }
134 HILOGI("success!");
135 return DP_SUCCESS;
136 }
137
DeleteSessionKey(uint32_t userId,int32_t sessionKeyId)138 int32_t SessionKeyManager::DeleteSessionKey(uint32_t userId, int32_t sessionKeyId)
139 {
140 HILOGI("call! userId : %{public}u, sessionKeyId : %{public}d", userId, sessionKeyId);
141 if (userId == 0) {
142 HILOGE("params is invalid");
143 return DP_INVALID_PARAMS;
144 }
145 AssetValue aliasValue = { .blob = { static_cast<uint32_t>(sizeof(sessionKeyId)),
146 const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(&sessionKeyId)) } };
147 AssetValue userIdValue = { .u32 = userId };
148 AssetAttr attr[] = {
149 { .tag = SEC_ASSET_TAG_ALIAS, .value = aliasValue },
150 { .tag = SEC_ASSET_TAG_USER_ID, .value = userIdValue }
151 };
152
153 int32_t ret = AssetAdapter::GetInstance().DeleteAsset(attr, sizeof(attr) / sizeof(attr[0]));
154 if (ret != DP_SUCCESS) {
155 HILOGE("DeleteAsset failed");
156 return ret;
157 }
158 HILOGI("success!");
159 return DP_SUCCESS;
160 }
161
GeneratedSessionKeyId(uint32_t userId,int32_t & sessionKeyId)162 void SessionKeyManager::GeneratedSessionKeyId(uint32_t userId, int32_t& sessionKeyId)
163 {
164 HILOGI("call");
165 int32_t ret = 0;
166 int32_t randomNumber = 0;
167 do {
168 int32_t seed = std::chrono::system_clock::now().time_since_epoch().count();
169 std::default_random_engine generator(seed);
170 std::uniform_int_distribution<int32_t> distribution(0, INT32_MAX);
171 randomNumber = distribution(generator);
172 std::vector<uint8_t> sessionKey;
173 ret = GetSessionKey(userId, randomNumber, sessionKey);
174 } while (ret == DP_SUCCESS);
175 sessionKeyId = randomNumber;
176 HILOGI("success! userId : %{public}u, sessionKeyId : %{public}d", userId, sessionKeyId);
177 return;
178 }
179 } // namespace DistributedDeviceProfile
180 } // namespace OHOS
181