• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * \file asn1write.h
3  *
4  * \brief ASN.1 buffer writing functionality
5  */
6 /*
7  *  Copyright The Mbed TLS Contributors
8  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
9  */
10 #ifndef MBEDTLS_ASN1_WRITE_H
11 #define MBEDTLS_ASN1_WRITE_H
12 
13 #if !defined(MBEDTLS_CONFIG_FILE)
14 #include "mbedtls/config.h"
15 #else
16 #include MBEDTLS_CONFIG_FILE
17 #endif
18 
19 #include "mbedtls/asn1.h"
20 
21 #define MBEDTLS_ASN1_CHK_ADD(g, f)                      \
22     do                                                  \
23     {                                                   \
24         if ((ret = (f)) < 0)                         \
25         return ret;                              \
26         else                                            \
27         (g) += ret;                                 \
28     } while (0)
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /**
35  * \brief           Write a length field in ASN.1 format.
36  *
37  * \note            This function works backwards in data buffer.
38  *
39  * \param p         The reference to the current position pointer.
40  * \param start     The start of the buffer, for bounds-checking.
41  * \param len       The length value to write.
42  *
43  * \return          The number of bytes written to \p p on success.
44  * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
45  */
46 int mbedtls_asn1_write_len(unsigned char **p, unsigned char *start,
47                            size_t len);
48 /**
49  * \brief           Write an ASN.1 tag in ASN.1 format.
50  *
51  * \note            This function works backwards in data buffer.
52  *
53  * \param p         The reference to the current position pointer.
54  * \param start     The start of the buffer, for bounds-checking.
55  * \param tag       The tag to write.
56  *
57  * \return          The number of bytes written to \p p on success.
58  * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
59  */
60 int mbedtls_asn1_write_tag(unsigned char **p, unsigned char *start,
61                            unsigned char tag);
62 
63 /**
64  * \brief           Write raw buffer data.
65  *
66  * \note            This function works backwards in data buffer.
67  *
68  * \param p         The reference to the current position pointer.
69  * \param start     The start of the buffer, for bounds-checking.
70  * \param buf       The data buffer to write.
71  * \param size      The length of the data buffer.
72  *
73  * \return          The number of bytes written to \p p on success.
74  * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
75  */
76 int mbedtls_asn1_write_raw_buffer(unsigned char **p, unsigned char *start,
77                                   const unsigned char *buf, size_t size);
78 
79 #if defined(MBEDTLS_BIGNUM_C)
80 /**
81  * \brief           Write an arbitrary-precision number (#MBEDTLS_ASN1_INTEGER)
82  *                  in ASN.1 format.
83  *
84  * \note            This function works backwards in data buffer.
85  *
86  * \param p         The reference to the current position pointer.
87  * \param start     The start of the buffer, for bounds-checking.
88  * \param X         The MPI to write.
89  *                  It must be non-negative.
90  *
91  * \return          The number of bytes written to \p p on success.
92  * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
93  */
94 int mbedtls_asn1_write_mpi(unsigned char **p, unsigned char *start,
95                            const mbedtls_mpi *X);
96 #endif /* MBEDTLS_BIGNUM_C */
97 
98 /**
99  * \brief           Write a NULL tag (#MBEDTLS_ASN1_NULL) with zero data
100  *                  in ASN.1 format.
101  *
102  * \note            This function works backwards in data buffer.
103  *
104  * \param p         The reference to the current position pointer.
105  * \param start     The start of the buffer, for bounds-checking.
106  *
107  * \return          The number of bytes written to \p p on success.
108  * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
109  */
110 int mbedtls_asn1_write_null(unsigned char **p, unsigned char *start);
111 
112 /**
113  * \brief           Write an OID tag (#MBEDTLS_ASN1_OID) and data
114  *                  in ASN.1 format.
115  *
116  * \note            This function works backwards in data buffer.
117  *
118  * \param p         The reference to the current position pointer.
119  * \param start     The start of the buffer, for bounds-checking.
120  * \param oid       The OID to write.
121  * \param oid_len   The length of the OID.
122  *
123  * \return          The number of bytes written to \p p on success.
124  * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
125  */
126 int mbedtls_asn1_write_oid(unsigned char **p, unsigned char *start,
127                            const char *oid, size_t oid_len);
128 
129 /**
130  * \brief           Write an AlgorithmIdentifier sequence in ASN.1 format.
131  *
132  * \note            This function works backwards in data buffer.
133  *
134  * \param p         The reference to the current position pointer.
135  * \param start     The start of the buffer, for bounds-checking.
136  * \param oid       The OID of the algorithm to write.
137  * \param oid_len   The length of the algorithm's OID.
138  * \param par_len   The length of the parameters, which must be already written.
139  *                  If 0, NULL parameters are added
140  *
141  * \return          The number of bytes written to \p p on success.
142  * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
143  */
144 int mbedtls_asn1_write_algorithm_identifier(unsigned char **p,
145                                             unsigned char *start,
146                                             const char *oid, size_t oid_len,
147                                             size_t par_len);
148 
149 /**
150  * \brief           Write an AlgorithmIdentifier sequence in ASN.1 format.
151  *
152  * \note            This function works backwards in data buffer.
153  *
154  * \param p         The reference to the current position pointer.
155  * \param start     The start of the buffer, for bounds-checking.
156  * \param oid       The OID of the algorithm to write.
157  * \param oid_len   The length of the algorithm's OID.
158  * \param par_len   The length of the parameters, which must be already written.
159  * \param has_par   If there are any parameters. If 0, par_len must be 0. If 1
160  *                  and \p par_len is 0, NULL parameters are added.
161  *
162  * \return          The number of bytes written to \p p on success.
163  * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
164  */
165 int mbedtls_asn1_write_algorithm_identifier_ext(unsigned char **p,
166                                                 unsigned char *start,
167                                                 const char *oid, size_t oid_len,
168                                                 size_t par_len, int has_par);
169 
170 /**
171  * \brief           Write a boolean tag (#MBEDTLS_ASN1_BOOLEAN) and value
172  *                  in ASN.1 format.
173  *
174  * \note            This function works backwards in data buffer.
175  *
176  * \param p         The reference to the current position pointer.
177  * \param start     The start of the buffer, for bounds-checking.
178  * \param boolean   The boolean value to write, either \c 0 or \c 1.
179  *
180  * \return          The number of bytes written to \p p on success.
181  * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
182  */
183 int mbedtls_asn1_write_bool(unsigned char **p, unsigned char *start,
184                             int boolean);
185 
186 /**
187  * \brief           Write an int tag (#MBEDTLS_ASN1_INTEGER) and value
188  *                  in ASN.1 format.
189  *
190  * \note            This function works backwards in data buffer.
191  *
192  * \param p         The reference to the current position pointer.
193  * \param start     The start of the buffer, for bounds-checking.
194  * \param val       The integer value to write.
195  *                  It must be non-negative.
196  *
197  * \return          The number of bytes written to \p p on success.
198  * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
199  */
200 int mbedtls_asn1_write_int(unsigned char **p, unsigned char *start, int val);
201 
202 /**
203  * \brief           Write an enum tag (#MBEDTLS_ASN1_ENUMERATED) and value
204  *                  in ASN.1 format.
205  *
206  * \note            This function works backwards in data buffer.
207  *
208  * \param p         The reference to the current position pointer.
209  * \param start     The start of the buffer, for bounds-checking.
210  * \param val       The integer value to write.
211  *
212  * \return          The number of bytes written to \p p on success.
213  * \return          A negative \c MBEDTLS_ERR_ASN1_XXX error code on failure.
214  */
215 int mbedtls_asn1_write_enum(unsigned char **p, unsigned char *start, int val);
216 
217 /**
218  * \brief           Write a string in ASN.1 format using a specific
219  *                  string encoding tag.
220 
221  * \note            This function works backwards in data buffer.
222  *
223  * \param p         The reference to the current position pointer.
224  * \param start     The start of the buffer, for bounds-checking.
225  * \param tag       The string encoding tag to write, e.g.
226  *                  #MBEDTLS_ASN1_UTF8_STRING.
227  * \param text      The string to write.
228  * \param text_len  The length of \p text in bytes (which might
229  *                  be strictly larger than the number of characters).
230  *
231  * \return          The number of bytes written to \p p on success.
232  * \return          A negative error code on failure.
233  */
234 int mbedtls_asn1_write_tagged_string(unsigned char **p, unsigned char *start,
235                                      int tag, const char *text,
236                                      size_t text_len);
237 
238 /**
239  * \brief           Write a string in ASN.1 format using the PrintableString
240  *                  string encoding tag (#MBEDTLS_ASN1_PRINTABLE_STRING).
241  *
242  * \note            This function works backwards in data buffer.
243  *
244  * \param p         The reference to the current position pointer.
245  * \param start     The start of the buffer, for bounds-checking.
246  * \param text      The string to write.
247  * \param text_len  The length of \p text in bytes (which might
248  *                  be strictly larger than the number of characters).
249  *
250  * \return          The number of bytes written to \p p on success.
251  * \return          A negative error code on failure.
252  */
253 int mbedtls_asn1_write_printable_string(unsigned char **p,
254                                         unsigned char *start,
255                                         const char *text, size_t text_len);
256 
257 /**
258  * \brief           Write a UTF8 string in ASN.1 format using the UTF8String
259  *                  string encoding tag (#MBEDTLS_ASN1_UTF8_STRING).
260  *
261  * \note            This function works backwards in data buffer.
262  *
263  * \param p         The reference to the current position pointer.
264  * \param start     The start of the buffer, for bounds-checking.
265  * \param text      The string to write.
266  * \param text_len  The length of \p text in bytes (which might
267  *                  be strictly larger than the number of characters).
268  *
269  * \return          The number of bytes written to \p p on success.
270  * \return          A negative error code on failure.
271  */
272 int mbedtls_asn1_write_utf8_string(unsigned char **p, unsigned char *start,
273                                    const char *text, size_t text_len);
274 
275 /**
276  * \brief           Write a string in ASN.1 format using the IA5String
277  *                  string encoding tag (#MBEDTLS_ASN1_IA5_STRING).
278  *
279  * \note            This function works backwards in data buffer.
280  *
281  * \param p         The reference to the current position pointer.
282  * \param start     The start of the buffer, for bounds-checking.
283  * \param text      The string to write.
284  * \param text_len  The length of \p text in bytes (which might
285  *                  be strictly larger than the number of characters).
286  *
287  * \return          The number of bytes written to \p p on success.
288  * \return          A negative error code on failure.
289  */
290 int mbedtls_asn1_write_ia5_string(unsigned char **p, unsigned char *start,
291                                   const char *text, size_t text_len);
292 
293 /**
294  * \brief           Write a bitstring tag (#MBEDTLS_ASN1_BIT_STRING) and
295  *                  value in ASN.1 format.
296  *
297  * \note            This function works backwards in data buffer.
298  *
299  * \param p         The reference to the current position pointer.
300  * \param start     The start of the buffer, for bounds-checking.
301  * \param buf       The bitstring to write.
302  * \param bits      The total number of bits in the bitstring.
303  *
304  * \return          The number of bytes written to \p p on success.
305  * \return          A negative error code on failure.
306  */
307 int mbedtls_asn1_write_bitstring(unsigned char **p, unsigned char *start,
308                                  const unsigned char *buf, size_t bits);
309 
310 /**
311  * \brief           This function writes a named bitstring tag
312  *                  (#MBEDTLS_ASN1_BIT_STRING) and value in ASN.1 format.
313  *
314  *                  As stated in RFC 5280 Appendix B, trailing zeroes are
315  *                  omitted when encoding named bitstrings in DER.
316  *
317  * \note            This function works backwards within the data buffer.
318  *
319  * \param p         The reference to the current position pointer.
320  * \param start     The start of the buffer which is used for bounds-checking.
321  * \param buf       The bitstring to write.
322  * \param bits      The total number of bits in the bitstring.
323  *
324  * \return          The number of bytes written to \p p on success.
325  * \return          A negative error code on failure.
326  */
327 int mbedtls_asn1_write_named_bitstring(unsigned char **p,
328                                        unsigned char *start,
329                                        const unsigned char *buf,
330                                        size_t bits);
331 
332 /**
333  * \brief           Write an octet string tag (#MBEDTLS_ASN1_OCTET_STRING)
334  *                  and value in ASN.1 format.
335  *
336  * \note            This function works backwards in data buffer.
337  *
338  * \param p         The reference to the current position pointer.
339  * \param start     The start of the buffer, for bounds-checking.
340  * \param buf       The buffer holding the data to write.
341  * \param size      The length of the data buffer \p buf.
342  *
343  * \return          The number of bytes written to \p p on success.
344  * \return          A negative error code on failure.
345  */
346 int mbedtls_asn1_write_octet_string(unsigned char **p, unsigned char *start,
347                                     const unsigned char *buf, size_t size);
348 
349 /**
350  * \brief           Create or find a specific named_data entry for writing in a
351  *                  sequence or list based on the OID. If not already in there,
352  *                  a new entry is added to the head of the list.
353  *                  Warning: Destructive behaviour for the val data!
354  *
355  * \param list      The pointer to the location of the head of the list to seek
356  *                  through (will be updated in case of a new entry).
357  * \param oid       The OID to look for.
358  * \param oid_len   The size of the OID.
359  * \param val       The associated data to store. If this is \c NULL,
360  *                  no data is copied to the new or existing buffer.
361  * \param val_len   The minimum length of the data buffer needed.
362  *                  If this is 0, do not allocate a buffer for the associated
363  *                  data.
364  *                  If the OID was already present, enlarge, shrink or free
365  *                  the existing buffer to fit \p val_len.
366  *
367  * \return          A pointer to the new / existing entry on success.
368  * \return          \c NULL if if there was a memory allocation error.
369  */
370 mbedtls_asn1_named_data *mbedtls_asn1_store_named_data(mbedtls_asn1_named_data **list,
371                                                        const char *oid, size_t oid_len,
372                                                        const unsigned char *val,
373                                                        size_t val_len);
374 
375 #ifdef __cplusplus
376 }
377 #endif
378 
379 #endif /* MBEDTLS_ASN1_WRITE_H */
380