4 * \brief Generic ASN.1 parsing
\r
7 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
\r
8 * SPDX-License-Identifier: Apache-2.0
\r
10 * Licensed under the Apache License, Version 2.0 (the "License"); you may
\r
11 * not use this file except in compliance with the License.
\r
12 * You may obtain a copy of the License at
\r
14 * http://www.apache.org/licenses/LICENSE-2.0
\r
16 * Unless required by applicable law or agreed to in writing, software
\r
17 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
\r
18 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
19 * See the License for the specific language governing permissions and
\r
20 * limitations under the License.
\r
22 * This file is part of mbed TLS (https://tls.mbed.org)
\r
24 #ifndef MBEDTLS_ASN1_H
\r
25 #define MBEDTLS_ASN1_H
\r
27 #if !defined(MBEDTLS_CONFIG_FILE)
\r
30 #include MBEDTLS_CONFIG_FILE
\r
35 #if defined(MBEDTLS_BIGNUM_C)
\r
40 * \addtogroup asn1_module
\r
45 * \name ASN1 Error codes
\r
46 * These error codes are OR'ed to X509 error codes for
\r
47 * higher error granularity.
\r
48 * ASN1 is a standard to specify data structures.
\r
51 #define MBEDTLS_ERR_ASN1_OUT_OF_DATA -0x0060 /**< Out of data when parsing an ASN1 data structure. */
\r
52 #define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG -0x0062 /**< ASN1 tag was of an unexpected value. */
\r
53 #define MBEDTLS_ERR_ASN1_INVALID_LENGTH -0x0064 /**< Error when trying to determine the length or invalid length. */
\r
54 #define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH -0x0066 /**< Actual length differs from expected length. */
\r
55 #define MBEDTLS_ERR_ASN1_INVALID_DATA -0x0068 /**< Data is invalid. (not used) */
\r
56 #define MBEDTLS_ERR_ASN1_ALLOC_FAILED -0x006A /**< Memory allocation failed */
\r
57 #define MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -0x006C /**< Buffer too small when writing ASN.1 data structure. */
\r
62 * \name DER constants
\r
63 * These constants comply with the DER encoded ASN.1 type tags.
\r
64 * DER encoding uses hexadecimal representation.
\r
65 * An example DER sequence is:\n
\r
66 * - 0x02 -- tag indicating INTEGER
\r
67 * - 0x01 -- length in octets
\r
69 * Such sequences are typically read into \c ::mbedtls_x509_buf.
\r
72 #define MBEDTLS_ASN1_BOOLEAN 0x01
\r
73 #define MBEDTLS_ASN1_INTEGER 0x02
\r
74 #define MBEDTLS_ASN1_BIT_STRING 0x03
\r
75 #define MBEDTLS_ASN1_OCTET_STRING 0x04
\r
76 #define MBEDTLS_ASN1_NULL 0x05
\r
77 #define MBEDTLS_ASN1_OID 0x06
\r
78 #define MBEDTLS_ASN1_UTF8_STRING 0x0C
\r
79 #define MBEDTLS_ASN1_SEQUENCE 0x10
\r
80 #define MBEDTLS_ASN1_SET 0x11
\r
81 #define MBEDTLS_ASN1_PRINTABLE_STRING 0x13
\r
82 #define MBEDTLS_ASN1_T61_STRING 0x14
\r
83 #define MBEDTLS_ASN1_IA5_STRING 0x16
\r
84 #define MBEDTLS_ASN1_UTC_TIME 0x17
\r
85 #define MBEDTLS_ASN1_GENERALIZED_TIME 0x18
\r
86 #define MBEDTLS_ASN1_UNIVERSAL_STRING 0x1C
\r
87 #define MBEDTLS_ASN1_BMP_STRING 0x1E
\r
88 #define MBEDTLS_ASN1_PRIMITIVE 0x00
\r
89 #define MBEDTLS_ASN1_CONSTRUCTED 0x20
\r
90 #define MBEDTLS_ASN1_CONTEXT_SPECIFIC 0x80
\r
93 * Bit masks for each of the components of an ASN.1 tag as specified in
\r
94 * ITU X.690 (08/2015), section 8.1 "General rules for encoding",
\r
95 * paragraph 8.1.2.2:
\r
98 * +-------+-----+------------+
\r
99 * | Class | P/C | Tag number |
\r
100 * +-------+-----+------------+
\r
102 #define MBEDTLS_ASN1_TAG_CLASS_MASK 0xC0
\r
103 #define MBEDTLS_ASN1_TAG_PC_MASK 0x20
\r
104 #define MBEDTLS_ASN1_TAG_VALUE_MASK 0x1F
\r
107 /* \} addtogroup asn1_module */
\r
109 /** Returns the size of the binary string, without the trailing \\0 */
\r
110 #define MBEDTLS_OID_SIZE(x) (sizeof(x) - 1)
\r
113 * Compares an mbedtls_asn1_buf structure to a reference OID.
\r
115 * Only works for 'defined' oid_str values (MBEDTLS_OID_HMAC_SHA1), you cannot use a
\r
116 * 'unsigned char *oid' here!
\r
118 #define MBEDTLS_OID_CMP(oid_str, oid_buf) \
\r
119 ( ( MBEDTLS_OID_SIZE(oid_str) != (oid_buf)->len ) || \
\r
120 memcmp( (oid_str), (oid_buf)->p, (oid_buf)->len) != 0 )
\r
127 * \name Functions to parse ASN.1 data structures
\r
132 * Type-length-value structure that allows for ASN1 using DER.
\r
134 typedef struct mbedtls_asn1_buf
\r
136 int tag; /**< ASN1 type, e.g. MBEDTLS_ASN1_UTF8_STRING. */
\r
137 size_t len; /**< ASN1 length, in octets. */
\r
138 unsigned char *p; /**< ASN1 data, e.g. in ASCII. */
\r
143 * Container for ASN1 bit strings.
\r
145 typedef struct mbedtls_asn1_bitstring
\r
147 size_t len; /**< ASN1 length, in octets. */
\r
148 unsigned char unused_bits; /**< Number of unused bits at the end of the string */
\r
149 unsigned char *p; /**< Raw ASN1 data for the bit string */
\r
151 mbedtls_asn1_bitstring;
\r
154 * Container for a sequence of ASN.1 items
\r
156 typedef struct mbedtls_asn1_sequence
\r
158 mbedtls_asn1_buf buf; /**< Buffer containing the given ASN.1 item. */
\r
159 struct mbedtls_asn1_sequence *next; /**< The next entry in the sequence. */
\r
161 mbedtls_asn1_sequence;
\r
164 * Container for a sequence or list of 'named' ASN.1 data items
\r
166 typedef struct mbedtls_asn1_named_data
\r
168 mbedtls_asn1_buf oid; /**< The object identifier. */
\r
169 mbedtls_asn1_buf val; /**< The named value. */
\r
170 struct mbedtls_asn1_named_data *next; /**< The next entry in the sequence. */
\r
171 unsigned char next_merged; /**< Merge next item into the current one? */
\r
173 mbedtls_asn1_named_data;
\r
176 * \brief Get the length of an ASN.1 element.
\r
177 * Updates the pointer to immediately behind the length.
\r
179 * \param p The position in the ASN.1 data
\r
180 * \param end End of data
\r
181 * \param len The variable that will receive the value
\r
183 * \return 0 if successful, MBEDTLS_ERR_ASN1_OUT_OF_DATA on reaching
\r
184 * end of data, MBEDTLS_ERR_ASN1_INVALID_LENGTH if length is
\r
187 int mbedtls_asn1_get_len( unsigned char **p,
\r
188 const unsigned char *end,
\r
192 * \brief Get the tag and length of the tag. Check for the requested tag.
\r
193 * Updates the pointer to immediately behind the tag and length.
\r
195 * \param p The position in the ASN.1 data
\r
196 * \param end End of data
\r
197 * \param len The variable that will receive the length
\r
198 * \param tag The expected tag
\r
200 * \return 0 if successful, MBEDTLS_ERR_ASN1_UNEXPECTED_TAG if tag did
\r
201 * not match requested tag, or another specific ASN.1 error code.
\r
203 int mbedtls_asn1_get_tag( unsigned char **p,
\r
204 const unsigned char *end,
\r
205 size_t *len, int tag );
\r
208 * \brief Retrieve a boolean ASN.1 tag and its value.
\r
209 * Updates the pointer to immediately behind the full tag.
\r
211 * \param p The position in the ASN.1 data
\r
212 * \param end End of data
\r
213 * \param val The variable that will receive the value
\r
215 * \return 0 if successful or a specific ASN.1 error code.
\r
217 int mbedtls_asn1_get_bool( unsigned char **p,
\r
218 const unsigned char *end,
\r
222 * \brief Retrieve an integer ASN.1 tag and its value.
\r
223 * Updates the pointer to immediately behind the full tag.
\r
225 * \param p The position in the ASN.1 data
\r
226 * \param end End of data
\r
227 * \param val The variable that will receive the value
\r
229 * \return 0 if successful or a specific ASN.1 error code.
\r
231 int mbedtls_asn1_get_int( unsigned char **p,
\r
232 const unsigned char *end,
\r
236 * \brief Retrieve a bitstring ASN.1 tag and its value.
\r
237 * Updates the pointer to immediately behind the full tag.
\r
239 * \param p The position in the ASN.1 data
\r
240 * \param end End of data
\r
241 * \param bs The variable that will receive the value
\r
243 * \return 0 if successful or a specific ASN.1 error code.
\r
245 int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end,
\r
246 mbedtls_asn1_bitstring *bs);
\r
249 * \brief Retrieve a bitstring ASN.1 tag without unused bits and its
\r
251 * Updates the pointer to the beginning of the bit/octet string.
\r
253 * \param p The position in the ASN.1 data
\r
254 * \param end End of data
\r
255 * \param len Length of the actual bit/octect string in bytes
\r
257 * \return 0 if successful or a specific ASN.1 error code.
\r
259 int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end,
\r
263 * \brief Parses and splits an ASN.1 "SEQUENCE OF <tag>"
\r
264 * Updated the pointer to immediately behind the full sequence tag.
\r
266 * \param p The position in the ASN.1 data
\r
267 * \param end End of data
\r
268 * \param cur First variable in the chain to fill
\r
269 * \param tag Type of sequence
\r
271 * \return 0 if successful or a specific ASN.1 error code.
\r
273 int mbedtls_asn1_get_sequence_of( unsigned char **p,
\r
274 const unsigned char *end,
\r
275 mbedtls_asn1_sequence *cur,
\r
278 #if defined(MBEDTLS_BIGNUM_C)
\r
280 * \brief Retrieve a MPI value from an integer ASN.1 tag.
\r
281 * Updates the pointer to immediately behind the full tag.
\r
283 * \param p The position in the ASN.1 data
\r
284 * \param end End of data
\r
285 * \param X The MPI that will receive the value
\r
287 * \return 0 if successful or a specific ASN.1 or MPI error code.
\r
289 int mbedtls_asn1_get_mpi( unsigned char **p,
\r
290 const unsigned char *end,
\r
292 #endif /* MBEDTLS_BIGNUM_C */
\r
295 * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence.
\r
296 * Updates the pointer to immediately behind the full
\r
297 * AlgorithmIdentifier.
\r
299 * \param p The position in the ASN.1 data
\r
300 * \param end End of data
\r
301 * \param alg The buffer to receive the OID
\r
302 * \param params The buffer to receive the params (if any)
\r
304 * \return 0 if successful or a specific ASN.1 or MPI error code.
\r
306 int mbedtls_asn1_get_alg( unsigned char **p,
\r
307 const unsigned char *end,
\r
308 mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params );
\r
311 * \brief Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no
\r
313 * Updates the pointer to immediately behind the full
\r
314 * AlgorithmIdentifier.
\r
316 * \param p The position in the ASN.1 data
\r
317 * \param end End of data
\r
318 * \param alg The buffer to receive the OID
\r
320 * \return 0 if successful or a specific ASN.1 or MPI error code.
\r
322 int mbedtls_asn1_get_alg_null( unsigned char **p,
\r
323 const unsigned char *end,
\r
324 mbedtls_asn1_buf *alg );
\r
327 * \brief Find a specific named_data entry in a sequence or list based on
\r
330 * \param list The list to seek through
\r
331 * \param oid The OID to look for
\r
332 * \param len Size of the OID
\r
334 * \return NULL if not found, or a pointer to the existing entry.
\r
336 mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list,
\r
337 const char *oid, size_t len );
\r
340 * \brief Free a mbedtls_asn1_named_data entry
\r
342 * \param entry The named data entry to free
\r
344 void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *entry );
\r
347 * \brief Free all entries in a mbedtls_asn1_named_data list
\r
348 * Head will be set to NULL
\r
350 * \param head Pointer to the head of the list of named data entries to free
\r
352 void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head );
\r
358 #endif /* asn1.h */
\r