1 /*
2  * Copyright (C) 2021-2022 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 "wifi_common_util.h"
17 #include <fstream>
18 #include <sstream>
19 #include <iterator>
20 #include <regex>
21 
22 #ifndef OHOS_ARCH_LITE
23 #include <vector>
24 #include <openssl/bio.h>
25 #include <openssl/evp.h>
26 #include <openssl/pem.h>
27 #include <openssl/x509.h>
28 #include "app_mgr_client.h"
29 #include "bundle_mgr_interface.h"
30 #include "if_system_ability_manager.h"
31 #include "ipc_skeleton.h"
32 #include "iservice_registry.h"
33 #include "system_ability_definition.h"
34 #include "common_timer_errors.h"
35 #endif
36 #include "wifi_logger.h"
37 #include <ifaddrs.h>
38 #include <net/if.h>
39 #include <netdb.h>
40 #include <cerrno>
41 
42 namespace OHOS {
43 namespace Wifi {
44 DEFINE_WIFILOG_LABEL("WifiCommonUtil");
45 
46 constexpr int PRIFIX_IP_LEN = 3;
47 constexpr int PRIFIX_P2P_LEN = 3;
48 constexpr int PRIFIX_CHBA_LEN = 4;
49 constexpr int PRIFIX_WLAN1_LEN = 5;
50 constexpr int FREQ_2G_MIN = 2412;
51 constexpr int FREQ_2G_MAX = 2472;
52 constexpr int FREQ_5G_MIN = 5170;
53 constexpr int FREQ_5G_MAX = 5825;
54 constexpr int CHANNEL_14_FREQ = 2484;
55 constexpr int CHANNEL_14 = 14;
56 constexpr int CENTER_FREQ_DIFF = 5;
57 constexpr int CHANNEL_2G_MIN = 1;
58 constexpr int CHANNEL_5G_MIN = 34;
59 constexpr int MIN_24G_CHANNEL = 1;
60 constexpr int MAX_24G_CHANNEL = 13;
61 constexpr int MIN_5G_CHANNEL = 36;
62 constexpr int MAX_5G_CHANNEL = 165;
63 constexpr int FREQ_CHANNEL_1 = 2412;
64 constexpr int FREQ_CHANNEL_36 = 5180;
65 constexpr int SECOND_TO_MICROSECOND = 1000 * 1000;
66 constexpr int MICROSECOND_TO_NANOSECOND = 1000;
67 constexpr char HIDDEN_CHAR_SHOW_AS = '*';
68 constexpr int PASSWORD_MIN_LEN = 8;
69 constexpr int PASSWORD_NO_HIDDEN_LEN = 2;
70 
71 constexpr uint32_t BASE_BIN = 2;
72 constexpr uint32_t BASE_HEX = 16;
73 constexpr uint32_t MAX_INT32_LENGTH = 11; // -2147483648 ~ 2147483647
74 constexpr uint32_t MAX_INT64_LENGTH = 20; // -9223372036854775808 ~ 9223372036854775807
75 constexpr uint32_t MAX_INT32_LENGTH_BIN = 32;
76 constexpr uint32_t MAX_INT32_LENGTH_HEX = 8;
77 
78 const uint32_t BASE64_UNIT_ONE_PADDING = 1;
79 const uint32_t BASE64_UNIT_TWO_PADDING = 2;
80 const uint32_t BASE64_SRC_UNIT_SIZE = 3;
81 const uint32_t BASE64_DEST_UNIT_SIZE = 4;
82 
83 static std::pair<std::string, int> g_brokerProcessInfo;
84 static constexpr uint8_t STEP_2BIT = 2;
85 static constexpr uint8_t HEX_OFFSET = 4;
86 static constexpr char HEX_TABLE[] = "0123456789ABCDEF";
87 
DataAnonymize(const std::string str,const char delim,const char hiddenCh,const int startIdx=0)88 static std::string DataAnonymize(const std::string str, const char delim,
89     const char hiddenCh, const int startIdx = 0)
90 {
91     std::string s = str;
92     constexpr auto minDelimSize = 2;
93     constexpr auto minKeepSize = 6;
94     if (std::count(s.begin(), s.end(), delim) < minDelimSize) {
95         if (s.size() <= minKeepSize) {
96             return std::string(s.size(), hiddenCh);
97         }
98         auto idx1 = 2;
99         const auto idx2 = static_cast<int>(s.size() - 4);
100         while (idx1++ < idx2) {
101             s[idx1] = hiddenCh;
102         }
103         return s;
104     }
105 
106     std::string::size_type begin = s.find_first_of(delim);
107     std::string::size_type end = s.find_last_of(delim);
108     int idx = 0;
109     while (idx++ < startIdx && begin < end) {
110         begin = s.find_first_of(delim, begin + 1);
111     }
112     while (begin++ != end) {
113         if (s[begin] != delim) {
114             s[begin] = hiddenCh;
115         }
116     }
117     return s;
118 }
119 
MacAnonymize(const std::string str)120 std::string MacAnonymize(const std::string str)
121 {
122     return DataAnonymize(str, ':', '*', 1);
123 }
124 
IpAnonymize(const std::string str)125 std::string IpAnonymize(const std::string str)
126 {
127     return DataAnonymize(str, '.', '*');
128 }
129 
SsidAnonymize(const std::string str)130 std::string SsidAnonymize(const std::string str)
131 {
132     if (str.empty()) {
133         return str;
134     }
135 
136     std::string s = str;
137     constexpr char hiddenChar = '*';
138     constexpr size_t minHiddenSize = 3;
139     constexpr size_t headKeepSize = 3;
140     constexpr size_t tailKeepSize = 3;
141     auto func = [hiddenChar](char& c) { c = hiddenChar; };
142     if (s.size() < minHiddenSize) {
143         std::for_each(s.begin(), s.end(), func);
144         return s;
145     }
146 
147     if (s.size() < (minHiddenSize + headKeepSize + tailKeepSize)) {
148         size_t beginIndex = 1;
149         size_t hiddenSize = s.size() - minHiddenSize + 1;
150         hiddenSize = hiddenSize > minHiddenSize ? minHiddenSize : hiddenSize;
151         std::for_each(s.begin() + beginIndex, s.begin() + beginIndex + hiddenSize, func);
152         return s;
153     }
154     std::for_each(s.begin() + headKeepSize, s.begin() + s.size() - tailKeepSize, func);
155     return s;
156 }
157 
PassWordAnonymize(const std::string str)158 std::string PassWordAnonymize(const std::string str)
159 {
160     if (str.size() < PASSWORD_MIN_LEN) {
161         WIFI_LOGE("Password should not shorter than 8");
162         return "";
163     }
164     std::string s = str;
165     auto func = [](char& c) { c = HIDDEN_CHAR_SHOW_AS; };
166     std::for_each(s.begin() + PASSWORD_NO_HIDDEN_LEN, s.end() - PASSWORD_NO_HIDDEN_LEN, func);
167     return s;
168 }
169 
ConvertStrChar(char ch)170 static unsigned char ConvertStrChar(char ch)
171 {
172     constexpr int numDiffForHexAlphabet = 10;
173     if (ch >= '0' && ch <= '9') {
174         return (ch - '0');
175     }
176     if (ch >= 'A' && ch <= 'F') {
177         return (ch - 'A' + numDiffForHexAlphabet);
178     }
179     if (ch >= 'a' && ch <= 'f') {
180         return (ch - 'a' + numDiffForHexAlphabet);
181     }
182     return 0;
183 }
184 
MacStrToArray(const std::string & strMac,unsigned char mac[WIFI_MAC_LEN])185 errno_t MacStrToArray(const std::string& strMac, unsigned char mac[WIFI_MAC_LEN])
186 {
187     constexpr int strMacLen = 18;
188     char tempArray[strMacLen] = { 0 };
189     errno_t ret = memcpy_s(tempArray, strMacLen, strMac.c_str(), strMac.size() + 1);
190     if (ret != EOK) {
191         return ret;
192     }
193 
194     int idx = 0;
195     constexpr int bitWidth = 4;
196     char *ptr = nullptr;
197     char *p = strtok_s(tempArray, ":", &ptr);
198     while ((p != nullptr) && (idx < WIFI_MAC_LEN)) {
199         mac[idx++] = (ConvertStrChar(*p) << bitWidth) | ConvertStrChar(*(p + 1));
200         p = strtok_s(nullptr, ":", &ptr);
201     }
202     return EOK;
203 }
204 
ConvertArrayChar(unsigned char ch)205 static char ConvertArrayChar(unsigned char ch)
206 {
207     constexpr int maxDecNum = 9;
208     constexpr int numDiffForHexAlphabet = 10;
209     if (ch <= maxDecNum) {
210         return '0' + ch;
211     }
212     if (ch <= 0xf) {
213         return ch + 'a' - numDiffForHexAlphabet;
214     }
215     return '0';
216 }
217 
MacArrayToStr(const unsigned char mac[WIFI_MAC_LEN])218 std::string MacArrayToStr(const unsigned char mac[WIFI_MAC_LEN])
219 {
220     constexpr int bitWidth = 4;
221     constexpr int noColonBit = 5;
222     std::stringstream ss;
223     for (int i = 0; i != WIFI_MAC_LEN; ++i) {
224         ss << ConvertArrayChar(mac[i] >> bitWidth) << ConvertArrayChar(mac[i] & 0xf);
225         if (i != noColonBit) {
226             ss << ":";
227         }
228     }
229     return ss.str();
230 }
231 
IsMacArrayEmpty(const unsigned char mac[WIFI_MAC_LEN])232 bool IsMacArrayEmpty(const unsigned char mac[WIFI_MAC_LEN])
233 {
234     for (int i = 0; i != WIFI_MAC_LEN; ++i) {
235         if (mac[i] != 0) {
236             return false;
237         }
238     }
239     return true;
240 }
241 
Ip2Number(const std::string & strIp)242 unsigned int Ip2Number(const std::string& strIp)
243 {
244     std::string::size_type front = 0;
245     std::string::size_type back = 0;
246     unsigned int number = 0;
247     int size = 32;
248     constexpr int sectionSize = 8;
249 
250     std::string ip(strIp + '.');
251     while ((back = ip.find_first_of('.', back)) != (std::string::size_type)std::string::npos) {
252         number |= static_cast<unsigned long>(std::stol(ip.substr(front, back - front).c_str()) <<
253             (size -= sectionSize));
254         front = ++back;
255     }
256     return number;
257 }
258 
Number2Ip(unsigned int intIp)259 std::string Number2Ip(unsigned int intIp)
260 {
261     constexpr int fourthPartMoveLen = 24;
262     constexpr int thirdPartMoveLen = 16;
263     constexpr int secondPartMoveLen = 8;
264 
265     std::string ip;
266     ip.append(std::to_string((intIp & 0xff000000) >> fourthPartMoveLen));
267     ip.push_back('.');
268     ip.append(std::to_string((intIp & 0x00ff0000) >> thirdPartMoveLen));
269     ip.push_back('.');
270     ip.append(std::to_string((intIp & 0x0000ff00) >> secondPartMoveLen));
271     ip.push_back('.');
272     ip.append(std::to_string(intIp & 0x000000ff));
273     return ip;
274 }
275 
StrSplit(const std::string & str,const std::string & delim)276 std::vector<std::string> StrSplit(const std::string& str, const std::string& delim) {
277     std::regex re(delim);
278     std::sregex_token_iterator
279         first{ str.begin(), str.end(), re, -1 },
280         last;
281     return { first, last };
282 }
283 
GetElapsedMicrosecondsSinceBoot()284 int64_t GetElapsedMicrosecondsSinceBoot()
285 {
286     struct timespec times = {0, 0};
287     clock_gettime(CLOCK_BOOTTIME, &times);
288     return static_cast<int64_t>(times.tv_sec) * SECOND_TO_MICROSECOND + times.tv_nsec / MICROSECOND_TO_NANOSECOND;
289 }
290 
291 #ifndef OHOS_ARCH_LITE
GetBundleManager()292 sptr<AppExecFwk::IBundleMgr> GetBundleManager()
293 {
294     sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
295     if (systemManager == nullptr) {
296         WIFI_LOGE("Get system ability manager failed!");
297         return nullptr;
298     }
299     return iface_cast<AppExecFwk::IBundleMgr>(systemManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID));
300 }
301 
GetBundleName()302 std::string GetBundleName()
303 {
304     sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
305     if (bundleInstance == nullptr) {
306         WIFI_LOGE("bundle instance is null!");
307         return "";
308     }
309 
310     AppExecFwk::BundleInfo bundleInfo;
311     auto ret = bundleInstance->GetBundleInfoForSelf(0, bundleInfo);
312     if (ret != OHOS::ERR_OK) {
313         return "";
314     }
315 
316     WIFI_LOGI("Get bundle name uid[%{public}d]: %{public}s", bundleInfo.uid, bundleInfo.name.c_str());
317     return bundleInfo.name;
318 }
319 
GetBundleAppIdByBundleName(const int userId,const std::string & bundleName)320 std::string GetBundleAppIdByBundleName(const int userId, const std::string &bundleName)
321 {
322     sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
323     if (bundleInstance == nullptr) {
324         WIFI_LOGE("bundle instance is null!");
325         return "";
326     }
327 
328     AppExecFwk::BundleInfo bundleInfo;
329     AppExecFwk::GetBundleInfoFlag bundleInfoFlag = AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO;
330     auto ret = bundleInstance->GetBundleInfoV9(bundleName, static_cast<int32_t>(bundleInfoFlag), bundleInfo, userId);
331     if (ret != OHOS::ERR_OK) {
332         return "";
333     }
334     return bundleInfo.signatureInfo.appIdentifier;
335 }
336 
GetBundleNameByUid(const int uid,std::string & bundleName)337 ErrCode GetBundleNameByUid(const int uid, std::string &bundleName)
338 {
339     sptr<AppExecFwk::IBundleMgr> bundleInstance = GetBundleManager();
340     if (bundleInstance == nullptr) {
341         WIFI_LOGE("%{public}s bundle instance is null!", __FUNCTION__);
342         return WIFI_OPT_FAILED;
343     }
344     if (!bundleInstance->GetBundleNameForUid(uid, bundleName)) {
345         WIFI_LOGD("%{public}s get bundleName failed", __FUNCTION__);
346         return WIFI_OPT_FAILED;
347     }
348     return WIFI_OPT_SUCCESS;
349 }
350 
GetCallingPid()351 int GetCallingPid()
352 {
353     return IPCSkeleton::GetCallingPid();
354 }
355 
GetCallingUid()356 int GetCallingUid()
357 {
358     return IPCSkeleton::GetCallingUid();
359 }
360 
GetCallingTokenId()361 int GetCallingTokenId()
362 {
363     return IPCSkeleton::GetCallingTokenID();
364 }
365 
GetBrokerProcessNameByPid(const int uid,const int pid)366 std::string GetBrokerProcessNameByPid(const int uid, const int pid)
367 {
368     std::string processName = "";
369     if (g_brokerProcessInfo.second == pid) {
370         processName = g_brokerProcessInfo.first;
371     }
372     return processName;
373 }
374 
SetWifiBrokerProcess(int pid,std::string processName)375 void SetWifiBrokerProcess(int pid, std::string processName)
376 {
377     WIFI_LOGD("enter SetWifiBrokerProcess");
378     g_brokerProcessInfo = make_pair(processName, pid);
379 }
380 
TimeStats(const std::string desc)381 TimeStats::TimeStats(const std::string desc): m_desc(desc)
382 {
383     m_startTime = std::chrono::steady_clock::now();
384     WIFI_LOGI("[Time stats][start] %{public}s.", m_desc.c_str());
385 }
386 
~TimeStats()387 TimeStats::~TimeStats()
388 {
389     auto us = std::chrono::duration_cast<std::chrono::microseconds>
390         (std::chrono::steady_clock::now() - m_startTime).count();
391     constexpr int TIME_BASE = 1000;
392     WIFI_LOGI("[Time stats][end] %{public}s, time cost:%{public}lldus, %{public}lldms, %{public}llds",
393         m_desc.c_str(), us, us / TIME_BASE, us / TIME_BASE / TIME_BASE);
394 }
395 #endif
396 
FrequencyToChannel(int freq)397 int FrequencyToChannel(int freq)
398 {
399     WIFI_LOGD("FrequencyToChannel: %{public}d", freq);
400     int channel = INVALID_FREQ_OR_CHANNEL;
401     if (freq >= FREQ_2G_MIN && freq <= FREQ_2G_MAX) {
402         channel = (freq - FREQ_2G_MIN) / CENTER_FREQ_DIFF + CHANNEL_2G_MIN;
403     } else if (freq == CHANNEL_14_FREQ) {
404         channel = CHANNEL_14;
405     } else if (freq >= FREQ_5G_MIN && freq <= FREQ_5G_MAX) {
406         channel = (freq - FREQ_5G_MIN) / CENTER_FREQ_DIFF + CHANNEL_5G_MIN;
407     }
408     return channel;
409 }
410 
ChannelToFrequency(int channel)411 int ChannelToFrequency(int channel)
412 {
413     WIFI_LOGI("ChannelToFrequency: %{public}d", channel);
414     if (channel >= MIN_24G_CHANNEL && channel <= MAX_24G_CHANNEL) {
415         return ((channel - MIN_24G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_1);
416     }
417     if (MIN_5G_CHANNEL <= channel && channel <= MAX_5G_CHANNEL) {
418         return ((channel - MIN_5G_CHANNEL) * CENTER_FREQ_DIFF + FREQ_CHANNEL_36);
419     }
420     return INVALID_FREQ_OR_CHANNEL;
421 }
422 
IsOtherVapConnect()423 bool IsOtherVapConnect()
424 {
425     WIFI_LOGD("Enter IsOtherVapConnect");
426     int n;
427     int ret;
428     struct ifaddrs *ifaddr = nullptr;
429     struct ifaddrs *ifa = nullptr;
430     bool p2pOrHmlConnected = false;
431     bool hotspotEnable = false;
432     if (getifaddrs(&ifaddr) == -1) {
433         WIFI_LOGE("getifaddrs failed, error is %{public}d", errno);
434         return false;
435     }
436     for (ifa = ifaddr, n = 0; ifa != nullptr; ifa = ifa->ifa_next, n++) {
437         if (ifa->ifa_addr == nullptr) {
438             continue;
439         }
440         /* For an AF_INET interface address, display the address */
441         int family = ifa->ifa_addr->sa_family;
442         char ipAddress[NI_MAXHOST] = {0}; /* IP address storage */
443         if (family == AF_INET) {
444             ret = getnameinfo(ifa->ifa_addr,
445                 sizeof(struct sockaddr_in),
446                 ipAddress,
447                 NI_MAXHOST,
448                 nullptr,
449                 0,
450                 NI_NUMERICHOST);
451             if (ret != 0) {
452                 WIFI_LOGE("getnameinfo() failed: %{public}s\n", gai_strerror(ret));
453                 return false;
454             }
455         }
456         if (strncmp("192", ipAddress, PRIFIX_IP_LEN) != 0 && strncmp("172", ipAddress, PRIFIX_IP_LEN) != 0) {
457             continue;
458         }
459         if ((strncmp("p2p", ifa->ifa_name, PRIFIX_P2P_LEN) == 0 ||
460              strncmp("chba", ifa->ifa_name, PRIFIX_CHBA_LEN) == 0)) {
461             p2pOrHmlConnected = true;
462         }
463         if (strncmp("wlan1", ifa->ifa_name, PRIFIX_WLAN1_LEN) == 0) {
464             hotspotEnable = true;
465         }
466     }
467     freeifaddrs(ifaddr);
468     return p2pOrHmlConnected && hotspotEnable;
469 }
470 
Hex2num(char c)471 static int Hex2num(char c)
472 {
473     if (c >= '0' && c <= '9') {
474         return c - '0';
475     }
476     if (c >= 'a' && c <= 'f') {
477         return c - 'a' + 10; // convert to decimal
478     }
479     if (c >= 'A' && c <= 'F') {
480         return c - 'A' + 10; // convert to decimal
481     }
482     return -1;
483 }
484 
Hex2byte(const char * hex)485 int Hex2byte(const char *hex)
486 {
487     int a = Hex2num(*hex++);
488     if (a < 0) {
489         return -1;
490     }
491     int b = Hex2num(*hex++);
492     if (b < 0) {
493         return -1;
494     }
495     return (a << 4) | b; // convert to binary
496 }
497 
HexString2Byte(const char * hex,uint8_t * buf,size_t len)498 int HexString2Byte(const char *hex, uint8_t *buf, size_t len)
499 {
500     size_t i;
501     int a;
502     const char *ipos = hex;
503     uint8_t *opos = buf;
504 
505     for (i = 0; i < len; i++) {
506         a = Hex2byte(ipos);
507         if (a < 0) {
508             return -1;
509         }
510         *opos++ = a;
511         ipos += 2; // convert to binary
512     }
513     return 0;
514 }
515 
Byte2HexString(const uint8_t * byte,uint8_t bytesLen,char * hexstr,uint8_t hexstrLen)516 void Byte2HexString(const uint8_t* byte, uint8_t bytesLen, char* hexstr, uint8_t hexstrLen)
517 {
518     if ((byte == nullptr) || (hexstr == nullptr)) {
519         WIFI_LOGE("%{public}s: invalid parameter", __func__);
520         return;
521     }
522 
523     if (hexstrLen < bytesLen * 2) { // verify length
524         WIFI_LOGE("%{public}s: invalid byteLen:%{public}d or hexStrLen:%{public}d",
525             __func__, bytesLen, hexstrLen);
526         return;
527     }
528 
529     WIFI_LOGI("%{public}s byteLen:%{public}d, hexStrLen:%{public}d", __func__, bytesLen, hexstrLen);
530     uint8_t hexstrIndex = 0;
531     for (uint8_t i = 0; i < bytesLen; i++) {
532         if (snprintf_s(hexstr + hexstrIndex, hexstrLen - hexstrIndex, hexstrLen - hexstrIndex - 1,
533             "%02x", byte[i]) <= 0) {
534             WIFI_LOGI("%{public}s: failed to snprintf_s", __func__);
535         }
536         hexstrIndex += 2; // offset
537         if (hexstrIndex >= hexstrLen) {
538             break;
539         }
540     }
541 }
542 
DecodeBase64(const std::string & input,std::vector<uint8_t> & output)543 bool DecodeBase64(const std::string &input, std::vector<uint8_t> &output)
544 {
545 #ifndef OHOS_ARCH_LITE
546     WIFI_LOGD("%{public}s input:%{private}s, length:%{public}zu", __func__, input.c_str(), input.length());
547     if (input.length() % BASE64_DEST_UNIT_SIZE != 0) {
548         WIFI_LOGE("%{public}s: wrong data length for base64 encode string", __func__);
549         return false;
550     }
551     uint32_t decodedLen = input.length() * BASE64_SRC_UNIT_SIZE / BASE64_DEST_UNIT_SIZE;
552     if (input.at(input.length() - BASE64_UNIT_ONE_PADDING) == '=') {
553         decodedLen--;
554         if (input.at(input.length() - BASE64_UNIT_TWO_PADDING) == '=') {
555             decodedLen--;
556         }
557     }
558     output.resize(decodedLen);
559 
560     BIO *b64 = BIO_new(BIO_f_base64());
561     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
562     BIO *bio = BIO_new_mem_buf(input.c_str(), input.length());
563     bio = BIO_push(b64, bio);
564     if (BIO_read(bio, &output[0], input.length()) != static_cast<int32_t>(decodedLen)) {
565         WIFI_LOGE("%{public}s: wrong data length for decoded buffer", __func__);
566         return false;
567     }
568     BIO_free_all(bio);
569 #endif
570     return true;
571 }
572 
EncodeBase64(const std::vector<uint8_t> & input)573 std::string EncodeBase64(const std::vector<uint8_t> &input)
574 {
575 #ifndef OHOS_ARCH_LITE
576     WIFI_LOGD("%{public}s: size:%{public}zu", __func__, input.size());
577     if (input.empty()) {
578         WIFI_LOGE("%{public}s: wrong data length for string to encode.", __func__);
579         return "";
580     }
581     BIO *b64 = BIO_new(BIO_f_base64());
582     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
583     BIO *bio = BIO_new(BIO_s_mem());
584     bio = BIO_push(b64, bio);
585     BIO_write(bio, &input[0], input.size());
586     BIO_flush(bio);
587 
588     BUF_MEM *bptr = nullptr;
589     BIO_get_mem_ptr(bio, &bptr);
590     std::string output = "";
591     if (bptr != nullptr) {
592         std::vector<char> outputBuffer {};
593         WIFI_LOGI("%{public}s: length is %{public}zu", __func__, bptr->length);
594         outputBuffer.insert(outputBuffer.end(), bptr->data, bptr->data + bptr->length);
595         outputBuffer[bptr->length] = 0;
596         output = static_cast<char*>(&outputBuffer[0]);
597     }
598     BIO_free_all(bio);
599     return output;
600 #else
601     return "";
602 #endif
603 }
604 
getAuthInfo(const std::string & input,const std::string & delimiter)605 std::vector<std::string> getAuthInfo(const std::string &input, const std::string &delimiter)
606 {
607     size_t pos = 0;
608     std::string token;
609     std::vector<std::string> results;
610 
611     std::string splitStr = input;
612     WIFI_LOGD("%{public}s input:%{private}s, delimiter:%{public}s", __func__, input.c_str(), delimiter.c_str());
613     while ((pos = splitStr.find(delimiter)) != std::string::npos) {
614         token = splitStr.substr(0, pos);
615         if (token.length() > 0) {
616             results.push_back(token);
617             splitStr.erase(0, pos + delimiter.length());
618             WIFI_LOGD("%{public}s token:%{private}s, splitStr:%{public}s", __func__, token.c_str(), splitStr.c_str());
619         }
620     }
621     results.push_back(splitStr);
622     WIFI_LOGD("%{public}s size:%{public}zu", __func__, results.size());
623     return results;
624 }
625 
HexToString(const std::string & str)626 std::string HexToString(const std::string &str)
627 {
628     std::string result;
629     if (str.length() <= 0) {
630         return result;
631     }
632     for (size_t i = 0; i < str.length() - 1; i += STEP_2BIT) {
633         std::string byte = str.substr(i, STEP_2BIT);
634         char chr = 0;
635         int strTemp = CheckDataLegalHex(byte);
636         if (strTemp > 0) {
637             chr = static_cast<char>(strTemp);
638         }
639         result.push_back(chr);
640     }
641     return result;
642 }
643 
StringToHex(const std::string & data)644 std::string StringToHex(const std::string &data)
645 {
646     std::stringstream ss;
647     for (std::string::size_type i = 0; i < data.size(); ++i) {
648         unsigned char temp = static_cast<unsigned char>(data[i]) >> HEX_OFFSET;
649         ss << HEX_TABLE[temp] << HEX_TABLE[static_cast<unsigned char>(data[i]) & 0xf];
650     }
651     return ss.str();
652 }
653 
CheckDataLegalBin(const std::string & data)654 int CheckDataLegalBin(const std::string &data)
655 {
656     if (data.empty() || data.size() > MAX_INT32_LENGTH_BIN) {
657         WIFI_LOGE("CheckDataLegalBin: invalid data:%{private}s", data.c_str());
658         return 0;
659     }
660 
661     std::regex pattern("[0-1]+");
662     if (!std::regex_match(data, pattern)) {
663         return 0;
664     }
665     errno = 0;
666     char *endptr = nullptr;
667     long int num = std::strtol(data.c_str(), &endptr, BASE_BIN);
668     if (errno == ERANGE) {
669         WIFI_LOGE("CheckDataLegalBin errno == ERANGE, data:%{private}s", data.c_str());
670         return 0;
671     }
672 
673     return static_cast<int>(num);
674 }
675 
CheckDataLegalHex(const std::string & data)676 int CheckDataLegalHex(const std::string &data)
677 {
678     if (data.empty() || data.size() > MAX_INT32_LENGTH_HEX) {
679         WIFI_LOGE("CheckDataLegalHex: invalid data:%{private}s", data.c_str());
680         return 0;
681     }
682 
683     std::regex pattern("[0-9|a-f|A-F]+");
684     if (!std::regex_match(data, pattern)) {
685         return 0;
686     }
687     errno = 0;
688     char *endptr = nullptr;
689     long int num = std::strtol(data.c_str(), &endptr, BASE_HEX);
690     if (errno == ERANGE) {
691         WIFI_LOGE("CheckDataLegalHex errno == ERANGE, data:%{private}s", data.c_str());
692         return 0;
693     }
694 
695     return static_cast<int>(num);
696 }
697 
CheckDataLegal(std::string & data,int base)698 int CheckDataLegal(std::string &data, int base)
699 {
700     if (data.empty() || data.size() > MAX_INT32_LENGTH) {
701         WIFI_LOGE("CheckDataLegal: invalid data:%{private}s", data.c_str());
702         return 0;
703     }
704 
705     std::regex pattern("-?\\d+");
706     if (!std::regex_match(data, pattern)) {
707         return 0;
708     }
709     errno = 0;
710     char *endptr = nullptr;
711     long int num = std::strtol(data.c_str(), &endptr, base);
712     if (errno == ERANGE) {
713         WIFI_LOGE("CheckDataLegal errno == ERANGE, data:%{private}s", data.c_str());
714         return 0;
715     }
716 
717     return static_cast<int>(num);
718 }
719 
CheckDataToUint(std::string & data,int base)720 unsigned int CheckDataToUint(std::string &data, int base)
721 {
722     std::regex pattern("\\d+");
723     std::regex pattern1("\\d+");
724     if (!std::regex_search(data, pattern) || !std::regex_search(data, pattern1)) {
725         WIFI_LOGE("CheckDataToUint regex unsigned int value fail, data:%{private}s", data.c_str());
726         return 0;
727     }
728 
729     errno = 0;
730     char *endptr = nullptr;
731     unsigned long int num = std::strtoul(data.c_str(), &endptr, base);
732     if (errno == ERANGE) {
733         WIFI_LOGE("CheckDataToUint errno == ERANGE, data:%{private}s", data.c_str());
734         return 0;
735     }
736 
737     return static_cast<unsigned int>(num);
738 }
739 
CheckDataTolonglong(std::string & data,int base)740 long long CheckDataTolonglong(std::string &data, int base)
741 {
742     if (data.empty() || data.size() > MAX_INT64_LENGTH) {
743         WIFI_LOGE("CheckDataTolonglong: invalid data:%{private}s", data.c_str());
744         return 0;
745     }
746 
747     std::regex pattern("-?\\d+");
748     if (!std::regex_match(data, pattern)) {
749         return 0;
750     }
751     errno = 0;
752     char *endptr = nullptr;
753     long long int num = std::strtoll(data.c_str(), &endptr, base);
754     if (errno == ERANGE) {
755         WIFI_LOGE("CheckDataTolonglong errno == ERANGE, data:%{private}s", data.c_str());
756         return 0;
757     }
758     return num;
759 }
760 }  // namespace Wifi
761 }  // namespace OHOS
762