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 "icc_operator_rule.h"
17
18 #include <algorithm>
19 #include <charconv>
20 #include <system_error>
21
22 #include "telephony_log_wrapper.h"
23
24
25 namespace OHOS {
26 namespace Telephony {
27 constexpr int32_t INT32_INITVALUE = 0;
readOneByte(std::string::const_iterator & it,const std::string::const_iterator & ed,int32_t & res)28 static bool readOneByte(std::string::const_iterator &it, const std::string::const_iterator &ed, int32_t &res)
29 {
30 if (it == ed) {
31 TELEPHONY_LOGE("can not readTLVLength for empty string!!' ");
32 return false;
33 }
34 ++it;
35 if (it == ed) {
36 TELEPHONY_LOGE("can not readTLVLength for string length less 2");
37 return false;
38 }
39 const auto [nextPtr, err] =
40 std::from_chars(std::addressof(*(it - 1)), std::addressof(*(it + 1)), res, IccOperatorRule::HEX_);
41 if (err != std::errc()) {
42 const auto cond = std::make_error_condition(err);
43 TELEPHONY_LOGE("readLength occurent error!! '%{public}s' ", cond.message().data());
44 return false;
45 }
46 ++it;
47 return true;
48 }
49
parseSimpleTLV(std::string::const_iterator & it,const std::string::const_iterator & ed,std::string & tagName,int32_t & len,std::string & value)50 static bool parseSimpleTLV(std::string::const_iterator &it, const std::string::const_iterator &ed,
51 std::string &tagName, int32_t &len, std::string &value)
52 {
53 size_t inputSize = static_cast<long unsigned int>(std::distance(it, ed));
54 if (inputSize < IccOperatorRule::TLV_STAG_CHARLEN) {
55 std::string temp(it, ed);
56 TELEPHONY_LOGE("parseSimpleTLV from '%{public}s' size:%{public}zu < %{public}d", temp.data(), inputSize,
57 IccOperatorRule::TLV_STAG_CHARLEN);
58 return false;
59 }
60 /* begin parse tagName */
61 tagName.clear();
62 std::copy_n(it, IccOperatorRule::TLV_STAG_CHARLEN, std::back_inserter(tagName));
63 TELEPHONY_LOGI("parseSimpleTLV read tagName: '%{public}s' ", tagName.data());
64 it += IccOperatorRule::TLV_STAG_CHARLEN;
65 /* begin parse length */
66 len = INT32_INITVALUE;
67 if (inputSize < IccOperatorRule::TLV_STAG_CHARLEN + IccOperatorRule::TLV_LEN_CHARLEN) {
68 std::string temp(it, ed);
69 TELEPHONY_LOGE("parseSimpleTLV from '%{public}s' size:%{public}zu < %{public}d", temp.data(), inputSize,
70 IccOperatorRule::TLV_STAG_CHARLEN + IccOperatorRule::TLV_LEN_CHARLEN);
71 return false;
72 }
73 if (!readOneByte(it, ed, len)) {
74 TELEPHONY_LOGE("parseSimpleTLV parse length fail!");
75 return false;
76 }
77 /* begin parse value */
78 value.clear();
79 const auto valueCharLen = len + len;
80 if (static_cast<int>(inputSize) <
81 IccOperatorRule::TLV_STAG_CHARLEN + IccOperatorRule::TLV_LEN_CHARLEN + valueCharLen) {
82 std::string temp(it, ed);
83 TELEPHONY_LOGE("parseSimpleTLV from '%{public}s' size:%{public}zu < %{public}d", temp.data(), inputSize,
84 IccOperatorRule::TLV_STAG_CHARLEN + IccOperatorRule::TLV_LEN_CHARLEN + valueCharLen);
85 return false;
86 }
87 std::copy_n(it, valueCharLen, std::back_inserter(value));
88 it += valueCharLen;
89 return true;
90 }
91
CreateFromTLV(const std::string & hexStr,std::vector<IccOperatorRule> & result)92 bool IccOperatorRule::CreateFromTLV(const std::string &hexStr, std::vector<IccOperatorRule> &result)
93 {
94 TELEPHONY_LOGI("IccOperatorRule::CreateFromTLV by hexStr Begin!");
95 return CreateFromTLV(hexStr.begin(), hexStr.end(), result);
96 }
97
CreateFromTLV(const std::string::const_iterator & hexStrBeg,const std::string::const_iterator & hexStrEnd,std::vector<IccOperatorRule> & result)98 bool IccOperatorRule::CreateFromTLV(const std::string::const_iterator &hexStrBeg,
99 const std::string::const_iterator &hexStrEnd, std::vector<IccOperatorRule> &result)
100 {
101 TELEPHONY_LOGD("IccOperatorRule::CreateFromTLV by iterator Begin!");
102 result.clear();
103 const auto &[hexStrIt, prefixIt] =
104 std::mismatch(hexStrBeg, hexStrEnd, TAG_ALL_RULE.begin(), TAG_ALL_RULE.end());
105 // when TAG_ALL_RULE not a prefix of hexStrBeg
106 if (prefixIt != TAG_ALL_RULE.end()) {
107 std::string temp(hexStrBeg, hexStrEnd);
108 TELEPHONY_LOGE("hexStr:[%{public}s] not strartWith '%{public}s' !", temp.data(), TAG_ALL_RULE.data());
109 return false;
110 }
111 TELEPHONY_LOGI("start parse after of tag:'%{public}s' !", TAG_ALL_RULE.data());
112 std::string::const_iterator strIt = hexStrBeg + TAG_ALL_RULE.size();
113 int32_t len = INT32_INITVALUE;
114 if (!readOneByte(strIt, hexStrEnd, len)) {
115 TELEPHONY_LOGE("after tagStr '%{public}s' had not LenStr !", TAG_ALL_RULE.data());
116 return false;
117 }
118 TELEPHONY_LOGI("read TAG_ALL_RULE len:%{public}d ", len);
119 IccOperatorRule rule;
120 int32_t totalLen = INT32_INITVALUE;
121 while (strIt != hexStrEnd && totalLen < len) {
122 int32_t ruleLen = INT32_INITVALUE;
123 if (!DecodeTLVTagRule(strIt, hexStrEnd, rule, ruleLen)) {
124 break;
125 }
126 totalLen += ruleLen;
127 TELEPHONY_LOGI("DecodeRule once count:%{public}d ,TAG_ALL_RULE len:%{public}d", totalLen, len);
128 result.push_back(rule);
129 }
130 TELEPHONY_LOGI("End parse element of Rule! Size:[%{public}zu]", result.size());
131 return true;
132 }
133
DecodeTLVTagCertPkg(std::string::const_iterator & hexStrBeg,const std::string::const_iterator & hexStrEnd,IccOperatorRule & result)134 bool IccOperatorRule::DecodeTLVTagCertPkg(
135 std::string::const_iterator &hexStrBeg, const std::string::const_iterator &hexStrEnd, IccOperatorRule &result)
136 {
137 TELEPHONY_LOGI("Start parse TAG_CERT_PKG(%{public}s) for [%{public}s]", TAG_CERT_PKG.data(),
138 std::string(hexStrBeg, hexStrEnd).data());
139 const auto [hexStrIt, prefixIt] = std::mismatch(hexStrBeg, hexStrEnd, TAG_CERT_PKG.begin(), TAG_CERT_PKG.end());
140 if (prefixIt != TAG_CERT_PKG.end()) {
141 std::string temp(hexStrBeg, hexStrEnd);
142 TELEPHONY_LOGE("hexStr:[%{public}s] not strartWith '%{public}s' !", temp.data(), TAG_CERT_PKG.data());
143 return false;
144 }
145 hexStrBeg += TAG_CERT_PKG.size();
146 int32_t refDoLen = INT32_INITVALUE;
147 if (!readOneByte(hexStrBeg, hexStrEnd, refDoLen)) {
148 TELEPHONY_LOGE("after tagStr '%{public}s' had not LenStr !", TAG_CERT_PKG.data());
149 return false;
150 }
151 bool hasCertificate = false;
152 int32_t totalLen = INT32_INITVALUE;
153 while (hexStrBeg != hexStrEnd && totalLen < refDoLen) {
154 std::string tagName;
155 int32_t length = INT32_INITVALUE;
156 std::string value;
157 if (!parseSimpleTLV(hexStrBeg, hexStrEnd, tagName, length, value)) {
158 std::string temp(hexStrBeg, hexStrEnd);
159 TELEPHONY_LOGE("can not parse simple TLV at : '%{public}s'", temp.data());
160 return false;
161 }
162 totalLen += length + TLV_SIMPLE_TAG_ONEBYTE_LEN + TLV_SIMPLE_TAG_LENGTH_LEN;
163 TELEPHONY_LOGI("parse more TLV count:%{public}d , refDoLen:%{public}d", totalLen, refDoLen);
164 if (tagName == TAG_CERTIFICATE) {
165 result.SetCertificate(std::move(value));
166 hasCertificate = true;
167 } else if (tagName == TAG_PACKAGE) {
168 if (!result.SetPackageNameByHexStr(value)) {
169 return false;
170 }
171 }
172 }
173 return hasCertificate;
174 }
175
DecodeTLVTagLimits(std::string::const_iterator & hexStrBeg,const std::string::const_iterator & hexStrEnd,IccOperatorRule & result)176 bool IccOperatorRule::DecodeTLVTagLimits(
177 std::string::const_iterator &hexStrBeg, const std::string::const_iterator &hexStrEnd, IccOperatorRule &result)
178 {
179 TELEPHONY_LOGI("Start parse TAG_LIMITS(%{public}s) for [%{public}s]", TAG_LIMITS.data(),
180 std::string(hexStrBeg, hexStrEnd).data());
181 const auto [hexStrIt, prefixIt] = std::mismatch(hexStrBeg, hexStrEnd, TAG_LIMITS.begin(), TAG_LIMITS.end());
182 if (prefixIt != TAG_LIMITS.end()) {
183 std::string temp(hexStrBeg, hexStrEnd);
184 TELEPHONY_LOGE("hexStr:[%{public}s] not strartWith '%{public}s' !", temp.data(), TAG_LIMITS.data());
185 return false;
186 }
187 hexStrBeg += TAG_LIMITS.size();
188 int32_t arDoLen = INT32_INITVALUE;
189 if (!readOneByte(hexStrBeg, hexStrEnd, arDoLen)) {
190 TELEPHONY_LOGE("after tagStr '%{public}s' had not LenStr !", TAG_LIMITS.data());
191 return false;
192 }
193 int32_t totalLen = INT32_INITVALUE;
194 bool isReadTagPermArDo = false;
195 while (hexStrBeg != hexStrEnd && totalLen < arDoLen) {
196 std::string tagName;
197 int32_t length = INT32_INITVALUE;
198 std::string value;
199 if (!parseSimpleTLV(hexStrBeg, hexStrEnd, tagName, length, value)) {
200 std::string temp(hexStrBeg, hexStrEnd);
201 TELEPHONY_LOGE("can not parse simple TLV at : '%{public}s'", temp.data());
202 return false;
203 }
204 totalLen += length + TLV_SIMPLE_TAG_ONEBYTE_LEN + TLV_SIMPLE_TAG_LENGTH_LEN;
205 TELEPHONY_LOGI("parse more TLV count:%{public}d , arDolen:%{public}d", totalLen, arDoLen);
206 if (tagName == TAG_LIMIT) {
207 result.SetAccessLimit(std::move(value));
208 isReadTagPermArDo = true;
209 }
210 }
211 return isReadTagPermArDo;
212 }
213
DecodeTLVTagRule(std::string::const_iterator & hexStrBeg,const std::string::const_iterator & hexStrEnd,IccOperatorRule & result,int32_t & len)214 bool IccOperatorRule::DecodeTLVTagRule(std::string::const_iterator &hexStrBeg,
215 const std::string::const_iterator &hexStrEnd, IccOperatorRule &result, int32_t &len)
216 {
217 TELEPHONY_LOGI(
218 "Start parse TAG_RULE(%{public}s) for [%{public}s]", TAG_RULE.data(), std::string(hexStrBeg, hexStrEnd).data());
219 len = INT32_INITVALUE;
220 const auto [hexStrIt, prefixIt] =
221 std::mismatch(hexStrBeg, hexStrEnd, TAG_RULE.begin(), TAG_RULE.end());
222 if (prefixIt != TAG_RULE.end()) {
223 TELEPHONY_LOGE("hexStr not strartWith '%{public}s' !", TAG_RULE.data());
224 return false;
225 }
226 len += TLV_SIMPLE_TAG_ONEBYTE_LEN;
227 hexStrBeg += TAG_RULE.size();
228 int32_t refArLen = INT32_INITVALUE;
229 if (!readOneByte(hexStrBeg, hexStrEnd, refArLen)) {
230 TELEPHONY_LOGE("after tagStr '%{public}s' had not LenStr !", TAG_RULE.data());
231 return false;
232 }
233 len += TLV_SIMPLE_TAG_LENGTH_LEN + refArLen;
234 if (!DecodeTLVTagCertPkg(hexStrBeg, hexStrEnd, result)) {
235 TELEPHONY_LOGE("DecodeTLVTagCertPkg fail !");
236 return false;
237 }
238 if (!DecodeTLVTagLimits(hexStrBeg, hexStrEnd, result)) {
239 TELEPHONY_LOGE("DecodeTLVTagLimits fail !");
240 return false;
241 }
242 return true;
243 }
244
IccOperatorRule()245 IccOperatorRule::IccOperatorRule() {}
~IccOperatorRule()246 IccOperatorRule::~IccOperatorRule() {}
247
GetPackageName(std::string & result) const248 void IccOperatorRule::GetPackageName(std::string &result) const
249 {
250 result.clear();
251 result = std::string(packageName_.begin(), packageName_.end());
252 }
253
SetPackageName(const std::string & packageName)254 void IccOperatorRule::SetPackageName(const std::string &packageName)
255 {
256 this->packageName_ = packageName;
257 }
258
SetPackageName(std::string && packageName)259 void IccOperatorRule::SetPackageName(std::string &&packageName)
260 {
261 this->packageName_.swap(packageName);
262 }
263
SetPackageNameByHexStr(const std::string & hexStr)264 bool IccOperatorRule::SetPackageNameByHexStr(const std::string &hexStr)
265 {
266 packageName_.clear();
267 auto it = hexStr.begin();
268 while (it != hexStr.end()) {
269 int32_t value = INT32_INITVALUE;
270 if (!readOneByte(it, hexStr.end(), value)) {
271 TELEPHONY_LOGE("IccOperatorRule::SetPackageNameByHexStr fail !");
272 return false;
273 }
274 this->packageName_.push_back(static_cast<char>(value));
275 }
276 return true;
277 }
278
GetCertificate(std::string & result) const279 void IccOperatorRule::GetCertificate(std::string &result) const
280 {
281 result.clear();
282 result = std::string(certificate_.begin(), certificate_.end());
283 }
284
SetCertificate(const std::string & certificate)285 void IccOperatorRule::SetCertificate(const std::string &certificate)
286 {
287 this->certificate_ = certificate;
288 }
289
SetCertificate(std::string && certificate)290 void IccOperatorRule::SetCertificate(std::string &&certificate)
291 {
292 this->certificate_.swap(certificate);
293 }
294
SetAccessLimit(const std::string & accessLimit)295 void IccOperatorRule::SetAccessLimit(const std::string &accessLimit)
296 {
297 this->accessLimit_ = accessLimit;
298 }
299
SetAccessLimit(std::string && accessLimit)300 void IccOperatorRule::SetAccessLimit(std::string &&accessLimit)
301 {
302 this->accessLimit_.swap(accessLimit);
303 }
304
Matche(const std::string_view & certHash,const std::string_view & packageName) const305 bool IccOperatorRule::Matche(const std::string_view &certHash, const std::string_view &packageName) const
306 {
307 bool res = (this->certificate_ == certHash);
308 if (this->packageName_.empty()) {
309 return res;
310 }
311 return res && (this->packageName_ == packageName);
312 }
313 } // namespace Telephony
314 } // namespace OHOS
315