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 #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 36 extern "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 */ 53 int 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 */ 67 int 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 */ 85 int 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 */ 103 int 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 */ 119 int 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 */ 135 int 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 */ 153 int 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 */ 174 int 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 */ 192 int 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 */ 209 int 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 */ 224 int 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 */ 243 int 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 */ 262 int 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 */ 281 int 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 */ 299 int 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 */ 316 int 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 */ 336 int 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 */ 355 int 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 */ 379 mbedtls_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 */ 391