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