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 "string_util.h"
17 #include <stdbool.h>
18 #include <stdint.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include "securec.h"
22 #include "clib_error.h"
23 #include "hc_types.h"
24
25 #define OUT_OF_HEX 16
26 #define NUMBER_9_IN_DECIMAL 9
27 #define ASCII_CASE_DIFFERENCE_VALUE 32
28
29 static const char * const g_base64CharacterTable =
30 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
31
32 static const uint8_t g_base64DecodeTable[] = {
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 63,
36 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0, 0,
37 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
38 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0,
39 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
40 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
41 };
42
HexToChar(uint8_t hex)43 static char HexToChar(uint8_t hex)
44 {
45 return (hex > NUMBER_9_IN_DECIMAL) ? (hex + 0x37) : (hex + 0x30); /* Convert to the corresponding character */
46 }
47
ByteToHexString(const uint8_t * byte,uint32_t byteLen,char * hexStr,uint32_t hexLen)48 int32_t ByteToHexString(const uint8_t *byte, uint32_t byteLen, char *hexStr, uint32_t hexLen)
49 {
50 if (byte == NULL || hexStr == NULL) {
51 return CLIB_ERR_NULL_PTR;
52 }
53 /* The terminator('\0') needs 1 bit */
54 if (hexLen < byteLen * BYTE_TO_HEX_OPER_LENGTH + 1) {
55 return CLIB_ERR_INVALID_LEN;
56 }
57
58 for (uint32_t i = 0; i < byteLen; i++) {
59 hexStr[i * BYTE_TO_HEX_OPER_LENGTH] = HexToChar((byte[i] & 0xF0) >> 4); /* 4: shift right for filling */
60 hexStr[i * BYTE_TO_HEX_OPER_LENGTH + 1] = HexToChar(byte[i] & 0x0F); /* get low four bits */
61 }
62 hexStr[byteLen * BYTE_TO_HEX_OPER_LENGTH] = '\0';
63
64 return CLIB_SUCCESS;
65 }
66
CharToHex(char c)67 static uint8_t CharToHex(char c)
68 {
69 if ((c >= 'A') && (c <= 'F')) {
70 return (c - 'A' + DEC);
71 } else if ((c >= 'a') && (c <= 'f')) {
72 return (c - 'a' + DEC);
73 } else if ((c >= '0') && (c <= '9')) {
74 return (c - '0');
75 } else {
76 return OUT_OF_HEX;
77 }
78 }
79
HexStringToByte(const char * hexStr,uint8_t * byte,uint32_t byteLen)80 int32_t HexStringToByte(const char *hexStr, uint8_t *byte, uint32_t byteLen)
81 {
82 if (byte == NULL || hexStr == NULL) {
83 return CLIB_ERR_NULL_PTR;
84 }
85 uint32_t realHexLen = strlen(hexStr);
86 /* even number or not */
87 if (realHexLen % BYTE_TO_HEX_OPER_LENGTH != 0 || byteLen < realHexLen / BYTE_TO_HEX_OPER_LENGTH) {
88 return CLIB_ERR_INVALID_LEN;
89 }
90
91 for (uint32_t i = 0; i < realHexLen / BYTE_TO_HEX_OPER_LENGTH; i++) {
92 uint8_t high = CharToHex(hexStr[i * BYTE_TO_HEX_OPER_LENGTH]);
93 uint8_t low = CharToHex(hexStr[i * BYTE_TO_HEX_OPER_LENGTH + 1]);
94 if (high == OUT_OF_HEX || low == OUT_OF_HEX) {
95 return CLIB_ERR_INVALID_PARAM;
96 }
97 byte[i] = high << 4; /* 4: Set the high nibble */
98 byte[i] |= low; /* Set the low nibble */
99 }
100 return CLIB_SUCCESS;
101 }
102
StringToInt64(const char * cp)103 int64_t StringToInt64(const char *cp)
104 {
105 if (cp == NULL) {
106 return 0;
107 }
108 return strtoll(cp, NULL, DEC);
109 }
110
IsInvalidBase64Character(char c)111 static bool IsInvalidBase64Character(char c)
112 {
113 if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')) {
114 return false;
115 }
116 if ('0' <= c && c <= '9') {
117 return false;
118 }
119 if (c == '+' || c == '/') {
120 return false;
121 }
122 return true;
123 }
124
Base64StringToByte(const char * base64Str,uint8_t * byte,uint32_t * byteLen)125 int32_t Base64StringToByte(const char *base64Str, uint8_t *byte, uint32_t *byteLen)
126 {
127 if (base64Str == NULL || byte == NULL || byteLen == NULL) {
128 return CLIB_ERR_NULL_PTR;
129 }
130 uint32_t strLen = strlen(base64Str);
131 if (strLen < BYTE_TO_BASE64_MULTIPLIER) {
132 return CLIB_ERR_INVALID_LEN;
133 }
134 uint32_t len = strLen / BYTE_TO_BASE64_MULTIPLIER * BYTE_TO_BASE64_DIVISOR;
135 int j = 0;
136 for (int i = 0; i < 2; i++) { // at most two end fillings '='
137 if (base64Str[strLen - 1 - i] == '=') {
138 j++;
139 }
140 }
141 if (len - j > (*byteLen)) {
142 return CLIB_ERR_INVALID_LEN;
143 }
144 *byteLen = len - j;
145
146 // 6 bits each character(first 2 bits pad 0), 4 characters as a group to decode
147 if (IsInvalidBase64Character(base64Str[0]) || IsInvalidBase64Character(base64Str[1]) ||
148 IsInvalidBase64Character(base64Str[2])) {
149 return CLIB_ERR_INVALID_PARAM;
150 }
151 for (uint32_t i = 0, j = 0; i < strLen - 2; j += 3, i += 4) {
152 if (IsInvalidBase64Character(base64Str[i + 3]) && i + 3 < strLen - j) {
153 return CLIB_ERR_INVALID_PARAM;
154 }
155 /* splice the last 6 bits of the first character's value and the first 2 bits of the second character's value */
156 byte[j] = (g_base64DecodeTable[(int)base64Str[i]] << 2) | (g_base64DecodeTable[(int)base64Str[i + 1]] >> 4);
157 /* splice the last 4 bits of the second character's value and the first 4 bits of the third character's value */
158 byte[j + 1] = (g_base64DecodeTable[(int)base64Str[i + 1]] << 4) |
159 (g_base64DecodeTable[(int)base64Str[i + 2]] >> 2);
160 /* splice the last 2 bits of the third character's value and the first 6 bits of the forth character's value */
161 byte[j + 2] = (g_base64DecodeTable[(int)base64Str[i + 2]] << 6) | (g_base64DecodeTable[(int)base64Str[i + 3]]);
162 }
163 return CLIB_SUCCESS;
164 }
165
ByteToBase64String(const uint8_t * byte,uint32_t byteLen,char * base64Str,uint32_t strLen)166 int32_t ByteToBase64String(const uint8_t *byte, uint32_t byteLen, char *base64Str, uint32_t strLen)
167 {
168 if (byte == NULL || base64Str == NULL) {
169 return CLIB_ERR_NULL_PTR;
170 }
171 if (byteLen > (UINT32_MAX / BYTE_TO_BASE64_MULTIPLIER - 1) * BYTE_TO_BASE64_DIVISOR) {
172 return CLIB_ERR_INVALID_LEN;
173 }
174 uint32_t len = (byteLen / BYTE_TO_BASE64_DIVISOR + (byteLen % BYTE_TO_BASE64_DIVISOR != 0)) *
175 BYTE_TO_BASE64_MULTIPLIER;
176 if (len + 1 > strLen) {
177 return CLIB_ERR_INVALID_LEN;
178 }
179
180 uint32_t i;
181 uint32_t j;
182 // 3 bytes as a group to encode
183 for (i = 0, j = 0; i < len - 2; j += 3, i += 4) {
184 /* take the first 6 bits of the first byte to map to base64 character */
185 base64Str[i] = g_base64CharacterTable[byte[j] >> 2];
186 /*
187 * splice the last 2 bits of the first byte and the first 4 bits of the second byte,
188 * and map to base64 character
189 */
190 base64Str[i + 1] = g_base64CharacterTable[((byte[j] & 0x3) << 4) | (byte[j + 1] >> 4)];
191 /*
192 * splice the last 4 bits of the second byte and the first 2 bits of the third byte,
193 * and map to base64 character
194 */
195 base64Str[i + 2] = g_base64CharacterTable[((byte[j + 1] & 0xf) << 2) | (byte[j + 2] >> 6)];
196 /* take the last 6 bits of the third byte to map to base64 character */
197 base64Str[i + 3] = g_base64CharacterTable[byte[j + 2] & 0x3f];
198 }
199
200 // the lack of position fills '='
201 if (byteLen % 3 == 1) {
202 base64Str[i - 2] = '=';
203 base64Str[i - 1] = '=';
204 } else if (byteLen % 3 == 2) {
205 base64Str[i - 1] = '=';
206 }
207 base64Str[len] = '\0';
208
209 return CLIB_SUCCESS;
210 }
211
ToUpperCase(const char * oriStr,char ** desStr)212 int32_t ToUpperCase(const char *oriStr, char **desStr)
213 {
214 if (oriStr == NULL || desStr == NULL) {
215 return CLIB_ERR_NULL_PTR;
216 }
217 uint32_t len = strlen(oriStr);
218 *desStr = HcMalloc(len + 1, 0);
219 if (*desStr == NULL) {
220 return CLIB_ERR_BAD_ALLOC;
221 }
222 for (uint32_t i = 0; i < len; i++) {
223 if ((oriStr[i] >= 'a') && (oriStr[i] <= 'f')) {
224 (*desStr)[i] = oriStr[i] - ASCII_CASE_DIFFERENCE_VALUE;
225 } else {
226 (*desStr)[i] = oriStr[i];
227 }
228 }
229 return CLIB_SUCCESS;
230 }
231
DeepCopyString(const char * str,char ** newStr)232 int32_t DeepCopyString(const char *str, char **newStr)
233 {
234 if (str == NULL || newStr == NULL) {
235 return CLIB_ERR_NULL_PTR;
236 }
237 uint32_t len = strlen(str);
238 if (len == 0) {
239 return CLIB_ERR_INVALID_LEN;
240 }
241 char *val = (char *)HcMalloc(len + 1, 0);
242 if (val == NULL) {
243 return CLIB_ERR_BAD_ALLOC;
244 }
245 (void)memcpy_s(val, len, str, len);
246 *newStr = val;
247 return CLIB_SUCCESS;
248 }
249