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