json_enc.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  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. #include "internal/json_enc.h"
  10. #include "internal/nelem.h"
  11. #include "internal/numbers.h"
  12. #include <string.h>
  13. /*
  14. * wbuf
  15. * ====
  16. */
  17. static int wbuf_flush(struct json_write_buf *wbuf, int full);
  18. static int wbuf_init(struct json_write_buf *wbuf, BIO *bio, size_t alloc)
  19. {
  20. wbuf->buf = OPENSSL_malloc(alloc);
  21. if (wbuf->buf == NULL)
  22. return 0;
  23. wbuf->cur = 0;
  24. wbuf->alloc = alloc;
  25. wbuf->bio = bio;
  26. return 1;
  27. }
  28. static void wbuf_cleanup(struct json_write_buf *wbuf)
  29. {
  30. OPENSSL_free(wbuf->buf);
  31. wbuf->buf = NULL;
  32. wbuf->alloc = 0;
  33. }
  34. static void wbuf_set0_bio(struct json_write_buf *wbuf, BIO *bio)
  35. {
  36. wbuf->bio = bio;
  37. }
  38. /* Empty write buffer. */
  39. static ossl_inline void wbuf_clean(struct json_write_buf *wbuf)
  40. {
  41. wbuf->cur = 0;
  42. }
  43. /* Available data remaining in buffer. */
  44. static ossl_inline size_t wbuf_avail(struct json_write_buf *wbuf)
  45. {
  46. return wbuf->alloc - wbuf->cur;
  47. }
  48. /* Add character to write buffer, returning 0 on flush failure. */
  49. static ossl_inline int wbuf_write_char(struct json_write_buf *wbuf, char c)
  50. {
  51. if (wbuf_avail(wbuf) == 0) {
  52. if (!wbuf_flush(wbuf, /*full=*/0))
  53. return 0;
  54. }
  55. wbuf->buf[wbuf->cur++] = c;
  56. return 1;
  57. }
  58. /*
  59. * Write zero-terminated string to write buffer, returning 0 on flush failure.
  60. */
  61. static int wbuf_write_str(struct json_write_buf *wbuf, const char *s)
  62. {
  63. char c;
  64. while ((c = *s++) != 0)
  65. if (!wbuf_write_char(wbuf, c))
  66. return 0;
  67. return 1;
  68. }
  69. /* Flush write buffer, returning 0 on I/O failure. */
  70. static int wbuf_flush(struct json_write_buf *wbuf, int full)
  71. {
  72. size_t written = 0, total_written = 0;
  73. while (total_written < wbuf->cur) {
  74. if (!BIO_write_ex(wbuf->bio,
  75. wbuf->buf + total_written,
  76. wbuf->cur - total_written,
  77. &written)) {
  78. memmove(wbuf->buf,
  79. wbuf->buf + total_written,
  80. wbuf->cur - total_written);
  81. wbuf->cur = 0;
  82. return 0;
  83. }
  84. total_written += written;
  85. }
  86. wbuf->cur = 0;
  87. if (full)
  88. (void)BIO_flush(wbuf->bio); /* best effort */
  89. return 1;
  90. }
  91. /*
  92. * OSSL_JSON_ENC: Stack Management
  93. * ===============================
  94. */
  95. static int json_ensure_stack_size(OSSL_JSON_ENC *json, size_t num_bytes)
  96. {
  97. unsigned char *stack;
  98. if (json->stack_bytes >= num_bytes)
  99. return 1;
  100. if (num_bytes <= OSSL_NELEM(json->stack_small)) {
  101. stack = json->stack_small;
  102. } else {
  103. if (json->stack == json->stack_small)
  104. json->stack = NULL;
  105. stack = OPENSSL_realloc(json->stack, num_bytes);
  106. if (stack == NULL)
  107. return 0;
  108. }
  109. json->stack = stack;
  110. json->stack_bytes = num_bytes;
  111. return 1;
  112. }
  113. /* Push one bit onto the stack. Returns 0 on allocation failure. */
  114. static int json_push(OSSL_JSON_ENC *json, unsigned int v)
  115. {
  116. if (v > 1)
  117. return 0;
  118. if (json->stack_end_byte >= json->stack_bytes) {
  119. size_t new_size
  120. = (json->stack_bytes == 0)
  121. ? OSSL_NELEM(json->stack_small)
  122. : (json->stack_bytes * 2);
  123. if (!json_ensure_stack_size(json, new_size))
  124. return 0;
  125. json->stack_bytes = new_size;
  126. }
  127. if (v > 0)
  128. json->stack[json->stack_end_byte] |= (v << json->stack_end_bit);
  129. else
  130. json->stack[json->stack_end_byte] &= ~(1U << json->stack_end_bit);
  131. json->stack_end_bit = (json->stack_end_bit + 1) % CHAR_BIT;
  132. if (json->stack_end_bit == 0)
  133. ++json->stack_end_byte;
  134. return 1;
  135. }
  136. /*
  137. * Pop a bit from the stack. Returns 0 if stack is empty. Use json_peek() to get
  138. * the value before calling this.
  139. */
  140. static int json_pop(OSSL_JSON_ENC *json)
  141. {
  142. if (json->stack_end_byte == 0 && json->stack_end_bit == 0)
  143. return 0;
  144. if (json->stack_end_bit == 0) {
  145. --json->stack_end_byte;
  146. json->stack_end_bit = CHAR_BIT - 1;
  147. } else {
  148. --json->stack_end_bit;
  149. }
  150. return 1;
  151. }
  152. /*
  153. * Returns the bit on the top of the stack, or -1 if the stack is empty.
  154. */
  155. static int json_peek(OSSL_JSON_ENC *json)
  156. {
  157. size_t obyte, obit;
  158. obyte = json->stack_end_byte;
  159. obit = json->stack_end_bit;
  160. if (obit == 0) {
  161. if (obyte == 0)
  162. return -1;
  163. --obyte;
  164. obit = CHAR_BIT - 1;
  165. } else {
  166. --obit;
  167. }
  168. return (json->stack[obyte] & (1U << obit)) != 0;
  169. }
  170. /*
  171. * OSSL_JSON_ENC: Initialisation
  172. * =============================
  173. */
  174. enum {
  175. STATE_PRE_KEY,
  176. STATE_PRE_ITEM,
  177. STATE_PRE_COMMA
  178. };
  179. static ossl_inline int in_ijson(const OSSL_JSON_ENC *json)
  180. {
  181. return (json->flags & OSSL_JSON_FLAG_IJSON) != 0;
  182. }
  183. static ossl_inline int in_seq(const OSSL_JSON_ENC *json)
  184. {
  185. return (json->flags & OSSL_JSON_FLAG_SEQ) != 0;
  186. }
  187. static ossl_inline int in_pretty(const OSSL_JSON_ENC *json)
  188. {
  189. return (json->flags & OSSL_JSON_FLAG_PRETTY) != 0;
  190. }
  191. int ossl_json_init(OSSL_JSON_ENC *json, BIO *bio, uint32_t flags)
  192. {
  193. memset(json, 0, sizeof(*json));
  194. json->flags = flags;
  195. json->error = 0;
  196. if (!wbuf_init(&json->wbuf, bio, 4096))
  197. return 0;
  198. json->state = STATE_PRE_COMMA;
  199. return 1;
  200. }
  201. void ossl_json_cleanup(OSSL_JSON_ENC *json)
  202. {
  203. wbuf_cleanup(&json->wbuf);
  204. if (json->stack != json->stack_small)
  205. OPENSSL_free(json->stack);
  206. json->stack = NULL;
  207. }
  208. int ossl_json_flush_cleanup(OSSL_JSON_ENC *json)
  209. {
  210. int ok = ossl_json_flush(json);
  211. ossl_json_cleanup(json);
  212. return ok;
  213. }
  214. int ossl_json_reset(OSSL_JSON_ENC *json)
  215. {
  216. wbuf_clean(&json->wbuf);
  217. json->stack_end_byte = 0;
  218. json->stack_end_bit = 0;
  219. json->error = 0;
  220. return 1;
  221. }
  222. int ossl_json_flush(OSSL_JSON_ENC *json)
  223. {
  224. return wbuf_flush(&json->wbuf, /*full=*/1);
  225. }
  226. int ossl_json_set0_sink(OSSL_JSON_ENC *json, BIO *bio)
  227. {
  228. wbuf_set0_bio(&json->wbuf, bio);
  229. return 1;
  230. }
  231. int ossl_json_in_error(OSSL_JSON_ENC *json)
  232. {
  233. return json->error;
  234. }
  235. /*
  236. * JSON Builder Calls
  237. * ==================
  238. */
  239. static void json_write_qstring(OSSL_JSON_ENC *json, const char *str);
  240. static void json_indent(OSSL_JSON_ENC *json);
  241. static void json_raise_error(OSSL_JSON_ENC *json)
  242. {
  243. json->error = 1;
  244. }
  245. static void json_undefer(OSSL_JSON_ENC *json)
  246. {
  247. if (!json->defer_indent)
  248. return;
  249. json_indent(json);
  250. }
  251. static void json_write_char(OSSL_JSON_ENC *json, char ch)
  252. {
  253. if (ossl_json_in_error(json))
  254. return;
  255. json_undefer(json);
  256. if (!wbuf_write_char(&json->wbuf, ch))
  257. json_raise_error(json);
  258. }
  259. static void json_write_str(OSSL_JSON_ENC *json, const char *s)
  260. {
  261. if (ossl_json_in_error(json))
  262. return;
  263. json_undefer(json);
  264. if (!wbuf_write_str(&json->wbuf, s))
  265. json_raise_error(json);
  266. }
  267. static void json_indent(OSSL_JSON_ENC *json)
  268. {
  269. size_t i, depth;
  270. json->defer_indent = 0;
  271. if (!in_pretty(json))
  272. return;
  273. json_write_char(json, '\n');
  274. depth = json->stack_end_byte * 8 + json->stack_end_bit;
  275. for (i = 0; i < depth * 4; ++i)
  276. json_write_str(json, " ");
  277. }
  278. static int json_pre_item(OSSL_JSON_ENC *json)
  279. {
  280. int s;
  281. if (ossl_json_in_error(json))
  282. return 0;
  283. switch (json->state) {
  284. case STATE_PRE_COMMA:
  285. s = json_peek(json);
  286. if (s == 0) {
  287. json_raise_error(json);
  288. return 0;
  289. }
  290. if (s == 1) {
  291. json_write_char(json, ',');
  292. if (ossl_json_in_error(json))
  293. return 0;
  294. json_indent(json);
  295. }
  296. if (s < 0 && in_seq(json))
  297. json_write_char(json, '\x1E');
  298. json->state = STATE_PRE_ITEM;
  299. break;
  300. case STATE_PRE_ITEM:
  301. break;
  302. case STATE_PRE_KEY:
  303. default:
  304. json_raise_error(json);
  305. return 0;
  306. }
  307. return 1;
  308. }
  309. static void json_post_item(OSSL_JSON_ENC *json)
  310. {
  311. int s = json_peek(json);
  312. json->state = STATE_PRE_COMMA;
  313. if (s < 0 && in_seq(json))
  314. json_write_char(json, '\n');
  315. }
  316. /*
  317. * Begin a composite structure (object or array).
  318. *
  319. * type: 0=object, 1=array.
  320. */
  321. static void composite_begin(OSSL_JSON_ENC *json, int type, char ch)
  322. {
  323. if (!json_pre_item(json)
  324. || !json_push(json, type))
  325. json_raise_error(json);
  326. json_write_char(json, ch);
  327. json->defer_indent = 1;
  328. }
  329. /*
  330. * End a composite structure (object or array).
  331. *
  332. * type: 0=object, 1=array. Errors on mismatch.
  333. */
  334. static void composite_end(OSSL_JSON_ENC *json, int type, char ch)
  335. {
  336. int was_defer = json->defer_indent;
  337. if (ossl_json_in_error(json))
  338. return;
  339. json->defer_indent = 0;
  340. if (json_peek(json) != type) {
  341. json_raise_error(json);
  342. return;
  343. }
  344. if (type == 0 && json->state == STATE_PRE_ITEM) {
  345. json_raise_error(json);
  346. return;
  347. }
  348. if (!json_pop(json)) {
  349. json_raise_error(json);
  350. return;
  351. }
  352. if (!was_defer)
  353. json_indent(json);
  354. json_write_char(json, ch);
  355. json_post_item(json);
  356. }
  357. /* Begin a new JSON object. */
  358. void ossl_json_object_begin(OSSL_JSON_ENC *json)
  359. {
  360. composite_begin(json, 0, '{');
  361. json->state = STATE_PRE_KEY;
  362. }
  363. /* End a JSON object. Must be matched with a call to ossl_json_object_begin(). */
  364. void ossl_json_object_end(OSSL_JSON_ENC *json)
  365. {
  366. composite_end(json, 0, '}');
  367. }
  368. /* Begin a new JSON array. */
  369. void ossl_json_array_begin(OSSL_JSON_ENC *json)
  370. {
  371. composite_begin(json, 1, '[');
  372. json->state = STATE_PRE_ITEM;
  373. }
  374. /* End a JSON array. Must be matched with a call to ossl_json_array_begin(). */
  375. void ossl_json_array_end(OSSL_JSON_ENC *json)
  376. {
  377. composite_end(json, 1, ']');
  378. }
  379. /*
  380. * Encode a JSON key within an object. Pass a zero-terminated string, which can
  381. * be freed immediately following the call to this function.
  382. */
  383. void ossl_json_key(OSSL_JSON_ENC *json, const char *key)
  384. {
  385. if (ossl_json_in_error(json))
  386. return;
  387. if (json_peek(json) != 0) {
  388. /* Not in object */
  389. json_raise_error(json);
  390. return;
  391. }
  392. if (json->state == STATE_PRE_COMMA) {
  393. json_write_char(json, ',');
  394. json->state = STATE_PRE_KEY;
  395. }
  396. json_indent(json);
  397. if (json->state != STATE_PRE_KEY) {
  398. json_raise_error(json);
  399. return;
  400. }
  401. json_write_qstring(json, key);
  402. if (ossl_json_in_error(json))
  403. return;
  404. json_write_char(json, ':');
  405. if (in_pretty(json))
  406. json_write_char(json, ' ');
  407. json->state = STATE_PRE_ITEM;
  408. }
  409. /* Encode a JSON 'null' value. */
  410. void ossl_json_null(OSSL_JSON_ENC *json)
  411. {
  412. if (!json_pre_item(json))
  413. return;
  414. json_write_str(json, "null");
  415. json_post_item(json);
  416. }
  417. void ossl_json_bool(OSSL_JSON_ENC *json, int v)
  418. {
  419. if (!json_pre_item(json))
  420. return;
  421. json_write_str(json, v > 0 ? "true" : "false");
  422. json_post_item(json);
  423. }
  424. #define POW_53 (((int64_t)1) << 53)
  425. /* Encode a JSON integer from a uint64_t. */
  426. static void json_u64(OSSL_JSON_ENC *json, uint64_t v, int noquote)
  427. {
  428. char buf[22], *p = buf + sizeof(buf) - 1;
  429. int quote = !noquote && in_ijson(json) && v > (uint64_t)(POW_53 - 1);
  430. if (!json_pre_item(json))
  431. return;
  432. if (quote)
  433. json_write_char(json, '"');
  434. if (v == 0)
  435. p = "0";
  436. else
  437. for (*p = '\0'; v > 0; v /= 10)
  438. *--p = '0' + v % 10;
  439. json_write_str(json, p);
  440. if (quote)
  441. json_write_char(json, '"');
  442. json_post_item(json);
  443. }
  444. void ossl_json_u64(OSSL_JSON_ENC *json, uint64_t v)
  445. {
  446. json_u64(json, v, 0);
  447. }
  448. /* Encode a JSON integer from an int64_t. */
  449. void ossl_json_i64(OSSL_JSON_ENC *json, int64_t value)
  450. {
  451. uint64_t uv;
  452. int quote;
  453. if (value >= 0) {
  454. ossl_json_u64(json, (uint64_t)value);
  455. return;
  456. }
  457. if (!json_pre_item(json))
  458. return;
  459. quote = in_ijson(json)
  460. && (value > POW_53 - 1 || value < -POW_53 + 1);
  461. if (quote)
  462. json_write_char(json, '"');
  463. json_write_char(json, '-');
  464. uv = (value == INT64_MIN)
  465. ? ((uint64_t)-(INT64_MIN + 1)) + 1
  466. : (uint64_t)-value;
  467. json_u64(json, uv, /*noquote=*/1);
  468. if (quote && !ossl_json_in_error(json))
  469. json_write_char(json, '"');
  470. }
  471. /*
  472. * Encode a JSON UTF-8 string from a zero-terminated string. The string passed
  473. * can be freed immediately following the call to this function.
  474. */
  475. static ossl_inline int hex_digit(int v)
  476. {
  477. return v >= 10 ? 'a' + (v - 10) : '0' + v;
  478. }
  479. static ossl_inline void
  480. json_write_qstring_inner(OSSL_JSON_ENC *json, const char *str, size_t str_len,
  481. int nul_term)
  482. {
  483. char c, *o, obuf[7];
  484. unsigned char *u_str;
  485. int i;
  486. size_t j;
  487. if (ossl_json_in_error(json))
  488. return;
  489. json_write_char(json, '"');
  490. for (j = nul_term ? strlen(str) : str_len; j > 0; str++, j--) {
  491. c = *str;
  492. u_str = (unsigned char*)str;
  493. switch (c) {
  494. case '\n': o = "\\n"; break;
  495. case '\r': o = "\\r"; break;
  496. case '\t': o = "\\t"; break;
  497. case '\b': o = "\\b"; break;
  498. case '\f': o = "\\f"; break;
  499. case '"': o = "\\\""; break;
  500. case '\\': o = "\\\\"; break;
  501. default:
  502. /* valid UTF-8 sequences according to RFC-3629 */
  503. if (u_str[0] >= 0xc2 && u_str[0] <= 0xdf && j >= 2
  504. && u_str[1] >= 0x80 && u_str[1] <= 0xbf) {
  505. memcpy(obuf, str, 2);
  506. obuf[2] = '\0';
  507. str++, j--;
  508. o = obuf;
  509. break;
  510. }
  511. if (u_str[0] >= 0xe0 && u_str[0] <= 0xef && j >= 3
  512. && u_str[1] >= 0x80 && u_str[1] <= 0xbf
  513. && u_str[2] >= 0x80 && u_str[2] <= 0xbf
  514. && !(u_str[0] == 0xe0 && u_str[1] <= 0x9f)
  515. && !(u_str[0] == 0xed && u_str[1] >= 0xa0)) {
  516. memcpy(obuf, str, 3);
  517. obuf[3] = '\0';
  518. str += 2;
  519. j -= 2;
  520. o = obuf;
  521. break;
  522. }
  523. if (u_str[0] >= 0xf0 && u_str[0] <= 0xf4 && j >= 4
  524. && u_str[1] >= 0x80 && u_str[1] <= 0xbf
  525. && u_str[2] >= 0x80 && u_str[2] <= 0xbf
  526. && u_str[3] >= 0x80 && u_str[3] <= 0xbf
  527. && !(u_str[0] == 0xf0 && u_str[1] <= 0x8f)
  528. && !(u_str[0] == 0xf4 && u_str[1] >= 0x90)) {
  529. memcpy(obuf, str, 4);
  530. obuf[4] = '\0';
  531. str += 3;
  532. j -= 3;
  533. o = obuf;
  534. break;
  535. }
  536. if (u_str[0] < 0x20 || u_str[0] >= 0x7f) {
  537. obuf[0] = '\\';
  538. obuf[1] = 'u';
  539. for (i = 0; i < 4; ++i)
  540. obuf[2 + i] = hex_digit((u_str[0] >> ((3 - i) * 4)) & 0x0F);
  541. obuf[6] = '\0';
  542. o = obuf;
  543. } else {
  544. json_write_char(json, c);
  545. continue;
  546. }
  547. break;
  548. }
  549. json_write_str(json, o);
  550. }
  551. json_write_char(json, '"');
  552. }
  553. static void
  554. json_write_qstring(OSSL_JSON_ENC *json, const char *str)
  555. {
  556. json_write_qstring_inner(json, str, 0, 1);
  557. }
  558. static void
  559. json_write_qstring_len(OSSL_JSON_ENC *json, const char *str, size_t str_len)
  560. {
  561. json_write_qstring_inner(json, str, str_len, 0);
  562. }
  563. void ossl_json_str(OSSL_JSON_ENC *json, const char *str)
  564. {
  565. if (!json_pre_item(json))
  566. return;
  567. json_write_qstring(json, str);
  568. json_post_item(json);
  569. }
  570. void ossl_json_str_len(OSSL_JSON_ENC *json, const char *str, size_t str_len)
  571. {
  572. if (!json_pre_item(json))
  573. return;
  574. json_write_qstring_len(json, str, str_len);
  575. json_post_item(json);
  576. }
  577. /*
  578. * Encode binary data as a lowercase hex string. data_len is the data length in
  579. * bytes.
  580. */
  581. void ossl_json_str_hex(OSSL_JSON_ENC *json, const void *data, size_t data_len)
  582. {
  583. const unsigned char *b = data, *end = b + data_len;
  584. unsigned char c;
  585. if (!json_pre_item(json))
  586. return;
  587. json_write_char(json, '"');
  588. for (; b < end; ++b) {
  589. c = *b;
  590. json_write_char(json, hex_digit(c >> 4));
  591. json_write_char(json, hex_digit(c & 0x0F));
  592. }
  593. json_write_char(json, '"');
  594. json_post_item(json);
  595. }