• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 "asn1_utils.h"
17 #include <cctype>
18 #include <cstdio>
19 #include <securec.h>
20 #include <sstream>
21 #include "asn1_constants.h"
22 #include "telephony_errors.h"
23 
24 namespace OHOS {
25 namespace Telephony {
26 namespace {
27 const uint32_t HEX_STR_MAX_LENGTH = 4;
28 const uint32_t HEX_DATA_LEN = 16;
29 const uint32_t OFFSET_ONE_BIT = 1;
30 const uint32_t OFFSET_TWO_BIT = 2;
31 const uint32_t OFFSET_FOUR_BIT = 4;
32 const uint32_t OFFSET_THREE_BYTE = 24;
33 const uint32_t ONE_BYTE_LENGTH = 1;
34 const uint32_t TWO_BYTE_LENGTH = 2;
35 const uint32_t THREE_BYTE_LENGTH = 3;
36 const uint32_t FOUR_BYTE_LENGTH = 4;
37 const uint8_t ZERO_VALUE_OCCPUPIED_BIT_COUNT = 8;
38 const uint32_t NONZERO_OCCUPIED_BITS = 7;
39 // For exchanging adjacent bit pairs
40 const uint32_t MASK_PAIRS = 0x55555555;
41 // For swap adjacent 4-bit blocks
42 const uint32_t MASK_NIBBLES = 0x33333333;
43 // For swap adjacent bytes
44 const uint32_t MASK_BYTES = 0x0f0f0f0f;
45 // For exchange high and low 16 bits
46 const uint32_t MASK_HALFWORDS = 0xff00;
47 
48 const uint32_t MASK_BYTES_ONE_BYTE = 0x0F;
49 const uint32_t MASK_NIBBLES_ONE_BYTE = 0x33;
50 const uint32_t MASK_PAIRS_ONE_BYTE = 0x55;
51 }
52 
IsConstructedTag(uint32_t tag)53 bool Asn1Utils::IsConstructedTag(uint32_t tag)
54 {
55     std::vector<uint8_t> tagBytes;
56     uint32_t bytesLen = UintToBytes(tag, tagBytes);
57     if (bytesLen == 0 || tagBytes.empty()) {
58         TELEPHONY_LOGE("failed to transform uint data to bytes.");
59         return false;
60     }
61     return (static_cast<uint8_t>(tagBytes[0]) & BIT6_MASK) != 0;
62 }
63 
CalculateEncodedBytesNumForLength(uint32_t length)64 uint32_t Asn1Utils::CalculateEncodedBytesNumForLength(uint32_t length)
65 {
66     // default length is 1 byte
67     uint32_t len = 1;
68     if (length > MAX_INT8) {
69         len += ByteCountForUint(length);
70     }
71     return len;
72 }
73 
ByteCountForUint(uint32_t value)74 uint32_t Asn1Utils::ByteCountForUint(uint32_t value)
75 {
76     return ByteCountForInt(value, false);
77 }
78 
ByteCountForInt(uint32_t value,bool isSigned)79 uint32_t Asn1Utils::ByteCountForInt(uint32_t value, bool isSigned)
80 {
81     if (isSigned) {
82         if (value <= MAX_INT8) {
83             return ONE_BYTE_LENGTH;
84         }
85         if (value <= MAX_INT16) {
86             return TWO_BYTE_LENGTH;
87         }
88         if (value <= MAX_INT24) {
89             return THREE_BYTE_LENGTH;
90         }
91     } else {
92         if (value <= MAX_UINT8) {
93             return ONE_BYTE_LENGTH;
94         }
95         if (value <= MAX_UINT16) {
96             return TWO_BYTE_LENGTH;
97         }
98         if (value <= MAX_UINT24) {
99             return THREE_BYTE_LENGTH;
100         }
101     }
102     return FOUR_BYTE_LENGTH;
103 }
104 
105 // convert bytes array to string
BchToString(const std::vector<uint8_t> & src,std::string & destStr)106 void Asn1Utils::BchToString(const std::vector<uint8_t> &src, std::string &destStr)
107 {
108     std::string hexStr = BytesToHexStr(src);
109     destStr = SwapHexCharPair(hexStr);
110 }
111 
BcdToBytes(const std::string & bcd,std::vector<uint8_t> & bytes)112 void Asn1Utils::BcdToBytes(const std::string &bcd, std::vector<uint8_t> &bytes)
113 {
114     std::string hexStr = SwapHexCharPair(bcd);
115     bytes = HexStrToBytes(hexStr);
116 }
117 
BytesToHexStr(const std::vector<uint8_t> & bytes)118 std::string Asn1Utils::BytesToHexStr(const std::vector<uint8_t> &bytes)
119 {
120     if (bytes.size() > MAX_BPP_LENGTH) {
121         TELEPHONY_LOGE("bytes length(%{public}lu) is more than max byte.", bytes.size());
122         return "";
123     }
124     std::ostringstream oss;
125     for (size_t i = 0; i < bytes.size(); i++) {
126         oss << std::hex << std::uppercase << std::setw(BYTE_TO_HEX_LEN) << std::setfill('0') << (bytes[i] & MAX_UINT8);
127     }
128     return oss.str();
129 }
130 
ByteToHexStr(uint8_t src,std::string & dest)131 uint32_t Asn1Utils::ByteToHexStr(uint8_t src, std::string &dest)
132 {
133     std::ostringstream oss;
134     oss << std::hex << std::uppercase << std::setw(BYTE_TO_HEX_LEN) << std::setfill('0') << (src & MAX_UINT8);
135     dest = oss.str();
136     return static_cast<uint32_t>(dest.size());
137 }
138 
HexStrToBytes(const std::string & hexStr)139 std::vector<uint8_t> Asn1Utils::HexStrToBytes(const std::string& hexStr)
140 {
141     std::vector<uint8_t> ret = {};
142     if (hexStr.length() > (MAX_BPP_LENGTH * BYTE_TO_HEX_LEN)) {
143         TELEPHONY_LOGE("hexStr length(%{public}lu) is more than max byte.", hexStr.length());
144         return ret;
145     }
146 
147     if ((hexStr.length() % BYTE_TO_HEX_LEN) != 0) {
148         return ret;
149     }
150 
151     for (size_t i = 0; i < hexStr.length(); i += BYTE_TO_HEX_LEN) {
152         uint8_t byte = static_cast<uint8_t>(strtol((hexStr.substr(i, BYTE_TO_HEX_LEN)).c_str(),
153             nullptr, HEX_DATA_LEN));
154         ret.push_back(byte);
155     }
156     return ret;
157 }
158 
BytesToInt(const std::vector<uint8_t> & src,uint32_t offset,uint32_t length,int32_t & valInt)159 bool Asn1Utils::BytesToInt(const std::vector<uint8_t> &src, uint32_t offset, uint32_t length, int32_t &valInt)
160 {
161     if (length > HEX_STR_MAX_LENGTH || (offset + length) > src.size()) {
162         TELEPHONY_LOGE("length(%{public}d) or offset(%{public}d) is invalid.", length, offset);
163         return false;
164     }
165     std::vector<uint8_t> subByteStream(src.begin() + offset, src.begin() + offset + length);
166     std::string hexStr = BytesToHexStr(subByteStream);
167     valInt = static_cast<int32_t>(strtol(hexStr.c_str(), nullptr, HEX_DATA_LEN));
168     return true;
169 }
170 
UintToBytes(const uint32_t value,std::vector<uint8_t> & bytes)171 uint32_t Asn1Utils::UintToBytes(const uint32_t value, std::vector<uint8_t> &bytes)
172 {
173     uint32_t len = ByteCountForInt(value, false);
174     std::ostringstream oss;
175     oss << std::hex << std::uppercase << std::setw(len * BYTE_TO_HEX_LEN) << std::setfill('0') << value;
176     std::string hexStr = oss.str();
177     bytes = HexStrToBytes(hexStr);
178     return len;
179 }
180 
IntToBytes(int32_t value,std::vector<uint8_t> & dest)181 uint32_t Asn1Utils::IntToBytes(int32_t value, std::vector<uint8_t> &dest)
182 {
183     uint32_t len = ByteCountForInt(static_cast<uint32_t>(value), true);
184     std::ostringstream oss;
185     oss << std::hex << std::uppercase << std::setw(len * BYTE_TO_HEX_LEN) << std::setfill('0') << value;
186     std::string hexStr = oss.str();
187     dest = HexStrToBytes(hexStr);
188     return len;
189 }
190 
BytesToString(const std::vector<uint8_t> & src)191 std::string Asn1Utils::BytesToString(const std::vector<uint8_t> &src)
192 {
193     std::string hexStr = BytesToHexStr(src);
194     std::string dest = HexStrToString(hexStr);
195     return dest;
196 }
197 
StrToHexStr(const std::string & str)198 std::string Asn1Utils::StrToHexStr(const std::string& str)
199 {
200     std::string inputStr = str;
201     std::vector<uint8_t> bytes = {};
202     for (size_t i = 0; i < inputStr.length(); i++) {
203         bytes.push_back(static_cast<uint8_t>(inputStr[i]));
204     }
205     std::string result = BytesToHexStr(bytes);
206     return result;
207 }
208 
HexStrToString(const std::string & hexStr)209 std::string Asn1Utils::HexStrToString(const std::string& hexStr)
210 {
211     std::string inputHexStr = hexStr;
212     std::vector<uint8_t> bytes = HexStrToBytes(inputHexStr);
213     std::string result("");
214     for (size_t i = 0; i < bytes.size(); i++) {
215         result += (static_cast<char>(bytes[i]));
216     }
217     return result;
218 }
219 
StringToBytes(const std::string & src)220 std::vector<uint8_t> Asn1Utils::StringToBytes(const std::string &src)
221 {
222     std::string hexStr = StrToHexStr(src);
223     std::vector<uint8_t> dest = HexStrToBytes(hexStr);
224     return dest;
225 }
226 
ReverseInt(uint32_t value)227 uint32_t Asn1Utils::ReverseInt(uint32_t value)
228 {
229     uint32_t valueTemp = value;
230     // Exchanging adjacent bit pairs
231     valueTemp = ((valueTemp & MASK_PAIRS) << OFFSET_ONE_BIT) | ((valueTemp >> OFFSET_ONE_BIT) & MASK_PAIRS);
232     // Swap adjacent 4-bit blocks
233     valueTemp = ((valueTemp & MASK_NIBBLES) << OFFSET_TWO_BIT) | ((valueTemp >> OFFSET_TWO_BIT) & MASK_NIBBLES);
234     // Swap adjacent bytes
235     valueTemp = ((valueTemp & MASK_BYTES) << OFFSET_FOUR_BIT) | ((valueTemp >> OFFSET_FOUR_BIT) & MASK_BYTES);
236     // Exchange high and low 16 bits
237     valueTemp = (valueTemp << OFFSET_THREE_BYTE) | ((valueTemp & MASK_HALFWORDS) << OFFSET_EIGHT_BIT) |
238         ((valueTemp >> OFFSET_EIGHT_BIT) & MASK_HALFWORDS) | (valueTemp >> OFFSET_THREE_BYTE);
239     return valueTemp;
240 }
241 
CountTrailingZeros(const uint8_t value)242 uint8_t Asn1Utils::CountTrailingZeros(const uint8_t value)
243 {
244     if (value == 0) {
245         return ZERO_VALUE_OCCPUPIED_BIT_COUNT;
246     }
247 
248     uint32_t valueTemp = ((static_cast<uint32_t>(value)) & MAX_UINT8);
249     // The number of bits occupied by non-zero values
250     uint8_t nonZeroBitCount = static_cast<uint8_t>(NONZERO_OCCUPIED_BITS);
251     if ((valueTemp & static_cast<uint32_t>(MASK_BYTES_ONE_BYTE)) != 0) {
252         nonZeroBitCount -= static_cast<uint8_t>(OFFSET_FOUR_BIT);
253     }
254     if ((valueTemp & static_cast<uint32_t>(MASK_NIBBLES_ONE_BYTE)) != 0) {
255         nonZeroBitCount -= static_cast<uint8_t>(OFFSET_TWO_BIT);
256     }
257     if ((valueTemp & static_cast<uint32_t>(MASK_PAIRS_ONE_BYTE)) != 0) {
258         nonZeroBitCount -= static_cast<uint8_t>(OFFSET_ONE_BIT);
259     }
260     return nonZeroBitCount;
261 }
262 
263 // convert bytes array to string
SwapHexCharPair(const std::string & hexStr)264 std::string Asn1Utils::SwapHexCharPair(const std::string &hexStr)
265 {
266     std::string result = "";
267     if (hexStr.length() > (MAX_UINT8 * BYTE_TO_HEX_LEN)) {
268         return result;
269     }
270 
271     std::string tmphexStr = hexStr;
272     if (tmphexStr.length() % BYTE_TO_HEX_LEN != 0) {
273         tmphexStr += "0";
274     }
275     for (size_t i = 0; i < tmphexStr.length(); i += BYTE_TO_HEX_LEN) {
276         result += tmphexStr.substr(i + ONE_BYTE_LENGTH, ONE_BYTE_LENGTH);
277         result += tmphexStr.substr(i, ONE_BYTE_LENGTH);
278     }
279     return result;
280 }
281 } // namespace Telephony
282 }
283