1 /*
2  * Copyright (c) 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 "security_guard_utils.h"
17 
18 #include <cerrno>
19 #include <fstream>
20 
21 #include "security_guard_log.h"
22 
23 namespace OHOS::Security::SecurityGuard {
24 namespace {
25     constexpr int32_t DEC_RADIX = 10;
26     constexpr int32_t HEX_RADIX = 16;
27     constexpr int32_t STR_INDEX = 2;
28     constexpr int32_t TIME_BUF_LEN = 32;
29     constexpr int32_t FILE_MAX_SIZE = 2 * 1024 * 1024; // byte
30 }
31 
StrToU32(const std::string & str,uint32_t & value)32 bool SecurityGuardUtils::StrToU32(const std::string &str, uint32_t &value)
33 {
34     unsigned long long tmp = 0;
35     bool isOK = StrToULL(str, tmp);
36     value = static_cast<uint32_t>(tmp);
37     return isOK && (tmp <= UINT32_MAX);
38 }
39 
StrToI64(const std::string & str,int64_t & value)40 bool SecurityGuardUtils::StrToI64(const std::string &str, int64_t &value)
41 {
42     long long tmp = 0;
43     bool isOK = StrToLL(str, tmp, DEC_RADIX);
44     value = tmp;
45     return isOK && (tmp >= INT64_MIN && tmp <= INT64_MAX);
46 }
47 
StrToI64Hex(const std::string & str,int64_t & value)48 bool SecurityGuardUtils::StrToI64Hex(const std::string &str, int64_t &value)
49 {
50     long long tmp = 0;
51     bool isOK;
52     if (str.substr(0, STR_INDEX) == "0x") {
53         isOK = StrToLL(str, tmp, HEX_RADIX);
54     } else {
55         isOK = StrToLL(str, tmp, DEC_RADIX);
56     }
57     value = tmp;
58     return isOK && (tmp >= INT64_MIN && tmp <= INT64_MAX);
59 }
60 
StrToLL(const std::string & str,long long & value,int32_t base)61 bool SecurityGuardUtils::StrToLL(const std::string &str, long long &value, int32_t base)
62 {
63     auto add = str.c_str();
64     char *end = nullptr;
65     errno = 0;
66     value = strtoll(add, &end, base);
67     if ((errno == ERANGE && (value == LLONG_MAX || value == LLONG_MIN)) || (errno != 0 && value == 0)) {
68         SGLOGE("strtoll converse error,str=%{public}s", str.c_str());
69         return false;
70     } else if (end == add) {
71         SGLOGE("strtoll no digit find");
72         return false;
73     } else if (end[0] != '\0') {
74         SGLOGE("strtoll no all digit");
75         return false;
76     }
77 
78     return true;
79 }
80 
StrToULL(const std::string & str,unsigned long long & value)81 bool SecurityGuardUtils::StrToULL(const std::string &str, unsigned long long &value)
82 {
83     auto add = str.c_str();
84     char *end = nullptr;
85     errno = 0;
86     value = strtoull(add, &end, DEC_RADIX);
87     if ((errno == ERANGE && value == ULLONG_MAX) || (errno != 0 && value == 0)) {
88         SGLOGE("strtoull converse error,str=%{public}s", str.c_str());
89         return false;
90     } else if (end == add) {
91         SGLOGE("strtoull no digit find");
92         return false;
93     } else if (end[0] != '\0') {
94         SGLOGE("strtoull no all digit");
95         return false;
96     }
97 
98     return true;
99 }
100 
GetDate()101 std::string SecurityGuardUtils::GetDate()
102 {
103     time_t timestamp = time(nullptr);
104     struct tm timeInfo{};
105     localtime_r(&timestamp, &timeInfo);
106     char buf[TIME_BUF_LEN] = {};
107     if (strftime(buf, sizeof(buf), "%Y%m%d%H%M%S", &timeInfo) == 0) {
108         return "";
109     }
110     std::string data(buf);
111     return data;
112 }
113 
CopyFile(const std::string & srcPath,const std::string & dstPath)114 bool SecurityGuardUtils::CopyFile(const std::string &srcPath, const std::string &dstPath)
115 {
116     std::ifstream src(srcPath, std::ios::binary);
117     if (!src.is_open() || !src) {
118         SGLOGE("copy file stream error");
119         src.close();
120         return false;
121     }
122     if (src.seekg(0, std::ios_base::end).tellg() > FILE_MAX_SIZE) {
123         SGLOGE("cfg file is too large");
124         src.close();
125         return false;
126     }
127     src.seekg(0, std::ios::beg);
128     std::ofstream dst(dstPath, std::ios::binary);
129     if (!dst.is_open() || !dst) {
130         SGLOGE("copy file stream error");
131         src.close();
132         dst.close();
133         return false;
134     }
135 
136     dst << src.rdbuf();
137     src.close();
138     dst.close();
139     return true;
140 }
141 }