• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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