json_enc.c 17 KB

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