Path: blob/main/crypto/openssl/include/internal/json_enc.h
34879 views
/*1* Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#ifndef OSSL_JSON_ENC_H10# define OSSL_JSON_ENC_H1112# include <openssl/bio.h>1314/*15* JSON Encoder16* ============17*18* This JSON encoder is used for qlog. It supports ordinary JSON (RFC 7159),19* JSON-SEQ (RFC 7464) and I-JSON (RFC 7493). It supports only basic ASCII.20*/2122struct json_write_buf {23BIO *bio;24char *buf;25size_t alloc, cur;26};2728typedef struct ossl_json_enc_st {29uint32_t flags;30/* error: 1 if an error has occurred. */31/* state: current state. */32/* stack stores a bitmap. 0=object, 1=array. */33/* stack cur size: stack_end_byte bytes, stack_end_bit bits. */34/* stack alloc size: stack_bytes bytes. */35unsigned char error, stack_end_bit, state, *stack, defer_indent;36unsigned char stack_small[16];37struct json_write_buf wbuf;38size_t stack_end_byte, stack_bytes;39} OSSL_JSON_ENC;4041/*42* ossl_json_init43* --------------44*45* Initialises a JSON encoder.46*47* If the flag OSSL_JSON_FLAG_SEQ is passed, the output is in JSON-SEQ. The48* caller should use the encoder as though it is encoding members of a JSON49* array (but without calling ossl_json_array_begin() or ossl_json_array_end()).50* Each top-level JSON item (e.g. JSON object) encoded will be separated51* correctly as per the JSON-SEQ format.52*53* If the flag OSSL_JSON_FLAG_SEQ is not passed, the output is in JSON format.54* Generally the caller should encode only a single output item (e.g. a JSON55* object).56*57* By default, JSON output is maximally compact. If OSSL_JSON_FLAG_PRETTY is58* set, JSON/JSON-SEQ output is spaced for optimal human readability.59*60* If OSSL_JSON_FLAG_IJSON is set, integers outside the range `[-2**53 + 1,61* 2**53 - 1]` are automatically converted to decimal strings before62* serialization.63*/64#define OSSL_JSON_FLAG_NONE 065#define OSSL_JSON_FLAG_SEQ (1U << 0)66#define OSSL_JSON_FLAG_PRETTY (1U << 1)67#define OSSL_JSON_FLAG_IJSON (1U << 2)6869int ossl_json_init(OSSL_JSON_ENC *json, BIO *bio, uint32_t flags);7071/*72* ossl_json_cleanup73* -----------------74*75* Destroys a JSON encoder.76*/77void ossl_json_cleanup(OSSL_JSON_ENC *json);7879/*80* ossl_json_reset81* ---------------82*83* Resets a JSON encoder, as though it has just been initialised, allowing it84* to be used again for new output syntactically unrelated to any previous85* output. This is similar to calling ossl_json_cleanup followed by86* ossl_json_init but may allow internal buffers to be reused.87*88* If the JSON encoder has entered an error state, this function MAY allow89* recovery from this error state, in which case it will return 1. If this90* function returns 0, the JSON encoder is unrecoverable and91* ossl_json_cleanup() must be called.92*93* Automatically calls ossl_json_flush().94*/95int ossl_json_reset(OSSL_JSON_ENC *json);9697/*98* ossl_json_flush99* ---------------100*101* Flushes the JSON encoder, ensuring that any residual bytes in internal102* buffers are written to the provided sink BIO. Flushing may also happen103* autonomously as buffers are filled, but the caller must use this function104* to guarantee all data has been flushed.105*/106int ossl_json_flush(OSSL_JSON_ENC *json);107108/*109* ossl_json_flush_cleanup110* -----------------------111*112* Tries to flush as in a call to ossl_json_flush, and then calls113* ossl_json_cleanup regardless of the result. The result of the flush call is114* returned.115*/116int ossl_json_flush_cleanup(OSSL_JSON_ENC *json);117118/*119* ossl_json_set0_sink120* -------------------121*122* Changes the sink used by the JSON encoder.123*/124int ossl_json_set0_sink(OSSL_JSON_ENC *json, BIO *bio);125126/*127* ossl_json_in_error128* ------------------129*130* To enhance the ergonomics of the JSON API, the JSON object uses an implicit131* error tracking model. When a JSON API call fails (for example due to caller132* error, such as trying to close an array which was not opened), the JSON133* object enters an error state and all further calls are silently ignored.134*135* The caller can detect this condition after it is finished making builder136* calls to the JSON object by calling this function. This function returns 1137* if an error occurred. At this point the caller's only recourse is to call138* ossl_json_reset() or ossl_json_cleanup().139*140* Note that partial (i.e., invalid) output may still have been sent to the BIO141* in this case. Since the amount of output which can potentially be produced142* by a JSON object is unbounded, it is impractical to buffer it all before143* flushing. It is expected that errors will ordinarily be either caller errors144* (programming errors) or BIO errors.145*/146int ossl_json_in_error(OSSL_JSON_ENC *json);147148/*149* JSON Builder Calls150* ==================151*152* These functions are used to build JSON output. The functions which have153* begin and end function pairs must be called in correctly nested sequence.154* When writing an object, ossl_json_key() must be called exactly once before155* each call to write a JSON item.156*157* The JSON library takes responsibility for enforcing correct usage patterns.158* If a call is made that does not correspond to the JSON syntax, the JSON159* object enters the error state and all subsequent calls are ignored.160*161* In JSON-SEQ mode, the caller should act as though the library implicitly162* places all calls between an ossl_json_array_begin() and163* ossl_json_array_end() pair; for example, the normal usage pattern would be164* to call ossl_json_object_begin() followed by ossl_json_object_end(), in165* repeated sequence.166*167* The library does not enforce non-generation of duplicate keys. Avoiding this168* is the caller's responsibility. It is also the caller's responsibility to169* pass valid UTF-8 strings. All other forms of invalid output will cause an170* error. Note that due to the immediate nature of the API, partial output may171* have already been generated in such a case.172*/173174/* Begin a new JSON object. */175void ossl_json_object_begin(OSSL_JSON_ENC *json);176177/* End a JSON object. Must be matched with a call to ossl_json_object_begin(). */178void ossl_json_object_end(OSSL_JSON_ENC *json);179180/* Begin a new JSON array. */181void ossl_json_array_begin(OSSL_JSON_ENC *json);182183/* End a JSON array. Must be matched with a call to ossl_json_array_end(). */184void ossl_json_array_end(OSSL_JSON_ENC *json);185186/*187* Encode a JSON key within an object. Pass a zero-terminated string, which can188* be freed immediately following the call to this function.189*/190void ossl_json_key(OSSL_JSON_ENC *json, const char *key);191192/* Encode a JSON 'null' value. */193void ossl_json_null(OSSL_JSON_ENC *json);194195/* Encode a JSON boolean value. */196void ossl_json_bool(OSSL_JSON_ENC *json, int value);197198/* Encode a JSON integer from a uint64_t. */199void ossl_json_u64(OSSL_JSON_ENC *json, uint64_t value);200201/* Encode a JSON integer from an int64_t. */202void ossl_json_i64(OSSL_JSON_ENC *json, int64_t value);203204/*205* Encode a JSON UTF-8 string from a zero-terminated string. The string passed206* can be freed immediately following the call to this function.207*/208void ossl_json_str(OSSL_JSON_ENC *json, const char *str);209210/*211* Encode a JSON UTF-8 string from a string with the given length. The string212* passed can be freed immediately following the call to this function.213*/214void ossl_json_str_len(OSSL_JSON_ENC *json, const char *str, size_t str_len);215216/*217* Encode binary data as a lowercase hex string. data_len is the data length in218* bytes.219*/220void ossl_json_str_hex(OSSL_JSON_ENC *json, const void *data, size_t data_len);221222#endif223224225