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