From a5559e06227d1ae7356ae6ade7a23c4868d92c91 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 3 Nov 2023 14:07:39 +0100 Subject: [PATCH 1/2] hexdecoct: implicitly parse URL-safe base64 format, too JSON-I (RFC 7493) suggests to use the URL safe base64 alphabet, rather than the regular one when encoding binary data in JSON strings. We generally uses the regular alphabet though. Let's be tolerant in what we parse however: simply accept both formats when we parse base64. This does nothing about base64 generation though, only about parsing. --- src/basic/hexdecoct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c index 898ed83f86..ea683eb427 100644 --- a/src/basic/hexdecoct.c +++ b/src/basic/hexdecoct.c @@ -553,12 +553,12 @@ int unbase64char(char c) { offset += '9' - '0' + 1; - if (c == '+') + if (IN_SET(c, '+', '-')) /* Support both the regular and the URL safe character set (see above) */ return offset; offset++; - if (c == '/') + if (IN_SET(c, '/', '_')) /* ditto */ return offset; return -EINVAL; From fd81692f4b51d1f7f8914acbe79595f6dfa460f5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 3 Nov 2023 21:34:45 +0100 Subject: [PATCH 2/2] test: add test for the combined base64/base64url decoder --- src/test/test-hexdecoct.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/test/test-hexdecoct.c b/src/test/test-hexdecoct.c index 9d71db6ae1..f884008660 100644 --- a/src/test/test-hexdecoct.c +++ b/src/test/test-hexdecoct.c @@ -516,4 +516,33 @@ TEST(hexdump) { hexdump(stdout, data, sizeof(data)); } +TEST(base64withwithouturl) { + static const uint8_t plaintext[] = { + 0xcc, 0xa1, 0x72, 0x22, 0xae, 0xda, 0x66, 0x7e, 0x04, 0xa6, 0xe0, 0x82, + 0x9a, 0x97, 0x05, 0xf6, 0x33, 0xe0, 0x0f, 0xc2, 0x45, 0x13, 0x58, 0x3f, + 0xc5, 0xf4, 0xf4, 0x31, 0xab, 0x3c, 0x5f, 0x83, 0x34, 0x5b, 0x27, 0x32, + 0x8a, 0x04, 0x6c, 0x43, 0x82, 0x07, 0xe3, 0x2c, 0xac, 0xb9, 0xfb, 0xac, + 0xd0, 0x03, 0x91, 0x42, 0xcb, 0xa4, 0xde, 0x87, 0x86, 0x85, 0x10, 0xbb, + 0xb7, 0x5b, 0x4b, 0xc8, 0xa0, 0xf4, 0x22, 0x1d, 0x15, 0x71, 0x87, 0x9d, + 0xbf, 0x9f, 0xa9, 0xf1, 0xee, 0xa2, 0xb6, 0xaa, 0xc8, 0xc3, 0x37, 0x9c, + 0xbb, 0xdf, 0x3e, 0xac, 0xdc, 0x94, 0x54, 0x38, 0x56, 0x07, 0x34, 0xb4, + 0x3c, 0xcc, 0x31, 0x13 + }; + + _cleanup_free_ void *buffer = NULL; + size_t size; + + /* This is regular base64 */ + assert_se(unbase64mem("zKFyIq7aZn4EpuCCmpcF9jPgD8JFE1g/xfT0Mas8X4M0WycyigRsQ4IH4yysufus0AORQsuk3oeGhRC7t1tLyKD0Ih0VcYedv5+p8e6itqrIwzecu98+rNyUVDhWBzS0PMwxEw==", SIZE_MAX, &buffer, &size) >= 0); + assert_se(memcmp_nn(plaintext, sizeof(plaintext), buffer, size) == 0); + buffer = mfree(buffer); + + /* This is the same but in base64url */ + assert_se(unbase64mem("zKFyIq7aZn4EpuCCmpcF9jPgD8JFE1g_xfT0Mas8X4M0WycyigRsQ4IH4yysufus0AORQsuk3oeGhRC7t1tLyKD0Ih0VcYedv5-p8e6itqrIwzecu98-rNyUVDhWBzS0PMwxEw==", SIZE_MAX, &buffer, &size) >= 0); + assert_se(memcmp_nn(plaintext, sizeof(plaintext), buffer, size) == 0); + + /* Hint: use xxd -i to generate the static C array from some data, and basenc --base64 + basenc + * --base64url to generate the correctly encoded base64 strings */ +} + DEFINE_TEST_MAIN(LOG_INFO);