1 /*
2 * Copyright (c) 2021 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 <sstream>
17 #include <iomanip>
18
19 #include "device_manager_log.h"
20 #include "constants.h"
21 #include "encrypt_utils.h"
22 #include "device_manager_errno.h"
23 #include "device_manager_log.h"
24 #include "encrypt_utils.h"
25 #include "msg_request_auth.h"
26 #include "parameter.h"
27 #include "softbus_session.h"
28 #include "softbus_bus_center.h"
29 #include "msg_request_auth.h"
30
31 namespace OHOS {
32 namespace DistributedHardware {
MsgRequestAuth(std::string & token,std::string hostPkgName,std::string targetPkgName,const int32_t groupVisibility,const DmDeviceInfo & devReqInfo,const DmAppImageInfo & imageInfo,std::string & extras)33 MsgRequestAuth::MsgRequestAuth(std::string &token, std::string hostPkgName, std::string targetPkgName,
34 const int32_t groupVisibility, const DmDeviceInfo& devReqInfo, const DmAppImageInfo &imageInfo,
35 std::string &extras)
36 {
37 DMLOG(DM_LOG_INFO, "MsgRequestAuth construction started");
38 nlohmann::json jsonObject = nlohmann::json::parse(extras, nullptr, false);
39 if (jsonObject.is_discarded()) {
40 DMLOG(DM_LOG_ERROR, "MsgRequestAuth error");
41 return;
42 }
43 if (!jsonObject.contains(APP_NAME_KEY) || !jsonObject.contains(APP_DESCRIPTION_KEY)) {
44 DMLOG(DM_LOG_ERROR, "MsgRequestAuth, err json string");
45 return;
46 }
47
48 mAuthType_ = jsonObject.contains(AUTH_TYPE) ? (int32_t)jsonObject[AUTH_TYPE] : AUTH_TYPE_QR;
49 mHead_ = std::make_shared<MsgHead>((mAuthType_ == AUTH_TYPE_QR) ? (DmMsgType::MSG_TYPE_REQ_AUTH) :
50 (DmMsgType::MSG_TYPE_AUTH_BY_PIN));
51 std::string deviceManagerPkgName = "ohos.distributedhardware.devicemanager";
52 NodeBasicInfo localBasicInfo;
53 int32_t ret = GetLocalNodeDeviceInfo(deviceManagerPkgName.c_str(), &localBasicInfo);
54 if (ret != 0) {
55 DMLOG(DM_LOG_ERROR, "GetLocalNodeDeviceInfo err: %d", ret);
56 return;
57 }
58 mDeviceName_ = localBasicInfo.deviceName;
59 char localDeviceId[DEVICE_UUID_LENGTH] = {0};
60 GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
61 mDeviceId_ = localDeviceId;
62 mToken_ = token;
63 mHostPkg_ = hostPkgName;
64 mTargetPkg_ = targetPkgName;
65 mGroupVisibility_ = groupVisibility;
66 mAppName_ = jsonObject[APP_NAME_KEY];
67 mAppDescription_ = jsonObject[APP_DESCRIPTION_KEY];
68 mImageInfo_ = imageInfo;
69 mThumbnailSize_ = mImageInfo_.GetAppThumbnailLen();
70 mAppIconSize_ = mImageInfo_.GetAppIconLen();
71 mDeviceType_ = ToHexString(localBasicInfo.deviceTypeId);
72 DMLOG(DM_LOG_INFO, "MsgRequestAuth construction completed");
73 }
74
GetEncodedAppInfo(const uint8_t * dataSrc,int32_t srcLen,std::string & outString)75 int32_t MsgRequestAuth::GetEncodedAppInfo(const uint8_t *dataSrc, int32_t srcLen, std::string &outString)
76 {
77 DMLOG(DM_LOG_INFO, "MsgRequestAuth GetEncodedAppInfo started");
78 if (srcLen <= 0 || dataSrc == nullptr) {
79 DMLOG(DM_LOG_ERROR, "data string is empty");
80 return DEVICEMANAGER_OK;
81 }
82
83 int32_t tempBufLen = ((srcLen / BASE64_BYTE_LEN_3) + 1) * BASE64_BYTE_LEN_4 + 1;
84 char *tmpBuf = (char *)calloc(sizeof(char), tempBufLen);
85 if (tmpBuf == nullptr) {
86 DMLOG(DM_LOG_ERROR, "getEncodedAppInfoString: malloc mem error, size %d", tempBufLen);
87 return DEVICEMANAGER_MALLOC_ERROR;
88 }
89
90 size_t outLen = 0;
91 int32_t ret = EncryptUtils::MbedtlsBase64Encode((uint8_t *)tmpBuf, tempBufLen, &outLen, dataSrc, (size_t)srcLen);
92 if (ret != 0) {
93 DMLOG(DM_LOG_ERROR, "MbedtlsBase64Encode error");
94 free(tmpBuf);
95 return ENCODE_DATA_ERROR;
96 }
97 outString = tmpBuf;
98 free(tmpBuf);
99 tmpBuf = nullptr;
100 DMLOG(DM_LOG_INFO, "MsgRequestAuth GetEncodedAppInfo completed");
101 return DEVICEMANAGER_OK;
102 }
103
GetDecodeAppInfo(const std::string appString,uint8_t ** outBuffer,int32_t & outBufferLen)104 void MsgRequestAuth::GetDecodeAppInfo(const std::string appString, uint8_t **outBuffer, int32_t &outBufferLen)
105 {
106 DMLOG(DM_LOG_INFO, "MsgRequestAuth GetDecodeAppInfo started");
107 int32_t tempBufLen = appString.length() + 1;
108 uint8_t *buffer = (uint8_t *)calloc(sizeof(char), tempBufLen);
109 if (buffer == nullptr) {
110 DMLOG(DM_LOG_ERROR, "GetDecodeAppInfo: malloc mem error, tempBufLen %d", tempBufLen);
111 return;
112 }
113
114 size_t outLen = 0;
115 int32_t ret = EncryptUtils::MbedtlsBase64Decode(buffer, tempBufLen, &outLen,
116 (const uint8_t*)appString.c_str(), appString.length());
117 if (ret != 0 || static_cast<int32_t>(outLen) > tempBufLen) {
118 DMLOG(DM_LOG_ERROR, "MbedtlsBase64Decode failed, ret %d, outLen %d, tempBufLen %d",
119 ret, outLen, tempBufLen);
120 outBufferLen = 0;
121 *outBuffer = nullptr;
122 free(buffer);
123 return;
124 }
125
126 DMLOG(DM_LOG_INFO, "MsgRequestAuth GetDecodeAppInfo outBufferLen %d", outBufferLen);
127 outBufferLen = outLen;
128 *outBuffer = buffer;
129 }
130
EncodeDevInfo()131 std::string MsgRequestAuth::EncodeDevInfo()
132 {
133 DMLOG(DM_LOG_INFO, "MsgRequestAuth EncodeDevInfo started");
134 nlohmann::json jsonObj;
135 mHead_->Encode(jsonObj);
136 jsonObj[TAG_SLICE_NUM] = mMsgSlice_;
137 jsonObj[TAG_INDEX] = 0;
138 jsonObj[TAG_REQUESTER] = mDeviceName_;
139 jsonObj[TAG_DEVICE_ID] = mDeviceId_;
140 jsonObj[TAG_DEVICE_TYPE] = mDeviceType_;
141 jsonObj[TAG_TOKEN] = mToken_;
142 jsonObj[TAG_VISIBILITY] = mGroupVisibility_;
143 if (mGroupVisibility_ == GROUP_VISIBILITY_IS_PRIVATE) {
144 jsonObj[TAG_TARGET] = mTargetPkg_;
145 jsonObj[TAG_HOST] = mHostPkg_;
146 }
147 jsonObj[TAG_APP_NAME] = mAppName_;
148 jsonObj[TAG_APP_DESCRIPTION] = mAppDescription_;
149
150 std::string appIconStr = "";
151 GetEncodedAppInfo(mImageInfo_.GetAppIcon(), mImageInfo_.GetAppIconLen(), appIconStr);
152 jsonObj[TAG_APP_ICON] = appIconStr;
153 jsonObj[TAG_THUMBNAIL_SIZE] = mThumbnailSize_;
154 jsonObj[TAG_AUTH_TYPE] = mAuthType_;
155 DMLOG(DM_LOG_INFO, "MsgRequestAuth EncodeDevInfo completed");
156 return jsonObj.dump();
157 }
158
DecodeDeviceInfo(nlohmann::json & json,std::shared_ptr<MsgRequestAuth> msg)159 void MsgRequestAuth::DecodeDeviceInfo(nlohmann::json &json, std::shared_ptr<MsgRequestAuth> msg)
160 {
161 msg->mDeviceName_ = json[TAG_REQUESTER];
162 msg->mDeviceId_ = json[TAG_DEVICE_ID];
163 msg->mDeviceType_ = json[TAG_DEVICE_TYPE];
164 msg->mToken_ = json[TAG_TOKEN];
165 msg->mGroupVisibility_ = json[TAG_VISIBILITY];
166 if (msg->mGroupVisibility_ == GROUP_VISIBILITY_IS_PRIVATE) {
167 msg->mTargetPkg_ = json[TAG_TARGET];
168 msg->mHostPkg_ = json[TAG_HOST];
169 }
170 msg->mAppName_ = json[TAG_APP_NAME];
171 msg->mAppDescription_ = json[TAG_APP_DESCRIPTION];
172
173 const std::string iconStr = json[TAG_APP_ICON];
174 uint8_t *appIcon = nullptr;
175 int32_t appIconLen = 0;
176 msg->GetDecodeAppInfo(iconStr, &appIcon, appIconLen);
177 if (appIcon != nullptr) {
178 msg->mImageInfo_.ResetIcon(appIcon, appIconLen);
179 free(appIcon);
180 }
181
182 SetThumbnailSize(json, msg);
183 msg->mAuthType_ = json[TAG_AUTH_TYPE];
184 }
185
Encode()186 std::vector<std::string> MsgRequestAuth::Encode()
187 {
188 DMLOG(DM_LOG_INFO, "MsgRequestAuth encode started");
189 std::vector<std::string> jsonStrs;
190 int32_t thumbnailSlice =
191 ((mThumbnailSize_ / MSG_MAX_SIZE) + (mThumbnailSize_ % MSG_MAX_SIZE) == 0 ? 0 : 1);
192 mMsgSlice_ = thumbnailSlice + 1;
193 jsonStrs.push_back(EncodeDevInfo());
194 for (int32_t idx = 0; idx < thumbnailSlice; idx++) {
195 nlohmann::json jsonObj;
196 mHead_->Encode(jsonObj);
197 jsonObj[TAG_SLICE_NUM] = mMsgSlice_;
198 jsonObj[TAG_INDEX] = idx + 1;
199 jsonObj[TAG_DEVICE_ID] = mDeviceId_;
200 jsonObj[TAG_THUMBNAIL_SIZE] = mThumbnailSize_;
201
202 // frag thumbnail by 45KB
203 std::string thumbnailStr = "";
204 int32_t leftLen = mImageInfo_.GetAppThumbnailLen() - idx * MSG_MAX_SIZE;
205 int32_t sliceLen = (leftLen > MSG_MAX_SIZE) ? MSG_MAX_SIZE : leftLen;
206
207 DMLOG(DM_LOG_INFO, "TAG_APP_THUMBNAIL encode, idx %d, encodeLen %d, mThumbnailSize_ %d",
208 idx, sliceLen, mThumbnailSize_);
209
210 const uint8_t *thumbnail = mImageInfo_.GetAppThumbnail();
211 GetEncodedAppInfo(thumbnail + idx * MSG_MAX_SIZE, sliceLen, thumbnailStr);
212 jsonObj[TAG_APP_THUMBNAIL] = thumbnailStr;
213
214 jsonStrs.push_back(jsonObj.dump());
215 }
216 DMLOG(DM_LOG_INFO, "MsgRequestAuth encode completed");
217 return jsonStrs;
218 }
219
Decode(nlohmann::json & json,std::shared_ptr<MsgRequestAuth> msgIn)220 std::shared_ptr<MsgRequestAuth> MsgRequestAuth::Decode(nlohmann::json &json, std::shared_ptr<MsgRequestAuth> msgIn)
221 {
222 if (!json.contains(TAG_INDEX) || !json.contains(TAG_DEVICE_ID) || !json.contains(TAG_SLICE_NUM)) {
223 DMLOG(DM_LOG_ERROR, "err json string, first time");
224 return nullptr;
225 }
226 int32_t idx = json[TAG_INDEX];
227 std::string deviceId = json[TAG_DEVICE_ID];
228 if (!IsMsgValid(msgIn, json, deviceId, idx)) {
229 auto inValidMsg = std::make_shared<MsgRequestAuth>();
230 inValidMsg->mMsgSlice_ = FAIL;
231 return inValidMsg;
232 }
233
234 std::shared_ptr<MsgRequestAuth> msg = msgIn;
235 if (msgIn == nullptr || msgIn->mMsgCnt_ == msgIn->mMsgSlice_) {
236 msg = std::make_shared<MsgRequestAuth>();
237 }
238 msg->mHead_ = MsgHead::Decode(json);
239 msg->mMsgSlice_ = json[TAG_SLICE_NUM];
240 if (idx == 0) {
241 DecodeDeviceInfo(json, msg);
242 } else {
243 SetThumbnailSize(json, msg);
244 msg->mDeviceId_ = deviceId;
245 if (!json.contains(TAG_APP_THUMBNAIL)) {
246 DMLOG(DM_LOG_ERROR, "err json string, TAG_APP_THUMBNAIL not exit");
247 return nullptr;
248 }
249
250 std::string thumbnailStr = json[TAG_APP_THUMBNAIL];
251 uint8_t *thumbnail = nullptr;
252 int32_t thumbnailLen = 0;
253 msg->GetDecodeAppInfo(thumbnailStr, &thumbnail, thumbnailLen);
254 if (thumbnail == nullptr) {
255 DMLOG(DM_LOG_ERROR, "TAG_APP_THUMBNAIL Decode error");
256 return nullptr;
257 }
258
259 DMLOG(DM_LOG_INFO, "TAG_APP_THUMBNAIL decode, idx %d, decodeLen %d, mThumbnailSize_ %d",
260 idx, thumbnailLen, msg->mThumbnailSize_);
261 if (msg->mThumbnailSize_ < thumbnailLen + (idx - 1) * MSG_MAX_SIZE) {
262 auto inValidReqMsg = std::make_shared<MsgRequestAuth>();
263 inValidReqMsg->mMsgSlice_ = FAIL;
264 free(thumbnail);
265 return inValidReqMsg;
266 }
267 msg->mImageInfo_.SetThumbnailData(thumbnail, thumbnailLen, (idx - 1) * MSG_MAX_SIZE, thumbnailLen);
268 free(thumbnail);
269 }
270 msg->mMsgCnt_++;
271 return msg;
272 }
273
GetMsgSlice()274 int32_t MsgRequestAuth::GetMsgSlice()
275 {
276 return mMsgSlice_;
277 }
278
GetMsgCnt()279 int32_t MsgRequestAuth::GetMsgCnt()
280 {
281 return mMsgCnt_;
282 }
283
GetRequestDeviceId()284 std::string MsgRequestAuth::GetRequestDeviceId()
285 {
286 return mDeviceId_;
287 }
288
IsMsgValid(std::shared_ptr<MsgRequestAuth> msgIn,nlohmann::json & json,std::string & deviceId,int32_t index)289 bool MsgRequestAuth::IsMsgValid(std::shared_ptr<MsgRequestAuth> msgIn, nlohmann::json &json,
290 std::string &deviceId, int32_t index)
291 {
292 if (msgIn != nullptr && msgIn->mMsgCnt_ != msgIn->mMsgSlice_ && deviceId.compare(msgIn->mDeviceId_)) {
293 DMLOG(DM_LOG_ERROR, "IsMsgValid, msgIn error");
294 return false;
295 }
296
297 if (!json.contains(TAG_THUMBNAIL_SIZE)) {
298 DMLOG(DM_LOG_ERROR, "IsMsgValid, err json string");
299 return false;
300 }
301
302 if (index < 0 || index >= DES_SLICE_MAX_NUM) {
303 DMLOG(DM_LOG_ERROR, "index err");
304 return false;
305 }
306
307 if (index == 0) {
308 return IsAppInfoValid(json);
309 } else {
310 int32_t thumbnailSlice = json[TAG_THUMBNAIL_SIZE];
311 if (thumbnailSlice > THUMB_MAX_LEN || thumbnailSlice < 0) {
312 DMLOG(DM_LOG_ERROR, "IsMsgValid, thumbnailSlice error");
313 return false;
314 }
315 }
316 return true;
317 }
318
IsAppInfoValid(nlohmann::json & json)319 bool MsgRequestAuth::IsAppInfoValid(nlohmann::json &json)
320 {
321 if (!json.contains(TAG_REQUESTER) || !json.contains(TAG_DEVICE_TYPE) || !json.contains(TAG_TOKEN) ||
322 !json.contains(TAG_VISIBILITY) || !json.contains(TAG_APP_NAME) || !json.contains(TAG_APP_DESCRIPTION) ||
323 !json.contains(TAG_APP_ICON) || !json.contains(TAG_AUTH_TYPE) || !json.contains(TAG_DEVICE_ID)) {
324 DMLOG(DM_LOG_ERROR, "IsAppInfoValid:: err json string");
325 return false;
326 }
327
328 int32_t groupVisibility = json[TAG_VISIBILITY];
329 if (groupVisibility == GROUP_VISIBILITY_IS_PRIVATE) {
330 if (!json.contains(TAG_TARGET) || !json.contains(TAG_HOST)) {
331 DMLOG(DM_LOG_ERROR, "IsAppInfoValid:: err json string, TAG_TARGET or TAG_HOST not contain");
332 return false;
333 }
334 }
335
336 if (json[TAG_APP_ICON].size() > ICON_MAX_LEN) {
337 DMLOG(DM_LOG_ERROR, "IsAppInfoValid, appIcon size error");
338 return false;
339 }
340
341 int32_t thumbnailSize = json[TAG_THUMBNAIL_SIZE];
342 if (thumbnailSize > THUMB_MAX_LEN || thumbnailSize < 0) {
343 DMLOG(DM_LOG_ERROR, "IsAppInfoValid, thumbnailSize error");
344 return false;
345 }
346 return true;
347 }
348
SetAuthType(nlohmann::json & json,std::shared_ptr<MsgRequestAuth> msg)349 void MsgRequestAuth::SetAuthType(nlohmann::json &json, std::shared_ptr<MsgRequestAuth> msg)
350 {
351 int32_t authType = json.contains(TAG_AUTH_TYPE) ? (int32_t)json[TAG_AUTH_TYPE] : AUTH_TYPE_QR;
352 if (authType != AUTH_TYPE_QR && authType != AUTH_TYPE_PIN) {
353 authType = AUTH_TYPE_QR;
354 }
355 msg->mAuthType_ = authType;
356 }
357
SetThumbnailSize(nlohmann::json & json,std::shared_ptr<MsgRequestAuth> msg)358 void MsgRequestAuth::SetThumbnailSize(nlohmann::json &json, std::shared_ptr<MsgRequestAuth> msg)
359 {
360 if (!json.contains(TAG_THUMBNAIL_SIZE)) {
361 DMLOG(DM_LOG_ERROR, "SetThumbnailSize, err json string");
362 return;
363 }
364 int32_t thumbnailSlice = json[TAG_THUMBNAIL_SIZE];
365 if (msg->mThumbnailSize_ == 0) {
366 msg->mImageInfo_.InitThumbnail(thumbnailSlice);
367 msg->mThumbnailSize_ = msg->mImageInfo_.GetAppThumbnailLen();
368 DMLOG(DM_LOG_INFO, "thumbnailSlice %d, mThumbnailSize_ is, %d", thumbnailSlice, msg->mThumbnailSize_);
369 }
370 }
371
ToHexString(int32_t value)372 std::string MsgRequestAuth::ToHexString(int32_t value)
373 {
374 std::stringstream ioss;
375 std::string tmpStr;
376 ioss << std::setiosflags(std::ios::uppercase) << std::hex << value;
377 ioss >> tmpStr;
378 return tmpStr;
379 }
380 }
381 }
382