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