json_enc.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #ifndef OSSL_JSON_ENC_H
  10. # define OSSL_JSON_ENC_H
  11. # include <openssl/bio.h>
  12. /*
  13. * JSON Encoder
  14. * ============
  15. *
  16. * This JSON encoder is used for qlog. It supports ordinary JSON (RFC 7159),
  17. * JSON-SEQ (RFC 7464) and I-JSON (RFC 7493). It supports only basic ASCII.
  18. */
  19. struct json_write_buf {
  20. BIO *bio;
  21. char *buf;
  22. size_t alloc, cur;
  23. };
  24. typedef struct ossl_json_enc_st {
  25. uint32_t flags;
  26. /* error: 1 if an error has occurred. */
  27. /* state: current state. */
  28. /* stack stores a bitmap. 0=object, 1=array. */
  29. /* stack cur size: stack_end_byte bytes, stack_end_bit bits. */
  30. /* stack alloc size: stack_bytes bytes. */
  31. unsigned char error, stack_end_bit, state, *stack, defer_indent;
  32. unsigned char stack_small[16];
  33. struct json_write_buf wbuf;
  34. size_t stack_end_byte, stack_bytes;
  35. } OSSL_JSON_ENC;
  36. /*
  37. * ossl_json_init
  38. * --------------
  39. *
  40. * Initialises a JSON encoder.
  41. *
  42. * If the flag OSSL_JSON_FLAG_SEQ is passed, the output is in JSON-SEQ. The
  43. * caller should use the encoder as though it is encoding members of a JSON
  44. * array (but without calling ossl_json_array_begin() or ossl_json_array_end()).
  45. * Each top-level JSON item (e.g. JSON object) encoded will be separated
  46. * correctly as per the JSON-SEQ format.
  47. *
  48. * If the flag OSSL_JSON_FLAG_SEQ is not passed, the output is in JSON format.
  49. * Generally the caller should encode only a single output item (e.g. a JSON
  50. * object).
  51. *
  52. * By default, JSON output is maximally compact. If OSSL_JSON_FLAG_PRETTY is
  53. * set, JSON/JSON-SEQ output is spaced for optimal human readability.
  54. *
  55. * If OSSL_JSON_FLAG_IJSON is set, integers outside the range `[-2**53 + 1,
  56. * 2**53 - 1]` are automatically converted to decimal strings before
  57. * serialization.
  58. */
  59. #define OSSL_JSON_FLAG_NONE 0
  60. #define OSSL_JSON_FLAG_SEQ (1U << 0)
  61. #define OSSL_JSON_FLAG_PRETTY (1U << 1)
  62. #define OSSL_JSON_FLAG_IJSON (1U << 2)
  63. int ossl_json_init(OSSL_JSON_ENC *json, BIO *bio, uint32_t flags);
  64. /*
  65. * ossl_json_cleanup
  66. * -----------------
  67. *
  68. * Destroys a JSON encoder.
  69. */
  70. void ossl_json_cleanup(OSSL_JSON_ENC *json);
  71. /*
  72. * ossl_json_reset
  73. * ---------------
  74. *
  75. * Resets a JSON encoder, as though it has just been initialised, allowing it
  76. * to be used again for new output syntactically unrelated to any previous
  77. * output. This is similar to calling ossl_json_cleanup followed by
  78. * ossl_json_init but may allow internal buffers to be reused.
  79. *
  80. * If the JSON encoder has entered an error state, this function MAY allow
  81. * recovery from this error state, in which case it will return 1. If this
  82. * function returns 0, the JSON encoder is unrecoverable and
  83. * ossl_json_cleanup() must be called.
  84. *
  85. * Automatically calls ossl_json_flush().
  86. */
  87. int ossl_json_reset(OSSL_JSON_ENC *json);
  88. /*
  89. * ossl_json_flush
  90. * ---------------
  91. *
  92. * Flushes the JSON encoder, ensuring that any residual bytes in internal
  93. * buffers are written to the provided sink BIO. Flushing may also happen
  94. * autonomously as buffers are filled, but the caller must use this function
  95. * to guarantee all data has been flushed.
  96. */
  97. int ossl_json_flush(OSSL_JSON_ENC *json);
  98. /*
  99. * ossl_json_flush_cleanup
  100. * -----------------------
  101. *
  102. * Tries to flush as in a call to ossl_json_flush, and then calls
  103. * ossl_json_cleanup regardless of the result. The result of the flush call is
  104. * returned.
  105. */
  106. int ossl_json_flush_cleanup(OSSL_JSON_ENC *json);
  107. /*
  108. * ossl_json_set0_sink
  109. * -------------------
  110. *
  111. * Changes the sink used by the JSON encoder.
  112. */
  113. int ossl_json_set0_sink(OSSL_JSON_ENC *json, BIO *bio);
  114. /*
  115. * ossl_json_in_error
  116. * ------------------
  117. *
  118. * To enhance the ergonomics of the JSON API, the JSON object uses an implicit
  119. * error tracking model. When a JSON API call fails (for example due to caller
  120. * error, such as trying to close an array which was not opened), the JSON
  121. * object enters an error state and all further calls are silently ignored.
  122. *
  123. * The caller can detect this condition after it is finished making builder
  124. * calls to the JSON object by calling this function. This function returns 1
  125. * if an error occurred. At this point the caller's only recourse is to call
  126. * ossl_json_reset() or ossl_json_cleanup().
  127. *
  128. * Note that partial (i.e., invalid) output may still have been sent to the BIO
  129. * in this case. Since the amount of output which can potentially be produced
  130. * by a JSON object is unbounded, it is impractical to buffer it all before
  131. * flushing. It is expected that errors will ordinarily be either caller errors
  132. * (programming errors) or BIO errors.
  133. */
  134. int ossl_json_in_error(OSSL_JSON_ENC *json);
  135. /*
  136. * JSON Builder Calls
  137. * ==================
  138. *
  139. * These functions are used to build JSON output. The functions which have
  140. * begin and end function pairs must be called in correctly nested sequence.
  141. * When writing an object, ossl_json_key() must be called exactly once before
  142. * each call to write a JSON item.
  143. *
  144. * The JSON library takes responsibility for enforcing correct usage patterns.
  145. * If a call is made that does not correspond to the JSON syntax, the JSON
  146. * object enters the error state and all subsequent calls are ignored.
  147. *
  148. * In JSON-SEQ mode, the caller should act as though the library implicitly
  149. * places all calls between an ossl_json_array_begin() and
  150. * ossl_json_array_end() pair; for example, the normal usage pattern would be
  151. * to call ossl_json_object_begin() followed by ossl_json_object_end(), in
  152. * repeated sequence.
  153. *
  154. * The library does not enforce non-generation of duplicate keys. Avoiding this
  155. * is the caller's responsibility. It is also the caller's responsibility to
  156. * pass valid UTF-8 strings. All other forms of invalid output will cause an
  157. * error. Note that due to the immediate nature of the API, partial output may
  158. * have already been generated in such a case.
  159. */
  160. /* Begin a new JSON object. */
  161. void ossl_json_object_begin(OSSL_JSON_ENC *json);
  162. /* End a JSON object. Must be matched with a call to ossl_json_object_begin(). */
  163. void ossl_json_object_end(OSSL_JSON_ENC *json);
  164. /* Begin a new JSON array. */
  165. void ossl_json_array_begin(OSSL_JSON_ENC *json);
  166. /* End a JSON array. Must be matched with a call to ossl_json_array_end(). */
  167. void ossl_json_array_end(OSSL_JSON_ENC *json);
  168. /*
  169. * Encode a JSON key within an object. Pass a zero-terminated string, which can
  170. * be freed immediately following the call to this function.
  171. */
  172. void ossl_json_key(OSSL_JSON_ENC *json, const char *key);
  173. /* Encode a JSON 'null' value. */
  174. void ossl_json_null(OSSL_JSON_ENC *json);
  175. /* Encode a JSON boolean value. */
  176. void ossl_json_bool(OSSL_JSON_ENC *json, int value);
  177. /* Encode a JSON integer from a uint64_t. */
  178. void ossl_json_u64(OSSL_JSON_ENC *json, uint64_t value);
  179. /* Encode a JSON integer from an int64_t. */
  180. void ossl_json_i64(OSSL_JSON_ENC *json, int64_t value);
  181. /* Encode a JSON number from a 64-bit floating point value. */
  182. void ossl_json_f64(OSSL_JSON_ENC *json, double value);
  183. /*
  184. * Encode a JSON UTF-8 string from a zero-terminated string. The string passed
  185. * can be freed immediately following the call to this function.
  186. */
  187. void ossl_json_str(OSSL_JSON_ENC *json, const char *str);
  188. /*
  189. * Encode a JSON UTF-8 string from a string with the given length. The string
  190. * passed can be freed immediately following the call to this function.
  191. */
  192. void ossl_json_str_len(OSSL_JSON_ENC *json, const char *str, size_t str_len);
  193. /*
  194. * Encode binary data as a lowercase hex string. data_len is the data length in
  195. * bytes.
  196. */
  197. void ossl_json_str_hex(OSSL_JSON_ENC *json, const void *data, size_t data_len);
  198. #endif