• 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 
16 #ifndef BSL_ASN1_H
17 #define BSL_ASN1_H
18 
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <stdbool.h>
22 #include "bsl_list.h"
23 #include "bsl_uio.h"
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 #define BSL_ASN1_CLASS_UNIVERSAL       0x0   /* bit8 0, bit7 0 */
30 #define BSL_ASN1_CLASS_APPLICATION     0x40  /* bit8 0, bit7 1 */
31 #define BSL_ASN1_CLASS_CTX_SPECIFIC    0x80  /* bit8 1, bit7 0 */
32 #define BSL_ASN1_CLASS_PRIVATE         0xC0  /* bit8 1, bit7 1 */
33 
34 #define BSL_ASN1_TAG_CONSTRUCTED       0x20
35 
36 /* ASN1 tag from x.680  */
37 #define BSL_ASN1_TAG_BOOLEAN           0x01
38 #define BSL_ASN1_TAG_INTEGER           0x02
39 #define BSL_ASN1_TAG_BITSTRING         0x03
40 #define BSL_ASN1_TAG_OCTETSTRING       0x04
41 #define BSL_ASN1_TAG_NULL              0x05
42 #define BSL_ASN1_TAG_OBJECT_ID         0x06
43 #define BSL_ASN1_TAG_OBJECT_DESCP      0x07
44 #define BSL_ASN1_TAG_INSTANCE_OF       0x08
45 #define BSL_ASN1_TAG_REAL              0x09
46 #define BSL_ASN1_TAG_ENUMERATED        0x0A
47 #define BSL_ASN1_TAG_EMBEDDED_PDV      0x0B
48 #define BSL_ASN1_TAG_UTF8STRING        0x0C
49 #define BSL_ASN1_TAG_RALATIVE_ID       0x0D
50 #define BSL_ASN1_TAG_TIME              0x0E
51 #define BSL_ASN1_TAG_SEQUENCE          0x10
52 #define BSL_ASN1_TAG_SET               0x11
53 #define BSL_ASN1_TAG_PRINTABLESTRING   0x13
54 #define BSL_ASN1_TAG_IA5STRING         0x16
55 
56 #define BSL_ASN1_TAG_UTCTIME           0x17
57 #define BSL_ASN1_TAG_GENERALIZEDTIME   0x18
58 #define BSL_ASN1_TAG_BMPSTRING         0x1E
59 
60 /* Custom types, use private class to prevent conflicts */
61 #define BSL_ASN1_TAG_CHOICE (BSL_ASN1_CLASS_PRIVATE | 1)
62 #define BSL_ASN1_TAG_ANY (BSL_ASN1_CLASS_PRIVATE | 2)
63 #define BSL_ASN1_TAG_EMPTY 0x00 /* Empty tag, used to indicate that the tag is not encoded */
64 
65 /* The current value is flags, is used to guide asn1 encoding or decoding */
66 #define BSL_ASN1_FLAG_OPTIONAL 1
67 /* The current value is default, is used to guide asn1 encoding or decoding */
68 #define BSL_ASN1_FLAG_DEFAULT  2
69 /* Only parsing or encoding headers, and child nodes are not traversed */
70 #define BSL_ASN1_FLAG_HEADERONLY 4
71 /* The implied values are of the same type */
72 #define BSL_ASN1_FLAG_SAME 8
73 
74 #define BSL_ASN1_MAX_TEMPLATE_DEPTH 6
75 
76 #define BSL_ASN1_UTCTIME_LEN 13         // YYMMDDHHMMSSZ
77 #define BSL_ASN1_GENERALIZEDTIME_LEN 15 // YYYYMMDDHHMMSSZ
78 
79 #define BSL_ASN1_List BslList
80 
81 typedef enum {
82     BSL_ASN1_TYPE_GET_ANY_TAG = 0,
83     BSL_ASN1_TYPE_CHECK_CHOICE_TAG = 1
84 } BSL_ASN1_CALLBACK_TYPE;
85 
86 typedef struct _BSL_ASN1_TemplateItem {
87     /* exptect tag */
88     uint8_t tag;
89     /* corresponding to the tag flag */
90     uint8_t flags : 5;
91     uint8_t depth : 3;
92 } BSL_ASN1_TemplateItem;
93 
94 typedef struct _BSL_ASN1_Template {
95     BSL_ASN1_TemplateItem *templItems;
96     uint32_t templNum;
97 } BSL_ASN1_Template;
98 
99 typedef struct _BSL_ASN1_Buffer {
100     uint8_t tag;
101     uint32_t len;
102     uint8_t *buff;
103 } BSL_ASN1_Buffer;
104 
105 typedef struct _BSL_ASN1_BitString {
106     uint8_t *buff;
107     uint32_t len;
108     uint8_t unusedBits;
109 } BSL_ASN1_BitString;
110 
111 /**
112  * @ingroup bsl_asn1
113  * @brief The extension function for template decoding is used to handle decoding of uncertain data types.
114  *
115  * @param type [IN] BSL_ASN1_CALLBACK_TYPE
116  * @param idx [IN] The position of the data to be processed in the template.
117  * @param data [IN] The data to be processed.
118  * @param expVal [OUT] Output value.
119  */
120 typedef int32_t(*BSL_ASN1_DecTemplCallBack)(int32_t type, uint32_t idx, void *data, void *expVal);
121 
122 /**
123  * @ingroup bsl_asn1
124  * @brief The extension function for template decoding is used to convert an ASN item into a list.
125  *
126  * @param layer [IN] The layer of a list, used to construct the name node will use.
127  * @param asn [IN] The asn1 item to be decoded.
128  * @param cbParam [IN/OUT] The other parameters for decoding.
129  * @param list [OUT] Output value.
130  */
131 typedef int32_t(*BSL_ASN1_ParseListAsnItem)(uint32_t layer, BSL_ASN1_Buffer *asn, void *cbParam, BSL_ASN1_List *list);
132 
133 typedef struct _BSL_ASN1_DecodeListParam {
134     uint32_t layer;
135     uint8_t *expTag;
136 } BSL_ASN1_DecodeListParam;
137 
138 /**
139  * @ingroup bsl_asn1
140  * @brief Obtain the length of V or LV in an ASN1 TLV structure.
141  *
142  * @param encode [IN/OUT] Data to be decoded. Update the offset after decoding.
143  * @param encLen [IN/OUT] The length of the data to be decoded.
144  * @param completeLen [IN] True: Get the length of L+V; False: Get the length of V.
145  * @param len [OUT] Output.
146  * @retval  BSL_SUCCESS, success.
147  *          Other error codes see the bsl_errno.h.
148  */
149 int32_t BSL_ASN1_DecodeLen(uint8_t **encode, uint32_t *encLen, bool completeLen, uint32_t *len);
150 
151 /**
152  * @ingroup bsl_asn1
153  * @brief Decode the tag and length fields of an ASN.1 TLV structure and validate against expected tag.
154  *
155  * @param tag [IN] Expected ASN.1 tag value to validate against.
156  * @param encode [IN/OUT] Pointer to buffer containing encoded data. Updated to point after tag and length fields.
157  * @param encLen [IN/OUT] Length of remaining encoded data. Updated to reflect bytes consumed.
158  * @param valLen [OUT] Length of the value field in bytes.
159  * @retval BSL_SUCCESS Successfully decoded tag and length fields.
160  *         BSL_NULL_INPUT Invalid NULL parameters.
161  *         BSL_INVALID_ARG Buffer too small.
162  *         BSL_ASN1_ERR_MISMATCH_TAG Tag does not match expected value.
163  *         Other error codes see bsl_errno.h.
164  */
165 int32_t BSL_ASN1_DecodeTagLen(uint8_t tag, uint8_t **encode, uint32_t *encLen, uint32_t *valLen);
166 
167 /**
168  * @ingroup bsl_asn1
169  * @brief Decoding data of type 'SEQUENCE OF' or 'SET OF'.
170  *
171  * @param param [IN] The parameters of the data to be decoded.
172  * @param asn [IN] The data to be decoded.
173  * @param parseListItemCb [IN] User defined callback function used to convert an ASN item into a list.
174  * @param cbParam [IN/OUT] The parameters in the callback function.
175  * @param list [OUT] Decoding result.
176  * @retval  BSL_SUCCESS, success.
177  *          Other error codes see the bsl_errno.h.
178  */
179 int32_t BSL_ASN1_DecodeListItem(BSL_ASN1_DecodeListParam *param, BSL_ASN1_Buffer *asn,
180     BSL_ASN1_ParseListAsnItem parseListItemCb, void *cbParam, BSL_ASN1_List *list);
181 
182 /**
183  * @ingroup bsl_asn1
184  * @brief Decoding of primitive type data.
185  *
186  * @param asn [IN] The data to be decoded.
187  * @param decodeData [OUT] Decoding result.
188  * @retval  BSL_SUCCESS, success.
189  *          Other error codes see the bsl_errno.h.
190  */
191 int32_t BSL_ASN1_DecodePrimitiveItem(BSL_ASN1_Buffer *asn, void *decodeData);
192 
193 /**
194  * @ingroup bsl_asn1
195  * @brief Template decoding method.
196  *
197  * @param templ [IN] Encoding template.
198  * @param decTemlCb [IN] Function for handling uncertain types of data.
199  * @param encode [IN/OUT] Data to be decoded. Update the offset after decoding.
200  * @param encLen [IN/OUT] The length of the data to be decoded.
201  * @param asnArr [OUT] List of data to be decoded.
202  * @param arrNum [IN] The number of data to be encoded, which is determined by the template.
203  * @retval  BSL_SUCCESS, success.
204  *          Other error codes see the bsl_errno.h.
205  */
206 int32_t BSL_ASN1_DecodeTemplate(BSL_ASN1_Template *templ, BSL_ASN1_DecTemplCallBack decTemlCb,
207     uint8_t **encode, uint32_t *encLen, BSL_ASN1_Buffer *asnArr, uint32_t arrNum);
208 
209 /**
210  * @ingroup bsl_asn1
211  * @brief Decode one asn1 item.
212  *
213  * @param encode [IN/OUT] Data to be decoded. Update the offset after decoding.
214  * @param encLen [IN/OUT] The length of the data to be decoded.
215  * @param asnItem [OUT] Output.
216  * @retval  BSL_SUCCESS, success.
217  *          Other error codes see the bsl_errno.h.
218  */
219 int32_t BSL_ASN1_DecodeItem(uint8_t **encode, uint32_t *encLen, BSL_ASN1_Buffer *asnItem);
220 
221 /**
222  * @ingroup bsl_asn1
223  * @brief Obtain the length of an ASN1 TLV structure.
224  *
225  * @param data [IN] Data to be decoded. Update the offset after decoding.
226  * @param dataLen [OUT] Decoding result.
227  * @retval  BSL_SUCCESS, success.
228  *          Other error codes see the bsl_errno.h.
229  */
230 int32_t BSL_ASN1_GetCompleteLen(uint8_t *data, uint32_t *dataLen);
231 
232 /**
233  * @ingroup bsl_asn1
234  * @brief Template encoding method.
235  *
236  * @attention
237  *  1. For SET types: The elements in the template should be sorted into tag order.
238  *  2. The type for the following types of BSL_ASN1_Buffer.buff are as follows:
239  *    a. BSL_ASN1_TAG_BOOLEAN: bool *
240  *    b. BSL_ASN1_TAG_BITSTRING: BSL_ASN1_BitString *
241  *    c. BSL_ASN1_TAG_UTCTIME|BSL_ASN1_TAG_GENERALIZEDTIME: BSL_TIME *
242  *
243  * @param templ [IN] Encoding template.
244  * @param asnArr [IN] List of data to be encoded.
245  * @param arrNum [IN] The number of data to be encoded, which is determined by the template.
246  * @param encode [OUT] Encoding result.
247  * @param encLen [OUT] Encoding length.
248  * @retval  BSL_SUCCESS, success.
249  *          Other error codes see the bsl_errno.h.
250  */
251 int32_t BSL_ASN1_EncodeTemplate(BSL_ASN1_Template *templ, BSL_ASN1_Buffer *asnArr, uint32_t arrNum,
252     uint8_t **encode, uint32_t *encLen);
253 
254 /**
255  * @ingroup bsl_asn1
256  * @brief Encoding data of type 'SEQUENCE OF' or 'SET OF'.
257  *
258  * @attention
259  *   1. BSL_ASN1_TAG_SEQUENCE is type 'SEQUENCE OF'.
260  *   2. BSL_ASN1_TAG_SET is type 'SET OF'.
261  *   3. The sorting in 'SET OF' is currently not supported.
262  *
263  * @param tag [IN] BSL_ASN1_TAG_SEQUENCE or BSL_ASN1_TAG_SET
264  * @param listSize [IN] The number of elements in the list.
265  * @param templ [IN] Template for elements in the list.
266  * @param asnArr [IN] List of data to be encoded.
267  * @param arrNum [IN] The number of data to be encoded.
268  * @param out [OUT] Encoding result.
269  * @retval  BSL_SUCCESS, success.
270  *          Other error codes see the bsl_errno.h.
271  */
272 int32_t BSL_ASN1_EncodeListItem(uint8_t tag, uint32_t listSize, BSL_ASN1_Template *templ, BSL_ASN1_Buffer *asnArr,
273     uint32_t arrNum, BSL_ASN1_Buffer *out);
274 
275 /**
276  * @ingroup bsl_asn1
277  * @brief Encode the smaller positive integer.
278  *
279  * @param tag [IN] BSL_ASN1_TAG_INTEGER or BSL_ASN1_TAG_ENUMERATED
280  * @param limb [IN] Positive integer.
281  * @param asn [OUT] Encoding result.
282  * @retval  BSL_SUCCESS, success.
283  *          Other error codes see the bsl_errno.h.
284  */
285 int32_t BSL_ASN1_EncodeLimb(uint8_t tag, uint64_t limb, BSL_ASN1_Buffer *asn);
286 
287 /**
288  * @ingroup bsl_asn1
289  * @brief Calculate the total encoding length for a ASN.1 type through the content length.
290  *
291  * @param contentLen [IN] The length of the content to be encoded.
292  * @param encodeLen [OUT] The total number of bytes needed for DER encoding.
293  * @retval  BSL_SUCCESS, success.
294  *          Other error codes see the bsl_errno.h.
295  */
296 int32_t BSL_ASN1_GetEncodeLen(uint32_t contentLen, uint32_t *encodeLen);
297 
298 /**
299  * @ingroup bsl_asn1
300  * @brief Print asn1 data according to the format.
301  *
302  * @param layer [IN] Print layer.
303  * @param uio [IN/OUT] Print uio context.
304  * @param fmt [IN] Print format.
305  * @retval  BSL_SUCCESS, success.
306  *          Other error codes see the bsl_errno.h.
307  */
308 int32_t BSL_ASN1_Printf(uint32_t layer, BSL_UIO *uio, const char *fmt, ...);
309 
310 /**
311  * @ingroup bsl_asn1
312  * @brief Print asn1 data.
313  *
314  * @param layer [IN] Print layer.
315  * @param uio [IN/OUT] Print uio context.
316  * @param buff [IN] Print buffer.
317  * @param buffLen [IN] Print buffer length.
318  * @retval  BSL_SUCCESS, success.
319  *          Other error codes see the bsl_errno.h.
320  */
321 int32_t BSL_ASN1_PrintfBuff(uint32_t layer, BSL_UIO *uio, const void *buff, uint32_t buffLen);
322 
323 #ifdef __cplusplus
324 }
325 #endif
326 
327 #endif // BSL_ASN1_H
328