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