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