1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15 #include <stdbool.h>
16 #include "securec.h"
17 #include "bsl_err.h"
18 #include "bsl_bytes.h"
19 #include "bsl_log_internal.h"
20 #include "bsl_binlog_id.h"
21 #include "bsl_asn1_local.h"
22 #include "bsl_sal.h"
23 #include "sal_time.h"
24 #include "bsl_asn1.h"
25
26 #define BSL_ASN1_INDEFINITE_LENGTH 0x80
27 #define BSL_ASN1_DEFINITE_MAX_CONTENT_OCTET_NUM 0x7F // 127
28
BSL_ASN1_DecodeLen(uint8_t ** encode,uint32_t * encLen,bool completeLen,uint32_t * len)29 int32_t BSL_ASN1_DecodeLen(uint8_t **encode, uint32_t *encLen, bool completeLen, uint32_t *len)
30 {
31 if (encode == NULL || *encode == NULL || encLen == NULL || len == NULL) {
32 return BSL_NULL_INPUT;
33 }
34 uint8_t *temp = *encode;
35 uint32_t tempLen = *encLen;
36 uint32_t parseLen = 0;
37 if (tempLen < 1) {
38 return BSL_ASN1_ERR_DECODE_LEN;
39 }
40
41 if ((*temp & BSL_ASN1_INDEFINITE_LENGTH) == 0) {
42 parseLen = *temp;
43 temp++;
44 tempLen--;
45 parseLen += ((completeLen) ? 1 : 0);
46 } else {
47 uint32_t index = *temp - BSL_ASN1_INDEFINITE_LENGTH;
48 if (index > sizeof(int32_t)) {
49 return BSL_ASN1_ERR_MAX_LEN_NUM;
50 }
51 temp++;
52 tempLen--;
53 if (tempLen < index) {
54 return BSL_ASN1_ERR_BUFF_NOT_ENOUGH;
55 }
56 for (uint32_t iter = 0; iter < index; iter++) {
57 parseLen = (parseLen << 8) | *temp; // one byte = 8 bits
58 temp++;
59 tempLen--;
60 }
61 // anti-flip
62 if (parseLen >= ((((uint64_t)1 << 32) - 1) - index - 2)) { // 1<<32:U32_MAX; 2: Tag + length(0x8x)
63 return BSL_ASN1_ERR_MAX_LEN_NUM;
64 }
65 parseLen += ((completeLen) ? (index + 1) : 0);
66 }
67 uint32_t length = (completeLen) ? *encLen : tempLen;
68 /* The length supports a maximum of 4 bytes */
69 if (parseLen > length) {
70 return BSL_ASN1_ERR_DECODE_LEN;
71 }
72 *len = parseLen;
73 *encode = temp;
74 *encLen = tempLen;
75 return BSL_SUCCESS;
76 }
77
BSL_ASN1_GetCompleteLen(uint8_t * data,uint32_t * dataLen)78 int32_t BSL_ASN1_GetCompleteLen(uint8_t *data, uint32_t *dataLen)
79 {
80 uint8_t *tmp = data;
81 uint32_t tmpLen = *dataLen;
82 uint32_t len = 0;
83 if (tmpLen < 1) {
84 return BSL_ASN1_ERR_BUFF_NOT_ENOUGH;
85 }
86
87 tmp++;
88 tmpLen--;
89 int32_t ret = BSL_ASN1_DecodeLen(&tmp, &tmpLen, true, &len);
90 if (ret != BSL_SUCCESS) {
91 return ret;
92 }
93 *dataLen = len + 1;
94 return BSL_SUCCESS;
95 }
96
BSL_ASN1_DecodeTagLen(uint8_t tag,uint8_t ** encode,uint32_t * encLen,uint32_t * valLen)97 int32_t BSL_ASN1_DecodeTagLen(uint8_t tag, uint8_t **encode, uint32_t *encLen, uint32_t *valLen)
98 {
99 if (encode == NULL || *encode == NULL || encLen == NULL || valLen == NULL) {
100 return BSL_NULL_INPUT;
101 }
102 uint8_t *temp = *encode;
103 uint32_t tempLen = *encLen;
104 if (tempLen < 1) {
105 return BSL_INVALID_ARG;
106 }
107
108 if (tag != *temp) {
109 return BSL_ASN1_ERR_MISMATCH_TAG;
110 }
111 temp++;
112 tempLen--;
113 uint32_t len;
114 int32_t ret = BSL_ASN1_DecodeLen(&temp, &tempLen, false, &len);
115 if (ret != BSL_SUCCESS) {
116 return ret;
117 }
118 if (len > tempLen) {
119 return BSL_ASN1_ERR_BUFF_NOT_ENOUGH;
120 }
121 *valLen = len;
122 *encode = temp;
123 *encLen = tempLen;
124 return BSL_SUCCESS;
125 }
126
BSL_ASN1_DecodeItem(uint8_t ** encode,uint32_t * encLen,BSL_ASN1_Buffer * asnItem)127 int32_t BSL_ASN1_DecodeItem(uint8_t **encode, uint32_t *encLen, BSL_ASN1_Buffer *asnItem)
128 {
129 if (encode == NULL || *encode == NULL || encLen == NULL || asnItem == NULL) {
130 return BSL_NULL_INPUT;
131 }
132 uint8_t tag;
133 uint32_t len;
134 uint8_t *temp = *encode;
135 uint32_t tempLen = *encLen;
136 if (tempLen < 1) {
137 return BSL_INVALID_ARG;
138 }
139 tag = *temp;
140 temp++;
141 tempLen--;
142 int32_t ret = BSL_ASN1_DecodeLen(&temp, &tempLen, false, &len);
143 if (ret != BSL_SUCCESS) {
144 return ret;
145 }
146 asnItem->tag = tag;
147 asnItem->len = len;
148 asnItem->buff = temp;
149 temp += len;
150 tempLen -= len;
151 *encode = temp;
152 *encLen = tempLen;
153 return BSL_SUCCESS;
154 }
155
ParseBool(uint8_t * val,uint32_t len,bool * decodeData)156 static int32_t ParseBool(uint8_t *val, uint32_t len, bool *decodeData)
157 {
158 if (len != 1) {
159 return BSL_ASN1_ERR_DECODE_BOOL;
160 }
161 *decodeData = (*val != 0) ? 1 : 0;
162 return BSL_SUCCESS;
163 }
164
ParseInt(uint8_t * val,uint32_t len,int * decodeData)165 static int32_t ParseInt(uint8_t *val, uint32_t len, int *decodeData)
166 {
167 uint8_t *temp = val;
168 if (len < 1 || len > sizeof(int)) {
169 return BSL_ASN1_ERR_DECODE_INT;
170 }
171
172 *decodeData = 0;
173 for (uint32_t i = 0; i < len; i++) {
174 *decodeData = (*decodeData << 8) | *temp;
175 temp++;
176 }
177 return BSL_SUCCESS;
178 }
179
ParseBitString(uint8_t * val,uint32_t len,BSL_ASN1_BitString * decodeData)180 static int32_t ParseBitString(uint8_t *val, uint32_t len, BSL_ASN1_BitString *decodeData)
181 {
182 if (len < 1 || *val > BSL_ASN1_VAL_MAX_BIT_STRING_LEN) {
183 return BSL_ASN1_ERR_DECODE_BIT_STRING;
184 }
185 decodeData->unusedBits = *val;
186 decodeData->buff = val + 1;
187 decodeData->len = len - 1;
188 return BSL_SUCCESS;
189 }
190
191 // len max support 4
DecodeAsciiNum(uint8_t ** encode,uint32_t len)192 static uint32_t DecodeAsciiNum(uint8_t **encode, uint32_t len)
193 {
194 uint32_t temp = 0;
195 uint8_t *data = *encode;
196 for (uint32_t i = 0; i < len; i++) {
197 temp *= 10; // 10: Process decimal numbers.
198 temp += (data[i] - '0');
199 }
200 *encode += len;
201 return temp;
202 }
203
CheckTime(uint8_t * data,uint32_t len)204 static int32_t CheckTime(uint8_t *data, uint32_t len)
205 {
206 for (uint32_t i = 0; i < len; i++) {
207 if (data[i] > '9' || data[i] < '0') {
208 return BSL_ASN1_ERR_DECODE_TIME;
209 }
210 }
211 return BSL_SUCCESS;
212 }
213
214 // Support utcTime for YYMMDDHHMMSS[Z] and generalizedTime for YYYYMMDDHHMMSS[Z].
ParseTime(uint8_t tag,uint8_t * val,uint32_t len,BSL_TIME * decodeData)215 static int32_t ParseTime(uint8_t tag, uint8_t *val, uint32_t len, BSL_TIME *decodeData)
216 {
217 int32_t ret;
218 uint8_t *temp = val;
219 if (tag == BSL_ASN1_TAG_UTCTIME && (len != 12 && len != 13)) { // 12 YYMMDDHHMMSS, 13 YYMMDDHHMMSSZ
220 return BSL_ASN1_ERR_DECODE_UTC_TIME;
221 }
222
223 if (tag == BSL_ASN1_TAG_GENERALIZEDTIME && (len != 14 && len != 15)) { // 14 YYYYMMDDHHMMSS, 15 YYYYMMDDHHMMSSZ
224 return BSL_ASN1_ERR_DECODE_GENERAL_TIME;
225 }
226
227 // Check if the encoding is within the expected range and prepare for conversion
228 ret = tag == BSL_ASN1_TAG_UTCTIME ? CheckTime(val, 12) : CheckTime(val, 14); // 12|14: ignoring Z
229 if (ret != BSL_SUCCESS) {
230 return ret;
231 }
232 if (tag == BSL_ASN1_TAG_UTCTIME) {
233 decodeData->year = (uint16_t)DecodeAsciiNum(&temp, 2); // 2: YY
234 if (decodeData->year < 50) {
235 decodeData->year += 2000;
236 } else {
237 decodeData->year += 1900;
238 }
239 } else {
240 decodeData->year = (uint16_t)DecodeAsciiNum(&temp, 4); // 4: YYYY
241 }
242 decodeData->month = (uint8_t)DecodeAsciiNum(&temp, 2); // 2:MM
243 decodeData->day = (uint8_t)DecodeAsciiNum(&temp, 2); // 2: DD
244 decodeData->hour = (uint8_t)DecodeAsciiNum(&temp, 2); // 2: HH
245 decodeData->minute = (uint8_t)DecodeAsciiNum(&temp, 2); // 2: MM
246 decodeData->second = (uint8_t)DecodeAsciiNum(&temp, 2); // 2: SS
247 return BSL_DateTimeCheck(decodeData) ? BSL_SUCCESS : BSL_ASN1_ERR_CHECK_TIME;
248 }
249
DecodeTwoLayerListInternal(uint32_t layer,BSL_ASN1_DecodeListParam * param,BSL_ASN1_Buffer * asn,BSL_ASN1_ParseListAsnItem parseListItemCb,void * cbParam,BSL_ASN1_List * list)250 static int32_t DecodeTwoLayerListInternal(uint32_t layer, BSL_ASN1_DecodeListParam *param, BSL_ASN1_Buffer *asn,
251 BSL_ASN1_ParseListAsnItem parseListItemCb, void *cbParam, BSL_ASN1_List *list)
252 {
253 int32_t ret;
254 uint8_t tag;
255 uint32_t encLen;
256 uint8_t *buff = asn->buff;
257 uint32_t len = asn->len;
258 BSL_ASN1_Buffer item;
259 while (len > 0) {
260 if (*buff != param->expTag[layer - 1]) {
261 return BSL_ASN1_ERR_MISMATCH_TAG;
262 }
263 tag = *buff;
264 buff++;
265 len--;
266 ret = BSL_ASN1_DecodeLen(&buff, &len, false, &encLen);
267 if (ret != BSL_SUCCESS) {
268 return ret;
269 }
270 item.tag = tag;
271 item.len = encLen;
272 item.buff = buff;
273 ret = parseListItemCb(layer, &item, cbParam, list);
274 if (ret != BSL_SUCCESS) {
275 return ret;
276 }
277 buff += encLen;
278 len -= encLen;
279 }
280 return BSL_SUCCESS;
281 }
282
DecodeOneLayerList(BSL_ASN1_DecodeListParam * param,BSL_ASN1_Buffer * asn,BSL_ASN1_ParseListAsnItem parseListItemCb,void * cbParam,BSL_ASN1_List * list)283 static int32_t DecodeOneLayerList(BSL_ASN1_DecodeListParam *param, BSL_ASN1_Buffer *asn,
284 BSL_ASN1_ParseListAsnItem parseListItemCb, void *cbParam, BSL_ASN1_List *list)
285 {
286 return DecodeTwoLayerListInternal(1, param, asn, parseListItemCb, cbParam, list);
287 }
288
DecodeTwoLayerList(BSL_ASN1_DecodeListParam * param,BSL_ASN1_Buffer * asn,BSL_ASN1_ParseListAsnItem parseListItemCb,void * cbParam,BSL_ASN1_List * list)289 static int32_t DecodeTwoLayerList(BSL_ASN1_DecodeListParam *param, BSL_ASN1_Buffer *asn,
290 BSL_ASN1_ParseListAsnItem parseListItemCb, void *cbParam, BSL_ASN1_List *list)
291 {
292 int32_t ret;
293 uint8_t tag;
294 uint32_t encLen;
295 uint8_t *buff = asn->buff;
296 uint32_t len = asn->len;
297 BSL_ASN1_Buffer item;
298 while (len > 0) {
299 if (*buff != param->expTag[0]) {
300 return BSL_ASN1_ERR_MISMATCH_TAG;
301 }
302 tag = *buff;
303 buff++;
304 len--;
305 ret = BSL_ASN1_DecodeLen(&buff, &len, false, &encLen);
306 if (ret != BSL_SUCCESS) {
307 return ret;
308 }
309 item.tag = tag;
310 item.len = encLen;
311 item.buff = buff;
312 ret = parseListItemCb(1, &item, cbParam, list);
313 if (ret != BSL_SUCCESS) {
314 return ret;
315 }
316 ret = DecodeTwoLayerListInternal(2, param, &item, parseListItemCb, cbParam, list);
317 if (ret != BSL_SUCCESS) {
318 return ret;
319 }
320 buff += encLen;
321 len -= encLen;
322 }
323 return BSL_SUCCESS;
324 }
325
BSL_ASN1_DecodeListItem(BSL_ASN1_DecodeListParam * param,BSL_ASN1_Buffer * asn,BSL_ASN1_ParseListAsnItem parseListItemCb,void * cbParam,BSL_ASN1_List * list)326 int32_t BSL_ASN1_DecodeListItem(BSL_ASN1_DecodeListParam *param, BSL_ASN1_Buffer *asn,
327 BSL_ASN1_ParseListAsnItem parseListItemCb, void *cbParam, BSL_ASN1_List *list)
328 {
329 if (param == NULL || asn == NULL || parseListItemCb == NULL || list == NULL) {
330 return BSL_INVALID_ARG;
331 }
332
333 // Currently, it supports a maximum of 2 layers
334 if (param->layer > BSL_ASN1_MAX_LIST_NEST_EPTH) {
335 return BSL_ASN1_ERR_EXCEED_LIST_DEPTH;
336 }
337 return param->layer == 1 ? DecodeOneLayerList(param, asn, parseListItemCb, cbParam, list)
338 : DecodeTwoLayerList(param, asn, parseListItemCb, cbParam, list);
339 }
340
ParseBMPString(const uint8_t * bmp,uint32_t bmpLen,BSL_ASN1_Buffer * decode)341 static int32_t ParseBMPString(const uint8_t *bmp, uint32_t bmpLen, BSL_ASN1_Buffer *decode)
342 {
343 if (bmp == NULL || bmpLen == 0 || decode == NULL) {
344 return BSL_NULL_INPUT;
345 }
346 if (bmpLen % 2 != 0) { // multiple of 2
347 return BSL_INVALID_ARG;
348 }
349 uint8_t *tmp = (uint8_t *)BSL_SAL_Malloc(bmpLen / 2); // decodeLen = bmpLen/2
350 if (tmp == NULL) {
351 return BSL_MALLOC_FAIL;
352 }
353 for (uint32_t i = 0; i < bmpLen / 2; i++) { // decodeLen = bmpLen/2
354 tmp[i] = bmp[i * 2 + 1];
355 }
356 decode->buff = tmp;
357 decode->len = bmpLen / 2; // decodeLen = bmpLen/2
358 return BSL_SUCCESS;
359 }
360
EncodeBMPString(const uint8_t * in,uint32_t inLen,uint8_t * encode,uint32_t * offset)361 static void EncodeBMPString(const uint8_t *in, uint32_t inLen, uint8_t *encode, uint32_t *offset)
362 {
363 uint8_t *output = encode + *offset;
364 for (uint32_t i = 0; i < inLen; i++) {
365 output[2 * i + 1] = in[i]; // need 2 space, [0,0] -> after encode = [0, data];
366 output[2 * i + 0] = 0;
367 }
368 *offset += inLen * 2; // encodeLen = 2 * inLen
369 return;
370 }
371
372 /**
373 * Big numbers do not need to call this interface,
374 * the filled leading 0 has no effect on the result of large numbers, big numbers can be directly used asn's buff.
375 *
376 * It has been ensured at parsing time that the content to which the buff points is security for length within asn'len
377 */
BSL_ASN1_DecodePrimitiveItem(BSL_ASN1_Buffer * asn,void * decodeData)378 int32_t BSL_ASN1_DecodePrimitiveItem(BSL_ASN1_Buffer *asn, void *decodeData)
379 {
380 if (asn == NULL || decodeData == NULL) {
381 return BSL_NULL_INPUT;
382 }
383 switch (asn->tag) {
384 case BSL_ASN1_TAG_BOOLEAN:
385 return ParseBool(asn->buff, asn->len, decodeData);
386 case BSL_ASN1_TAG_INTEGER:
387 case BSL_ASN1_TAG_ENUMERATED:
388 return ParseInt(asn->buff, asn->len, decodeData);
389 case BSL_ASN1_TAG_BITSTRING:
390 return ParseBitString(asn->buff, asn->len, decodeData);
391 case BSL_ASN1_TAG_UTCTIME:
392 case BSL_ASN1_TAG_GENERALIZEDTIME:
393 return ParseTime(asn->tag, asn->buff, asn->len, decodeData);
394 case BSL_ASN1_TAG_BMPSTRING:
395 return ParseBMPString(asn->buff, asn->len, decodeData);
396 default:
397 break;
398 }
399 return BSL_ASN1_FAIL;
400 }
401
BSL_ASN1_AnyOrChoiceTagProcess(bool isAny,BSL_ASN1_AnyOrChoiceParam * tagCbinfo,uint8_t * tag)402 static int32_t BSL_ASN1_AnyOrChoiceTagProcess(bool isAny, BSL_ASN1_AnyOrChoiceParam *tagCbinfo, uint8_t *tag)
403 {
404 if (tagCbinfo->tagCb == NULL) {
405 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05065, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
406 "asn1: callback is null", 0, 0, 0, 0);
407 return BSL_ASN1_ERR_NO_CALLBACK;
408 }
409 int32_t type = isAny == true ? BSL_ASN1_TYPE_GET_ANY_TAG : BSL_ASN1_TYPE_CHECK_CHOICE_TAG;
410 int32_t ret = tagCbinfo->tagCb(type, tagCbinfo->idx, tagCbinfo->previousAsnOrTag, tag);
411 if (ret != BSL_SUCCESS) {
412 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05066, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
413 "asn1: callback is err %x", ret, 0, 0, 0);
414 }
415 return ret;
416 }
417
BSL_ASN1_ProcessWithoutDefOrOpt(BSL_ASN1_AnyOrChoiceParam * tagCbinfo,uint8_t realTag,uint8_t * expTag)418 static int32_t BSL_ASN1_ProcessWithoutDefOrOpt(BSL_ASN1_AnyOrChoiceParam *tagCbinfo, uint8_t realTag, uint8_t *expTag)
419 {
420 int32_t ret;
421 uint8_t tag = *expTag;
422 // Any and choice will not have a coexistence scenario, which is meaningless.
423 if (tag == BSL_ASN1_TAG_CHOICE) {
424 tagCbinfo->previousAsnOrTag = &realTag;
425 return BSL_ASN1_AnyOrChoiceTagProcess(false, tagCbinfo, expTag);
426 }
427 // The tags of any and normal must be present
428 if (tag == BSL_ASN1_TAG_ANY) {
429 ret = BSL_ASN1_AnyOrChoiceTagProcess(true, tagCbinfo, &tag);
430 if (ret != BSL_SUCCESS) {
431 return ret;
432 }
433 }
434 if (tag != realTag) {
435 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05067, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
436 "asn1: expected tag %x is not match %x", tag, realTag, 0, 0);
437 return BSL_ASN1_ERR_TAG_EXPECTED;
438 }
439 *expTag = realTag;
440
441 return BSL_SUCCESS;
442 }
443
444 /**
445 * Reference: X.690 Information technology - ASN.1 encoding rules: 8.3
446 * If the contents octect of an integer value encoding consist of more than one octet,
447 * then the bits of the first octet and bit 8 of the second octet:
448 * a): shall not all be ones; and
449 * b): shall not all be zero.
450 *
451 * Note: Currently, only positive integers are supported, and negative integers are not supported.
452 */
ProcessIntegerType(uint8_t * temp,uint32_t len,BSL_ASN1_Buffer * asn)453 int32_t ProcessIntegerType(uint8_t *temp, uint32_t len, BSL_ASN1_Buffer *asn)
454 {
455 // Check if it is a negative number
456 if (*temp & 0x80) {
457 return BSL_ASN1_ERR_DECODE_INT;
458 }
459
460 // Check if the first octet is 0 and the second octet is not 0
461 if (*temp == 0 && len > 1 && (*(temp + 1) & 0x80) == 0) {
462 return BSL_ASN1_ERR_DECODE_INT;
463 }
464
465 // Calculate the actual length (remove leading zeros)
466 uint32_t actualLen = len;
467 uint8_t *actualBuff = temp;
468 while (actualLen > 1 && *actualBuff == 0) {
469 actualLen--;
470 actualBuff++;
471 }
472 asn->len = actualLen;
473 asn->buff = actualBuff;
474 return BSL_SUCCESS;
475 }
476
ProcessTag(uint8_t flags,BSL_ASN1_AnyOrChoiceParam * tagCbinfo,uint8_t * temp,uint32_t tempLen,uint8_t * tag,BSL_ASN1_Buffer * asn)477 static int32_t ProcessTag(uint8_t flags, BSL_ASN1_AnyOrChoiceParam *tagCbinfo, uint8_t *temp, uint32_t tempLen,
478 uint8_t *tag, BSL_ASN1_Buffer *asn)
479 {
480 int32_t ret = BSL_SUCCESS;
481 if ((flags & BSL_ASN1_FLAG_OPTIONAL_DEFAUL) != 0) {
482 if (tempLen < 1) {
483 asn->tag = 0;
484 asn->len = 0;
485 asn->buff = NULL;
486 return BSL_SUCCESS;
487 }
488 if (*tag == BSL_ASN1_TAG_ANY) {
489 ret = BSL_ASN1_AnyOrChoiceTagProcess(true, tagCbinfo, tag);
490 if (ret != BSL_SUCCESS) {
491 return ret;
492 }
493 }
494
495 if (*tag == BSL_ASN1_TAG_CHOICE) {
496 tagCbinfo->previousAsnOrTag = temp;
497 ret = BSL_ASN1_AnyOrChoiceTagProcess(false, tagCbinfo, tag);
498 if (ret != BSL_SUCCESS) {
499 return ret;
500 }
501 }
502 if (*tag == BSL_ASN1_TAG_EMPTY) {
503 return BSL_ASN1_ERR_TAG_EXPECTED;
504 }
505
506 if (*tag != *temp) { // The optional or default scene is not encoded
507 asn->tag = 0;
508 asn->len = 0;
509 asn->buff = NULL;
510 }
511 } else {
512 /* No optional or default scenes, tag must exist */
513 if (tempLen < 1) {
514 return BSL_ASN1_ERR_DECODE_LEN;
515 }
516 ret = BSL_ASN1_ProcessWithoutDefOrOpt(tagCbinfo, *temp, tag);
517 }
518 return ret;
519 }
520
BSL_ASN1_ProcessNormal(BSL_ASN1_AnyOrChoiceParam * tagCbinfo,BSL_ASN1_TemplateItem * item,uint8_t ** encode,uint32_t * encLen,BSL_ASN1_Buffer * asn)521 static int32_t BSL_ASN1_ProcessNormal(BSL_ASN1_AnyOrChoiceParam *tagCbinfo,
522 BSL_ASN1_TemplateItem *item, uint8_t **encode, uint32_t *encLen, BSL_ASN1_Buffer *asn)
523 {
524 uint32_t len;
525 uint8_t tag = item->tag;
526 uint8_t *temp = *encode;
527 uint32_t tempLen = *encLen;
528
529 asn->tag = tag; // init tag
530 int32_t ret = ProcessTag(item->flags, tagCbinfo, temp, tempLen, &tag, asn);
531 if (ret != BSL_SUCCESS || asn->tag == 0) {
532 return ret;
533 }
534
535 temp++;
536 tempLen--;
537 ret = BSL_ASN1_DecodeLen(&temp, &tempLen, false, &len);
538 if (ret != BSL_SUCCESS) {
539 return ret;
540 }
541 asn->tag = tag; // update tag
542 if ((tag == BSL_ASN1_TAG_INTEGER || tag == BSL_ASN1_TAG_ENUMERATED) && len > 0) {
543 ret = ProcessIntegerType(temp, len, asn);
544 if (ret != BSL_SUCCESS) {
545 return ret;
546 }
547 } else {
548 asn->len = len;
549 asn->buff = (tag == BSL_ASN1_TAG_NULL) ? NULL : temp;
550 }
551
552 /* struct type, headerOnly flag is set, only the whole is parsed, otherwise the parsed content is traversed */
553 if (((item->tag & BSL_ASN1_TAG_CONSTRUCTED) != 0 && (item->flags & BSL_ASN1_FLAG_HEADERONLY) != 0) ||
554 (item->tag & BSL_ASN1_TAG_CONSTRUCTED) == 0) {
555 temp += len;
556 tempLen -= len;
557 }
558
559 *encode = temp;
560 *encLen = tempLen;
561 return BSL_SUCCESS;
562 }
563
BSL_ASN1_SkipChildNode(uint32_t idx,BSL_ASN1_TemplateItem * item,uint32_t count)564 uint32_t BSL_ASN1_SkipChildNode(uint32_t idx, BSL_ASN1_TemplateItem *item, uint32_t count)
565 {
566 uint32_t i = idx + 1;
567 for (; i < count; i++) {
568 if (item[i].depth <= item[idx].depth) {
569 break;
570 }
571 }
572 return i - idx;
573 }
574
BSL_ASN1_IsConstructItem(BSL_ASN1_TemplateItem * item)575 static bool BSL_ASN1_IsConstructItem(BSL_ASN1_TemplateItem *item)
576 {
577 return item->tag & BSL_ASN1_TAG_CONSTRUCTED;
578 }
579
BSL_ASN1_FillConstructItemWithNull(BSL_ASN1_Template * templ,uint32_t * templIdx,BSL_ASN1_Buffer * asnArr,uint32_t arrNum,uint32_t * arrIdx)580 static int32_t BSL_ASN1_FillConstructItemWithNull(BSL_ASN1_Template *templ, uint32_t *templIdx,
581 BSL_ASN1_Buffer *asnArr, uint32_t arrNum, uint32_t *arrIdx)
582 {
583 // The construct type value is marked headeronly
584 if ((templ->templItems[*templIdx].flags & BSL_ASN1_FLAG_HEADERONLY) != 0) {
585 if (*arrIdx >= arrNum) {
586 return BSL_ASN1_ERR_OVERFLOW;
587 } else {
588 asnArr[*arrIdx].tag = 0;
589 asnArr[*arrIdx].len = 0;
590 asnArr[*arrIdx].buff = 0;
591 (*arrIdx)++;
592 }
593 (*templIdx) += BSL_ASN1_SkipChildNode(*templIdx, templ->templItems, templ->templNum);
594 } else {
595 // This scenario does not record information about the parent node
596 (*templIdx)++;
597 }
598 return BSL_SUCCESS;
599 }
600
BSL_ASN1_SkipChildNodeAndFill(uint32_t * idx,BSL_ASN1_Template * templ,BSL_ASN1_Buffer * asnArr,uint32_t arrNum,uint32_t * arrIndex)601 int32_t BSL_ASN1_SkipChildNodeAndFill(uint32_t *idx, BSL_ASN1_Template *templ,
602 BSL_ASN1_Buffer *asnArr, uint32_t arrNum, uint32_t *arrIndex)
603 {
604 uint32_t arrIdx = *arrIndex;
605 uint32_t i = *idx;
606 for (; i < templ->templNum;) {
607 if (templ->templItems[i].depth <= templ->templItems[*idx].depth && i > *idx) {
608 break;
609 }
610 // There are also struct types under the processing parent
611 if (BSL_ASN1_IsConstructItem(&templ->templItems[i])) {
612 int32_t ret = BSL_ASN1_FillConstructItemWithNull(templ, &i, asnArr, arrNum, &arrIdx);
613 if (ret != BSL_SUCCESS) {
614 return ret;
615 }
616 } else {
617 asnArr[arrIdx].tag = 0;
618 asnArr[arrIdx].len = 0;
619 asnArr[arrIdx].buff = 0;
620 arrIdx++;
621 i++;
622 }
623 }
624 *arrIndex = arrIdx;
625 *idx = i;
626 return BSL_SUCCESS;
627 }
628
BSL_ASN1_ProcessConstructResult(BSL_ASN1_Template * templ,uint32_t * templIdx,BSL_ASN1_Buffer * asn,BSL_ASN1_Buffer * asnArr,uint32_t arrNum,uint32_t * arrIdx)629 int32_t BSL_ASN1_ProcessConstructResult(BSL_ASN1_Template *templ, uint32_t *templIdx, BSL_ASN1_Buffer *asn,
630 BSL_ASN1_Buffer *asnArr, uint32_t arrNum, uint32_t *arrIdx)
631 {
632 int32_t ret;
633 // Optional or default construct type, without any data to be parsed, need to skip all child nodes
634 if ((templ->templItems[*templIdx].flags & BSL_ASN1_FLAG_OPTIONAL_DEFAUL) != 0 && asn->tag == 0) {
635 ret = BSL_ASN1_SkipChildNodeAndFill(templIdx, templ, asnArr, arrNum, arrIdx);
636 if (ret != BSL_SUCCESS) {
637 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05068, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
638 "asn1: skip and fill node err %x, idx %u", ret, *templIdx, 0, 0);
639 return ret;
640 }
641 return BSL_SUCCESS;
642 }
643
644 if ((templ->templItems[*templIdx].flags & BSL_ASN1_FLAG_HEADERONLY) != 0) {
645 if (*arrIdx >= arrNum) {
646 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05069, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
647 "asn1: array idx %u, overflow %u, templ %u", *arrIdx, arrNum, *templIdx, 0);
648 return BSL_ASN1_ERR_OVERFLOW;
649 } else {
650 // Shallow copy of structure
651 asnArr[*arrIdx].tag = asn->tag;
652 asnArr[*arrIdx].len = asn->len;
653 asnArr[*arrIdx].buff = asn->buff;
654 (*arrIdx)++;
655 }
656 (*templIdx) += BSL_ASN1_SkipChildNode(*templIdx, templ->templItems, templ->templNum);
657 } else {
658 (*templIdx)++; // Non header only flags, do not fill this parse
659 }
660 return BSL_SUCCESS;
661 }
662
IsInvalidTempl(BSL_ASN1_Template * templ)663 static inline bool IsInvalidTempl(BSL_ASN1_Template *templ)
664 {
665 return templ == NULL || templ->templNum == 0 || templ->templItems == NULL;
666 }
IsInvalidAsns(BSL_ASN1_Buffer * asnArr,uint32_t arrNum)667 static inline bool IsInvalidAsns(BSL_ASN1_Buffer *asnArr, uint32_t arrNum)
668 {
669 return asnArr == NULL || arrNum == 0;
670 }
671
BSL_ASN1_DecodeTemplate(BSL_ASN1_Template * templ,BSL_ASN1_DecTemplCallBack decTemlCb,uint8_t ** encode,uint32_t * encLen,BSL_ASN1_Buffer * asnArr,uint32_t arrNum)672 int32_t BSL_ASN1_DecodeTemplate(BSL_ASN1_Template *templ, BSL_ASN1_DecTemplCallBack decTemlCb,
673 uint8_t **encode, uint32_t *encLen, BSL_ASN1_Buffer *asnArr, uint32_t arrNum)
674 {
675 int32_t ret;
676 if (IsInvalidTempl(templ) || encode == NULL || *encode == NULL || encLen == NULL || IsInvalidAsns(asnArr, arrNum)) {
677 return BSL_NULL_INPUT;
678 }
679 uint8_t *temp = *encode;
680 uint32_t tempLen = *encLen;
681 BSL_ASN1_Buffer asn = {0}; // temp var
682 uint32_t arrIdx = 0;
683 BSL_ASN1_Buffer previousAsn = {0};
684 BSL_ASN1_AnyOrChoiceParam tagCbinfo = {0, NULL, decTemlCb};
685
686 for (uint32_t i = 0; i < templ->templNum;) {
687 if (templ->templItems[i].depth > BSL_ASN1_MAX_TEMPLATE_DEPTH) {
688 return BSL_ASN1_ERR_MAX_DEPTH;
689 }
690 tagCbinfo.previousAsnOrTag = &previousAsn;
691 tagCbinfo.idx = i;
692 if (BSL_ASN1_IsConstructItem(&templ->templItems[i])) {
693 ret = BSL_ASN1_ProcessNormal(&tagCbinfo, &templ->templItems[i], &temp, &tempLen, &asn);
694 if (ret != BSL_SUCCESS) {
695 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05070, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
696 "asn1: parse construct item err %x, idx %u", ret, i, 0, 0);
697 return ret;
698 }
699 ret = BSL_ASN1_ProcessConstructResult(templ, &i, &asn, asnArr, arrNum, &arrIdx);
700 if (ret != BSL_SUCCESS) {
701 return ret;
702 }
703 } else {
704 ret = BSL_ASN1_ProcessNormal(&tagCbinfo, &templ->templItems[i], &temp, &tempLen, &asn);
705 if (ret != BSL_SUCCESS) {
706 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05071, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
707 "asn1: parse primitive item err %x, idx %u", ret, i, 0, 0);
708 return ret;
709 }
710 // Process no construct result
711 if (arrIdx >= arrNum) {
712 BSL_LOG_BINLOG_FIXLEN(BINLOG_ID05072, BSL_LOG_LEVEL_ERR, BSL_LOG_BINLOG_TYPE_RUN,
713 "asn1: array idx %u, overflow %u, templ %u", arrIdx, arrNum, i, 0);
714 return BSL_ASN1_ERR_OVERFLOW;
715 } else {
716 asnArr[arrIdx++] = asn; // Shallow copy of structure
717 }
718 i++;
719 }
720 previousAsn = asn;
721 }
722
723 *encode = temp;
724 *encLen = tempLen;
725 return BSL_SUCCESS;
726 }
727
728 /* Init the depth and flags of the items. */
EncodeInitItemFlag(BSL_ASN1_EncodeItem * eItems,BSL_ASN1_TemplateItem * tItems,uint32_t eleNum)729 static int32_t EncodeInitItemFlag(BSL_ASN1_EncodeItem *eItems, BSL_ASN1_TemplateItem *tItems, uint32_t eleNum)
730 {
731 uint32_t stack[BSL_ASN1_MAX_TEMPLATE_DEPTH + 1] = {0}; // store the index of the items
732 int32_t peek = 0;
733
734 /* Stack the first item */
735 if (tItems[0].depth > BSL_ASN1_MAX_TEMPLATE_DEPTH) {
736 return BSL_ASN1_ERR_MAX_DEPTH;
737 }
738 eItems[0].depth = tItems[0].depth;
739 eItems[0].optional = tItems[0].flags & BSL_ASN1_FLAG_OPTIONAL_DEFAUL;
740 stack[peek] = 0;
741
742 for (uint32_t i = 1; i < eleNum; i++) {
743 if (tItems[i].depth > BSL_ASN1_MAX_TEMPLATE_DEPTH) {
744 return BSL_ASN1_ERR_MAX_DEPTH;
745 }
746 eItems[i].depth = tItems[i].depth;
747 while (eItems[i].depth <= eItems[stack[peek]].depth) {
748 peek--;
749 }
750 /* After the above processing, the top of the stack is the parent node of the current node. */
751 /* The null type only inherits the optional tag of the parent node. */
752 eItems[i].optional = eItems[stack[peek]].optional;
753 if (tItems[i].tag != BSL_ASN1_TAG_NULL) {
754 eItems[i].optional |= (tItems[i].flags & BSL_ASN1_FLAG_OPTIONAL_DEFAUL);
755 }
756 eItems[i].skip = eItems[stack[peek]].skip == 1 || (tItems[stack[peek]].flags & BSL_ASN1_FLAG_HEADERONLY) != 0;
757 stack[++peek] = i;
758 }
759 return BSL_SUCCESS;
760 }
761
IsAnyOrChoice(uint8_t tag)762 static inline bool IsAnyOrChoice(uint8_t tag)
763 {
764 return tag == BSL_ASN1_TAG_ANY || tag == BSL_ASN1_TAG_CHOICE;
765 }
766
GetOctetNumOfUint(uint64_t number)767 static uint8_t GetOctetNumOfUint(uint64_t number)
768 {
769 uint8_t cnt = 0;
770 for (uint64_t i = number; i != 0; i >>= 8) { // one byte = 8 bits
771 cnt++;
772 }
773 return cnt;
774 }
775
GetLenOctetNum(uint32_t contentOctetNum)776 static uint8_t GetLenOctetNum(uint32_t contentOctetNum)
777 {
778 return contentOctetNum <= BSL_ASN1_DEFINITE_MAX_CONTENT_OCTET_NUM ? 1 : 1 + GetOctetNumOfUint(contentOctetNum);
779 }
780
GetContentLenOfInt(uint8_t * buff,uint32_t len,uint32_t * outLen)781 static int32_t GetContentLenOfInt(uint8_t *buff, uint32_t len, uint32_t *outLen)
782 {
783 if (len == 0) {
784 *outLen = 0;
785 return BSL_SUCCESS;
786 }
787 uint32_t res = len;
788 for (uint32_t i = 0; i < len; i++) {
789 if (buff[i] != 0) {
790 break;
791 }
792 res--;
793 }
794 if (res == 0) { // The current int value is 0
795 *outLen = 1;
796 return BSL_SUCCESS;
797 }
798
799 uint8_t high = buff[len - res] & 0x80;
800 if (high) {
801 if (res == UINT32_MAX) {
802 return BSL_ASN1_ERR_LEN_OVERFLOW;
803 }
804 res++;
805 }
806 *outLen = res;
807 return BSL_SUCCESS;
808 }
809
GetContentLen(BSL_ASN1_Buffer * asn,uint32_t * len)810 static int32_t GetContentLen(BSL_ASN1_Buffer *asn, uint32_t *len)
811 {
812 if (asn == NULL || len == NULL) {
813 return BSL_NULL_INPUT;
814 }
815 switch (asn->tag) {
816 case BSL_ASN1_TAG_NULL:
817 *len = 0;
818 return BSL_SUCCESS;
819 case BSL_ASN1_TAG_INTEGER:
820 case BSL_ASN1_TAG_ENUMERATED:
821 return GetContentLenOfInt(asn->buff, asn->len, len);
822 case BSL_ASN1_TAG_BITSTRING:
823 *len = ((BSL_ASN1_BitString *)asn->buff)->len;
824 if (*len == UINT32_MAX) {
825 return BSL_ASN1_ERR_LEN_OVERFLOW;
826 }
827 *len += 1;
828 return BSL_SUCCESS;
829 case BSL_ASN1_TAG_UTCTIME:
830 *len = BSL_ASN1_UTCTIME_LEN;
831 return BSL_SUCCESS;
832 case BSL_ASN1_TAG_GENERALIZEDTIME:
833 *len = BSL_ASN1_GENERALIZEDTIME_LEN;
834 return BSL_SUCCESS;
835 case BSL_ASN1_TAG_BMPSTRING:
836 if (asn->len > UINT32_MAX / 2) { // 2: Each character is 2 bytes
837 return BSL_ASN1_ERR_LEN_OVERFLOW;
838 }
839 *len = asn->len * 2; // 2: Each character is 2 bytes
840 return BSL_SUCCESS;
841 default:
842 *len = asn->len;
843 return BSL_SUCCESS;
844 }
845 }
846
ComputeOctetNum(bool optional,BSL_ASN1_EncodeItem * item,BSL_ASN1_Buffer * asn)847 static int32_t ComputeOctetNum(bool optional, BSL_ASN1_EncodeItem *item, BSL_ASN1_Buffer *asn)
848 {
849 if (optional && asn->len == 0 && (asn->tag != BSL_ASN1_TAG_NULL)) {
850 return BSL_SUCCESS;
851 }
852 uint32_t contentOctetNum = 0;
853 if (asn->len != 0) {
854 int32_t ret = GetContentLen(asn, &contentOctetNum);
855 if (ret != BSL_SUCCESS) {
856 return ret;
857 }
858 }
859
860 item->lenOctetNum = GetLenOctetNum(contentOctetNum);
861 uint64_t tmp = (uint64_t)item->lenOctetNum + contentOctetNum;
862 if (tmp > UINT32_MAX - 1) {
863 return BSL_ASN1_ERR_LEN_OVERFLOW;
864 }
865
866 item->asnOctetNum = 1 + item->lenOctetNum + contentOctetNum;
867 return BSL_SUCCESS;
868 }
869
ComputeConstructAsnOctetNum(bool optional,BSL_ASN1_TemplateItem * templ,BSL_ASN1_EncodeItem * item,uint32_t itemNum,uint32_t curIdx)870 static int32_t ComputeConstructAsnOctetNum(bool optional, BSL_ASN1_TemplateItem *templ, BSL_ASN1_EncodeItem *item,
871 uint32_t itemNum, uint32_t curIdx)
872 {
873 uint8_t curDepth = templ[curIdx].depth;
874 uint32_t contentOctetNum = 0;
875 for (uint32_t i = curIdx + 1; i < itemNum && templ[i].depth != curDepth; i++) {
876 if (templ[i].depth - curDepth == 1) {
877 if (item[i].asnOctetNum > UINT32_MAX - contentOctetNum) {
878 return BSL_ASN1_ERR_LEN_OVERFLOW;
879 }
880 contentOctetNum += item[i].asnOctetNum;
881 }
882 }
883 if (contentOctetNum == 0 && optional) {
884 return BSL_SUCCESS;
885 }
886 item[curIdx].lenOctetNum = GetLenOctetNum(contentOctetNum);
887
888 // Use 64-bit math to prevent overflow during calculation
889 uint64_t totalLen = (uint64_t)item[curIdx].lenOctetNum + contentOctetNum;
890
891 // Check for 32-bit overflow (ASN.1 length must fit in uint32_t)
892 if (totalLen > UINT32_MAX - 1) { // -1 accounts for tag byte
893 return BSL_ASN1_ERR_LEN_OVERFLOW;
894 }
895 item[curIdx].asnOctetNum = 1 + item[curIdx].lenOctetNum + contentOctetNum;
896 return BSL_SUCCESS;
897 }
898
899 /**
900 * ASN.1 Encode Init Item Content:
901 * 1. Reverse traversal template items (from deepest to root node)
902 * 2. Process two types:
903 * - Construct type (SEQUENCE/SET): Calculate total length of contained sub-items
904 * - Basic type: Validate tag and calculate encoding length
905 */
EncodeInitItemContent(BSL_ASN1_EncodeItem * eItems,BSL_ASN1_TemplateItem * tItems,uint32_t itemNum,BSL_ASN1_Buffer * asnArr,uint32_t * asnNum)906 static int32_t EncodeInitItemContent(BSL_ASN1_EncodeItem *eItems, BSL_ASN1_TemplateItem *tItems, uint32_t itemNum,
907 BSL_ASN1_Buffer *asnArr, uint32_t *asnNum)
908 {
909 int64_t asnIdx = (int64_t)*asnNum - 1;
910 uint8_t lastDepth = 0;
911 int32_t ret;
912
913 for (int64_t i = itemNum - 1; i >= 0; i--) {
914 if (eItems[i].skip == 1) {
915 continue;
916 }
917 if (tItems[i].depth < lastDepth) {
918 eItems[i].tag = tItems[i].tag;
919 ret = ComputeConstructAsnOctetNum(eItems[i].optional, tItems, eItems, itemNum, i);
920 if (ret != BSL_SUCCESS) {
921 return ret;
922 }
923 } else {
924 if (asnIdx < 0) {
925 return BSL_ASN1_ERR_ENCODE_ASN_LACK;
926 }
927 if (eItems[i].optional == false && asnArr[asnIdx].tag != tItems[i].tag && !IsAnyOrChoice(tItems[i].tag)) {
928 return BSL_ASN1_ERR_TAG_EXPECTED;
929 }
930 ret = ComputeOctetNum(eItems[i].optional, eItems + i, asnArr + asnIdx);
931 if (ret != BSL_SUCCESS) {
932 return ret;
933 }
934 eItems[i].tag = asnArr[asnIdx].tag;
935 eItems[i].asn = asnArr + asnIdx; // Shallow copy.
936 asnIdx--;
937 }
938 lastDepth = tItems[i].depth;
939 }
940 *asnNum = asnIdx + 1; // Update the number of used ASN buffers
941 return BSL_SUCCESS;
942 }
943
EncodeNumber(uint64_t data,uint32_t encodeLen,uint8_t * encode,uint32_t * offset)944 static void EncodeNumber(uint64_t data, uint32_t encodeLen, uint8_t *encode, uint32_t *offset)
945 {
946 uint64_t tmp = data;
947 /* Encode from back to front. */
948 uint32_t initOff = *offset + encodeLen - 1;
949 for (uint32_t i = 0; i < encodeLen; i++) {
950 *(encode + initOff - i) = (uint8_t)tmp;
951 tmp >>= 8; // one byte = 8 bits
952 }
953 *offset += encodeLen;
954 }
955
EncodeLength(uint8_t lenOctetNum,uint32_t contentOctetNum,uint8_t * encode,uint32_t * offset)956 static void EncodeLength(uint8_t lenOctetNum, uint32_t contentOctetNum, uint8_t *encode, uint32_t *offset)
957 {
958 if (contentOctetNum <= BSL_ASN1_DEFINITE_MAX_CONTENT_OCTET_NUM) {
959 *(encode + *offset) = (uint8_t)contentOctetNum;
960 *offset += 1;
961 return;
962 }
963
964 // the initial octet
965 *(encode + *offset) = BSL_ASN1_INDEFINITE_LENGTH | (lenOctetNum - 1);
966 *offset += 1;
967 // the subsequent octets
968 EncodeNumber(contentOctetNum, lenOctetNum - 1, encode, offset);
969 }
970
EncodeBool(bool * data,uint8_t * encode,uint32_t * offset)971 static inline void EncodeBool(bool *data, uint8_t *encode, uint32_t *offset)
972 {
973 *(encode + *offset) = *data == true ? 0xFF : 0x00;
974 *offset += 1;
975 }
976
EncodeBitString(BSL_ASN1_BitString * data,uint32_t encodeLen,uint8_t * encode,uint32_t * offset)977 static void EncodeBitString(BSL_ASN1_BitString *data, uint32_t encodeLen, uint8_t *encode, uint32_t *offset)
978 {
979 *(encode + *offset) = data->unusedBits;
980
981 for (uint32_t i = 0; i < encodeLen - 1; i++) {
982 *(encode + *offset + i + 1) = *(data->buff + i);
983 }
984 // Last octet: Set unused bits to 0
985 *(encode + *offset + encodeLen - 1) >>= data->unusedBits;
986 *(encode + *offset + encodeLen - 1) <<= data->unusedBits;
987 *offset += encodeLen;
988 }
989
EncodeNum2Ascii(uint8_t * encode,uint32_t * offset,uint8_t encodeLen,uint16_t number)990 static void EncodeNum2Ascii(uint8_t *encode, uint32_t *offset, uint8_t encodeLen, uint16_t number)
991 {
992 uint16_t tmp = number;
993 /* Encode from back to front. */
994 uint32_t initOff = *offset + encodeLen - 1;
995 for (uint32_t i = 0; i < encodeLen; i++) {
996 *(encode + initOff - i) = tmp % 10 + '0'; // 10: Take the lowest digit of a decimal number.
997 tmp /= 10; // 10: Get the number in decimal except for the lowest bit.
998 }
999 *offset += encodeLen;
1000 }
1001
EncodeTime(BSL_TIME * time,uint8_t tag,uint8_t * encode,uint32_t * offset)1002 static void EncodeTime(BSL_TIME *time, uint8_t tag, uint8_t *encode, uint32_t *offset)
1003 {
1004 if (tag == BSL_ASN1_TAG_UTCTIME) {
1005 EncodeNum2Ascii(encode, offset, 2, time->year % 100); // 2: YY, %100: Get the lower 2 digits of the number
1006 } else {
1007 EncodeNum2Ascii(encode, offset, 4, time->year); // 4: YYYY
1008 }
1009 EncodeNum2Ascii(encode, offset, 2, time->month); // 2: MM
1010 EncodeNum2Ascii(encode, offset, 2, time->day); // 2: DD
1011 EncodeNum2Ascii(encode, offset, 2, time->hour); // 2: HH
1012 EncodeNum2Ascii(encode, offset, 2, time->minute); // 2: MM
1013 EncodeNum2Ascii(encode, offset, 2, time->second); // 2: SS
1014 *(encode + *offset) = 'Z';
1015 *offset += 1;
1016 }
1017
EncodeInt(BSL_ASN1_Buffer * asn,uint32_t encodeLen,uint8_t * encode,uint32_t * offset)1018 static void EncodeInt(BSL_ASN1_Buffer *asn, uint32_t encodeLen, uint8_t *encode, uint32_t *offset)
1019 {
1020 if (encodeLen < asn->len) {
1021 /* Skip the copying of high-order octets with all zeros. */
1022 (void)memcpy_s(encode + *offset, encodeLen, asn->buff + (asn->len - encodeLen), encodeLen);
1023 } else {
1024 /* the high bit of positive number octet is 1 */
1025 (void)memcpy_s(encode + *offset + (encodeLen - asn->len), asn->len, asn->buff, asn->len);
1026 }
1027 *offset += encodeLen;
1028 }
1029
EncodeContent(BSL_ASN1_Buffer * asn,uint32_t encodeLen,uint8_t * encode,uint32_t * offset)1030 static void EncodeContent(BSL_ASN1_Buffer *asn, uint32_t encodeLen, uint8_t *encode, uint32_t *offset)
1031 {
1032 switch (asn->tag) {
1033 case BSL_ASN1_TAG_BOOLEAN:
1034 EncodeBool((bool *)asn->buff, encode, offset);
1035 return;
1036 case BSL_ASN1_TAG_INTEGER:
1037 case BSL_ASN1_TAG_ENUMERATED:
1038 EncodeInt(asn, encodeLen, encode, offset);
1039 return;
1040 case BSL_ASN1_TAG_BITSTRING:
1041 EncodeBitString((BSL_ASN1_BitString *)asn->buff, encodeLen, encode, offset);
1042 return;
1043 case BSL_ASN1_TAG_UTCTIME:
1044 case BSL_ASN1_TAG_GENERALIZEDTIME:
1045 EncodeTime((BSL_TIME *)asn->buff, asn->tag, encode, offset);
1046 return;
1047 case BSL_ASN1_TAG_BMPSTRING:
1048 EncodeBMPString(asn->buff, asn->len, encode, offset);
1049 return;
1050 default:
1051 (void)memcpy_s(encode + *offset, encodeLen, asn->buff, encodeLen);
1052 *offset += encodeLen;
1053 return;
1054 }
1055 }
1056
EncodeItem(BSL_ASN1_EncodeItem * eItems,uint32_t itemNum,uint8_t * encode)1057 static void EncodeItem(BSL_ASN1_EncodeItem *eItems, uint32_t itemNum, uint8_t *encode)
1058 {
1059 uint8_t *temp = encode;
1060 uint32_t offset = 0;
1061 uint32_t contentOctetNum;
1062
1063 for (uint32_t i = 0; i < itemNum; i++) {
1064 if (eItems[i].asnOctetNum == 0) {
1065 continue;
1066 }
1067 contentOctetNum = eItems[i].asnOctetNum - 1 - eItems[i].lenOctetNum;
1068
1069 /* tag */
1070 *(temp + offset) = eItems[i].tag;
1071 offset += 1;
1072 /* length */
1073 EncodeLength(eItems[i].lenOctetNum, contentOctetNum, encode, &offset);
1074 /* content */
1075 if (contentOctetNum != 0 && eItems[i].asn != NULL && eItems[i].asn->len != 0) {
1076 EncodeContent(eItems[i].asn, contentOctetNum, encode, &offset);
1077 }
1078 }
1079 }
1080
CheckBslTime(BSL_ASN1_Buffer * asn)1081 static int32_t CheckBslTime(BSL_ASN1_Buffer *asn)
1082 {
1083 if (asn->len != sizeof(BSL_TIME)) {
1084 return BSL_ASN1_ERR_CHECK_TIME;
1085 }
1086 BSL_TIME *time = (BSL_TIME *)asn->buff;
1087 if (BSL_DateTimeCheck(time) == false) {
1088 return BSL_ASN1_ERR_CHECK_TIME;
1089 }
1090 if (asn->tag == BSL_ASN1_TAG_UTCTIME && (time->year < 2000 || time->year > 2049)) { // Utc time range: [2000, 2049]
1091 return BSL_ASN1_ERR_ENCODE_UTC_TIME;
1092 }
1093 if (asn->tag == BSL_ASN1_TAG_GENERALIZEDTIME &&
1094 time->year > 9999) { // 9999: The number of digits for year must be 4.
1095 return BSL_ASN1_ERR_ENCODE_GENERALIZED_TIME;
1096 }
1097 return BSL_SUCCESS;
1098 }
1099
CheckBMPString(BSL_ASN1_Buffer * asn)1100 static int32_t CheckBMPString(BSL_ASN1_Buffer *asn)
1101 {
1102 for (uint32_t i = 0; i < asn->len; i++) {
1103 if (asn->buff[i] > 127) { // max ascii 127.
1104 return BSL_INVALID_ARG;
1105 }
1106 }
1107 return BSL_SUCCESS;
1108 }
1109
CheckAsn(BSL_ASN1_Buffer * asn)1110 static int32_t CheckAsn(BSL_ASN1_Buffer *asn)
1111 {
1112 switch (asn->tag) {
1113 case BSL_ASN1_TAG_BOOLEAN:
1114 return asn->len != sizeof(bool) ? BSL_ASN1_ERR_ENCODE_BOOL : BSL_SUCCESS;
1115 case BSL_ASN1_TAG_BITSTRING:
1116 if (asn->len != sizeof(BSL_ASN1_BitString)) {
1117 return BSL_ASN1_ERR_ENCODE_BIT_STRING;
1118 }
1119 BSL_ASN1_BitString *bs = (BSL_ASN1_BitString *)asn->buff;
1120 return bs->unusedBits > BSL_ASN1_VAL_MAX_BIT_STRING_LEN ? BSL_ASN1_ERR_ENCODE_BIT_STRING : BSL_SUCCESS;
1121 case BSL_ASN1_TAG_UTCTIME:
1122 case BSL_ASN1_TAG_GENERALIZEDTIME:
1123 return CheckBslTime(asn);
1124 case BSL_ASN1_TAG_BMPSTRING:
1125 return CheckBMPString(asn);
1126 default:
1127 return BSL_SUCCESS;
1128 }
1129 }
1130
CheckAsnArr(BSL_ASN1_Buffer * asnArr,uint32_t arrNum)1131 static int32_t CheckAsnArr(BSL_ASN1_Buffer *asnArr, uint32_t arrNum)
1132 {
1133 int32_t ret;
1134 for (uint32_t i = 0; i < arrNum; i++) {
1135 if (asnArr[i].buff != NULL) {
1136 ret = CheckAsn(asnArr + i);
1137 if (ret != BSL_SUCCESS) {
1138 return ret;
1139 }
1140 }
1141 }
1142 return BSL_SUCCESS;
1143 }
1144
EncodeItemInit(BSL_ASN1_EncodeItem * eItems,BSL_ASN1_TemplateItem * tItems,uint32_t itemNum,BSL_ASN1_Buffer * asnArr,uint32_t * arrNum)1145 static int32_t EncodeItemInit(BSL_ASN1_EncodeItem *eItems, BSL_ASN1_TemplateItem *tItems, uint32_t itemNum,
1146 BSL_ASN1_Buffer *asnArr, uint32_t *arrNum)
1147 {
1148 int32_t ret = EncodeInitItemFlag(eItems, tItems, itemNum);
1149 if (ret != BSL_SUCCESS) {
1150 return ret;
1151 }
1152
1153 return EncodeInitItemContent(eItems, tItems, itemNum, asnArr, arrNum);
1154 }
1155
EncodeInit(BSL_ASN1_EncodeItem * eItems,BSL_ASN1_Template * templ,BSL_ASN1_Buffer * asnArr,uint32_t arrNum,uint32_t * encodeLen)1156 static int32_t EncodeInit(BSL_ASN1_EncodeItem *eItems, BSL_ASN1_Template *templ, BSL_ASN1_Buffer *asnArr,
1157 uint32_t arrNum, uint32_t *encodeLen)
1158 {
1159 uint32_t tempArrNum = arrNum;
1160 uint32_t stBegin;
1161 uint32_t stEnd = templ->templNum - 1;
1162 int32_t ret;
1163
1164 uint32_t i = templ->templNum;
1165 while (i-- > 0) {
1166 if (templ->templItems[i].depth > BSL_ASN1_MAX_TEMPLATE_DEPTH) {
1167 return BSL_ASN1_ERR_MAX_DEPTH;
1168 }
1169 if (templ->templItems[i].depth != 0) {
1170 continue;
1171 }
1172 stBegin = i;
1173 ret = EncodeItemInit(eItems + stBegin, templ->templItems + stBegin, stEnd - stBegin + 1, asnArr, &tempArrNum);
1174 if (ret != BSL_SUCCESS) {
1175 return ret;
1176 }
1177 if ((eItems + stBegin)->asnOctetNum > UINT32_MAX - *encodeLen) {
1178 return BSL_ASN1_ERR_LEN_OVERFLOW;
1179 }
1180 *encodeLen += (eItems + stBegin)->asnOctetNum;
1181 stEnd = i - 1;
1182 }
1183 if (tempArrNum != 0) { // Check whether all the asn-item has been used.
1184 return BSL_ASN1_ERR_ENCODE_ASN_TOO_MUCH;
1185 }
1186 return BSL_SUCCESS;
1187 }
1188
BSL_ASN1_EncodeTemplate(BSL_ASN1_Template * templ,BSL_ASN1_Buffer * asnArr,uint32_t arrNum,uint8_t ** encode,uint32_t * encLen)1189 int32_t BSL_ASN1_EncodeTemplate(BSL_ASN1_Template *templ, BSL_ASN1_Buffer *asnArr, uint32_t arrNum, uint8_t **encode,
1190 uint32_t *encLen)
1191 {
1192 if (IsInvalidTempl(templ) || IsInvalidAsns(asnArr, arrNum) || encode == NULL || *encode != NULL || encLen == NULL) {
1193 return BSL_INVALID_ARG;
1194 }
1195 int32_t ret = CheckAsnArr(asnArr, arrNum);
1196 if (ret != BSL_SUCCESS) {
1197 return ret;
1198 }
1199
1200 BSL_ASN1_EncodeItem *eItems = (BSL_ASN1_EncodeItem *)BSL_SAL_Calloc(templ->templNum, sizeof(BSL_ASN1_EncodeItem));
1201 if (eItems == NULL) {
1202 return BSL_MALLOC_FAIL;
1203 }
1204 uint32_t encodeLen = 0;
1205 ret = EncodeInit(eItems, templ, asnArr, arrNum, &encodeLen);
1206 if (ret != BSL_SUCCESS) {
1207 BSL_SAL_Free(eItems);
1208 return ret;
1209 }
1210
1211 *encode = (uint8_t *)BSL_SAL_Calloc(1, encodeLen);
1212 if (*encode == NULL) {
1213 BSL_SAL_Free(eItems);
1214 return BSL_MALLOC_FAIL;
1215 }
1216 EncodeItem(eItems, templ->templNum, *encode);
1217 *encLen = encodeLen;
1218
1219 BSL_SAL_Free(eItems);
1220 return BSL_SUCCESS;
1221 }
1222
BSL_ASN1_EncodeListItem(uint8_t tag,uint32_t listSize,BSL_ASN1_Template * templ,BSL_ASN1_Buffer * asnArr,uint32_t arrNum,BSL_ASN1_Buffer * out)1223 int32_t BSL_ASN1_EncodeListItem(uint8_t tag, uint32_t listSize, BSL_ASN1_Template *templ, BSL_ASN1_Buffer *asnArr,
1224 uint32_t arrNum, BSL_ASN1_Buffer *out)
1225 {
1226 if ((tag != BSL_ASN1_TAG_SEQUENCE && tag != BSL_ASN1_TAG_SET) || IsInvalidTempl(templ) ||
1227 IsInvalidAsns(asnArr, arrNum) || listSize == 0 || arrNum % listSize != 0 || out == NULL || out->buff != NULL) {
1228 return BSL_INVALID_ARG;
1229 }
1230 int32_t ret = CheckAsnArr(asnArr, arrNum);
1231 if (ret != BSL_SUCCESS) {
1232 return ret;
1233 }
1234 if (listSize > UINT32_MAX / templ->templNum) {
1235 return BSL_ASN1_ERR_LEN_OVERFLOW;
1236 }
1237
1238 BSL_ASN1_EncodeItem *eItems =
1239 (BSL_ASN1_EncodeItem *)BSL_SAL_Calloc(templ->templNum * listSize, sizeof(BSL_ASN1_EncodeItem));
1240 if (eItems == NULL) {
1241 return BSL_MALLOC_FAIL;
1242 }
1243 uint32_t encodeLen = 0;
1244 uint32_t itemAsnNum;
1245 for (uint32_t i = 0; i < listSize; i++) {
1246 itemAsnNum = arrNum / listSize;
1247 ret = EncodeItemInit(
1248 eItems + i * templ->templNum, templ->templItems, templ->templNum, asnArr + i * itemAsnNum, &itemAsnNum);
1249 if (ret != BSL_SUCCESS) {
1250 BSL_SAL_Free(eItems);
1251 return ret;
1252 }
1253 if (itemAsnNum != 0) {
1254 BSL_SAL_Free(eItems);
1255 return BSL_ASN1_ERR_ENCODE_ASN_TOO_MUCH;
1256 }
1257 if (eItems[i * templ->templNum].asnOctetNum > UINT32_MAX - encodeLen) {
1258 BSL_SAL_Free(eItems);
1259 return BSL_ASN1_ERR_LEN_OVERFLOW;
1260 }
1261 encodeLen += eItems[i * templ->templNum].asnOctetNum;
1262 }
1263
1264 out->buff = (uint8_t *)BSL_SAL_Calloc(1, encodeLen);
1265 if (out->buff == NULL) {
1266 BSL_SAL_Free(eItems);
1267 return BSL_MALLOC_FAIL;
1268 }
1269 uint8_t *encode = out->buff;
1270 for (uint32_t i = 0; i < listSize; i++) {
1271 EncodeItem(eItems + i * templ->templNum, templ->templNum, encode);
1272 encode += (eItems + i * templ->templNum)->asnOctetNum;
1273 }
1274
1275 out->tag = tag | BSL_ASN1_TAG_CONSTRUCTED;
1276 out->len = encodeLen;
1277
1278 BSL_SAL_Free(eItems);
1279 return BSL_SUCCESS;
1280 }
1281
BSL_ASN1_EncodeLimb(uint8_t tag,uint64_t limb,BSL_ASN1_Buffer * asn)1282 int32_t BSL_ASN1_EncodeLimb(uint8_t tag, uint64_t limb, BSL_ASN1_Buffer *asn)
1283 {
1284 if ((tag != BSL_ASN1_TAG_INTEGER && tag != BSL_ASN1_TAG_ENUMERATED) || asn == NULL || asn->buff != NULL) {
1285 return BSL_INVALID_ARG;
1286 }
1287
1288 asn->tag = tag;
1289 asn->len = limb == 0 ? 1 : GetOctetNumOfUint(limb);
1290 asn->buff = (uint8_t *)BSL_SAL_Calloc(1, asn->len);
1291 if (asn->buff == NULL) {
1292 return BSL_MALLOC_FAIL;
1293 }
1294 if (limb == 0) {
1295 return BSL_SUCCESS;
1296 }
1297 uint32_t offset = 0;
1298 EncodeNumber(limb, asn->len, asn->buff, &offset);
1299 return BSL_SUCCESS;
1300 }
1301
BSL_ASN1_GetEncodeLen(uint32_t contentLen,uint32_t * encodeLen)1302 int32_t BSL_ASN1_GetEncodeLen(uint32_t contentLen, uint32_t *encodeLen)
1303 {
1304 if (encodeLen == NULL) {
1305 return BSL_NULL_INPUT;
1306 }
1307 uint8_t lenOctetNum = GetLenOctetNum(contentLen);
1308 if (contentLen > (UINT32_MAX - lenOctetNum - 1)) {
1309 return BSL_ASN1_ERR_LEN_OVERFLOW;
1310 }
1311
1312 *encodeLen = 1 + lenOctetNum + contentLen;
1313 return BSL_SUCCESS;
1314 }
1315