Mercurial > libjeffpc
changeset 740:12be3c54727b
base64: add base64url encoder/decoder
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Sun, 31 Mar 2019 15:03:58 +0300 |
parents | c70b925f6484 |
children | 7a839d21735a |
files | base64.c include/jeffpc/base64.h mapfile-vers tests/CMakeLists.txt tests/base64/valid/1kB-random.b64url tests/base64/valid/a.b64url tests/base64/valid/ab.b64url tests/base64/valid/abc.b64url tests/base64/valid/abcd.b64url tests/base64/valid/abcde.b64url tests/base64/valid/abcdef.b64url tests/base64/valid/abcdefg.b64url tests/base64/valid/empty.b64url tests/base64/valid/f.b64url tests/base64/valid/ff.b64url tests/base64/valid/fo.b64url tests/base64/valid/foo.b64url tests/base64/valid/foob.b64url tests/base64/valid/fooba.b64url tests/base64/valid/foobar.b64url tests/base64/valid/nul.b64url tests/test_base64_decode.c tests/test_base64_encode.c |
diffstat | 23 files changed, 89 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/base64.c Sun Mar 31 14:53:30 2019 +0300 +++ b/base64.c Sun Mar 31 15:03:58 2019 +0300 @@ -27,6 +27,11 @@ "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; +static const char b64url_encode_table[64] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789-_"; + #define INV 0xff static const uint8_t b64_decode_table[256] = { INV, INV, INV, INV, INV, INV, INV, INV, /* 0x00..0x07 */ @@ -63,6 +68,41 @@ INV, INV, INV, INV, INV, INV, INV, INV, /* 0xf8..0xff */ }; +static const uint8_t b64url_decode_table[256] = { + INV, INV, INV, INV, INV, INV, INV, INV, /* 0x00..0x07 */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0x08..0x0f */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0x10..0x17 */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0x18..0x1f */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0x20..0x27 */ + INV, INV, INV, INV, INV, 0x3e, INV, INV, /* 0x28..0x2f */ + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, /* 0x30..0x37 */ + 0x3c, 0x3d, INV, INV, INV, INV, INV, INV, /* 0x38..0x3f */ + INV, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, /* 0x40..0x47 */ + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, /* 0x48..0x4f */ + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, /* 0x50..0x57 */ + 0x17, 0x18, 0x19, INV, INV, INV, INV, 0x3f, /* 0x58..0x5f */ + INV, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, /* 0x60..0x67 */ + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, /* 0x68..0x6f */ + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, /* 0x70..0x77 */ + 0x31, 0x32, 0x33, INV, INV, INV, INV, INV, /* 0x78..0x7f */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0x80..0x87 */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0x88..0x8f */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0x90..0x97 */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0x98..0x9f */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xa0..0xa7 */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xa8..0xaf */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xb0..0xb7 */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xb8..0xbf */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xc0..0xc7 */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xc8..0xcf */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xd0..0xd7 */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xd8..0xdf */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xe0..0xe7 */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xe8..0xef */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xf0..0xf7 */ + INV, INV, INV, INV, INV, INV, INV, INV, /* 0xf8..0xff */ +}; + __attribute__((always_inline)) static inline void __b64_encode(char *out, const void *_in, size_t inlen, const char *table) @@ -120,6 +160,11 @@ __b64_encode(out, in, inlen, b64_encode_table); } +void base64url_encode(char *out, const void *in, size_t inlen) +{ + __b64_encode(out, in, inlen, b64url_encode_table); +} + __attribute__((always_inline)) static inline ssize_t __b64_decode(void *_out, const char *_in, size_t inlen, const uint8_t *table) @@ -193,3 +238,8 @@ { return __b64_decode(out, in, inlen, b64_decode_table); } + +ssize_t base64url_decode(void *out, const char *in, size_t inlen) +{ + return __b64_decode(out, in, inlen, b64url_decode_table); +}
--- a/include/jeffpc/base64.h Sun Mar 31 14:53:30 2019 +0300 +++ b/include/jeffpc/base64.h Sun Mar 31 15:03:58 2019 +0300 @@ -30,6 +30,9 @@ extern ssize_t base64_decode(void *out, const char *in, size_t inlen); extern void base64_encode(char *out, const void *in, size_t inlen); +extern ssize_t base64url_decode(void *out, const char *in, size_t inlen); +extern void base64url_encode(char *out, const void *in, size_t inlen); + /* returns number of bytes needed to encode an input of @inlen bytes */ static inline size_t base64_required_length(size_t inlen) {
--- a/mapfile-vers Sun Mar 31 14:53:30 2019 +0300 +++ b/mapfile-vers Sun Mar 31 15:03:58 2019 +0300 @@ -31,6 +31,8 @@ # base64 base64_decode; base64_encode; + base64url_decode; + base64url_encode; # bst bst_add;
--- a/tests/CMakeLists.txt Sun Mar 31 14:53:30 2019 +0300 +++ b/tests/CMakeLists.txt Sun Mar 31 15:03:58 2019 +0300 @@ -22,8 +22,8 @@ build_perf_bin(tree) -build_test_bin_and_run_files(base64_encode raw b64 base64/valid) -build_test_bin_and_run_files(base64_decode b64 raw base64/valid) +build_test_bin_and_run_files(base64_encode raw "b64;b64url" base64/valid) +build_test_bin_and_run_files(base64_decode "b64;b64url" raw base64/valid) build_test_bin_and_run_files(cbor_pack lisp cbor cbor-common/valid) build_test_bin_and_run_files(cbor_unpack cbor lisp "cbor-common/valid;cbor-common/valid-unpack")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/1kB-random.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +3sgHmxdfbKlVGHyuC2T8qY_ZTNkVnc8tYlGs5WqS1PnVt4pUUsZzeulRCj2KVNNt6oI85FxRfFgZgJ0eyHSADyivtjRY4a8HbiolJ7oBlETXpMIjthCbUo4j89cPnLvcYmqYcBF0diuRji9_aeYujCAQTzRnoccelM6CyrrkIjjG9QhPEidC5LDmPClWn34FIIO7Us2cjW1FWjQG_NGUPoaSKsFhu2wEM9cLM9jI9-e8PldQhnfUFplPShKAVPzj-v2NvN695icjVAti4-g1T-MNfZPge1PVm_by71SUjho4OrdpSt-Zpbw9ZVxUDG8NzmmAjVk0Of2nieYeLaANHihUM5dl2QAg9cxXkLyIBHuBCgyU-cVTU82ld-RpV7n0Q-nWUtd4lVqm6Tzxcv5UDzRHx3lp7QhFgvLWlK3bd6edMJbKZHDXfPFuOWzmEDxqgu5NtePoFAW3OgbZ_OyuONeUphBqlyevdwIVAZ_B2D1_hkZ665m_CPJ8GJ9f3FUR_vyGIkmTQm2m9w-AQOL776uWch_untbh8_2miKuZ1MYzBgWUtmAk_sGJTm58o2Ss00cnAVPwYliyrhnDqspuHd2dg_lQv9GciUcrVSxnRxQCG8usLZLkXPEKv-rBNC04WFRt89WTVPMSU0qXz9xuCrhrfgykcmcTzSx8YESDGVfoCucMQ-HfPqoKSqXXSsycBSg5XAMwA8S8cOFNIUiRQr4cwxi00GvWpvyP995CEZNpCDgh14h5zfAzFZYrXqDD_yX39Rag6ulcMuXaqt3M2DzsbzLCURXL9LIZBLISgWg94ryE0rr5zCwRxx6X7vWltWWQjFJs382l5wyX2JNxXgRHxbwCka5NPAwCmbDRz47RDAcVsEyyQO_p6-JoUgVZwX44rEYQRh5PYzzUGMN9or8W3hL31j9GAd346o2VWXifFH4JH3ZPKH7A_th3s5pV3qRCIN50Do8w-TerlmFkErXAo2tfxc7ksS6aWeNV875_aIrrBGJUulftPoaXw9gGcyh1wCHv4olKA4eAT3_EfFR6fXQiIAkRvyllRVky2BaLmKmoMI4yCHYoNaPFh-QJJqA8PMSEmw1P-P6eUP-hnhHEzKHDSd3fOEiIUKid62-q4P9wHJOO3_lU_iZ-n2s9yEx6qwV3cCnnbsYZ-pGPvkR8Y3VgOM6iwV23S0J5NRVSXo5VP3u4W89EU6Zqbam31ycJl9I2FcA1efTpms7G14G1kKhINj48siCKczSHhAbUrgcjpbhkxkJ9DbOBJk7SkPMK1LfaPFfxQWXa7ovPqVvTpTcDIynl50RTcli4uXUriLXuY_SrXGIAD57XjEVHE5j2QAKffPlh2cEldo6rEw== \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/a.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +a.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/ab.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +ab.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/abc.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +abc.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/abcd.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +abcd.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/abcde.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +abcde.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/abcdef.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +abcdef.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/abcdefg.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +abcdefg.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/empty.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +empty.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/f.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +f.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/ff.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +_w== \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/fo.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +fo.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/foo.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +foo.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/foob.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +foob.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/fooba.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +fooba.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/foobar.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +foobar.b64 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/base64/valid/nul.b64url Sun Mar 31 15:03:58 2019 +0300 @@ -0,0 +1,1 @@ +nul.b64 \ No newline at end of file
--- a/tests/test_base64_decode.c Sun Mar 31 14:53:30 2019 +0300 +++ b/tests/test_base64_decode.c Sun Mar 31 15:03:58 2019 +0300 @@ -35,7 +35,8 @@ fprintf(stderr, "%s", tmp); } -static void check(const void *raw, size_t rawlen, const char *b64, size_t b64len) +static void check(const void *raw, size_t rawlen, const char *b64, size_t b64len, + bool url) { /* +10 as a redzone to catch out of bounds writes */ uint8_t out[rawlen + 10]; @@ -48,7 +49,11 @@ dumpraw(raw, rawlen); fprintf(stderr, "\n"); - ret = base64_decode(out, b64, b64len); + if (!url) + ret = base64_decode(out, b64, b64len); + else + ret = base64url_decode(out, b64, b64len); + if (ret < 0) fail("failed to decode"); @@ -66,5 +71,5 @@ void test(const char *ifname, void *in, size_t ilen, const char *iext, const char *ofname, void *out, size_t olen, const char *oext) { - check(out, olen, in, ilen); + check(out, olen, in, ilen, !strcmp(iext, "b64url")); }
--- a/tests/test_base64_encode.c Sun Mar 31 14:53:30 2019 +0300 +++ b/tests/test_base64_encode.c Sun Mar 31 15:03:58 2019 +0300 @@ -35,7 +35,8 @@ fprintf(stderr, "%s", tmp); } -static void check(const void *raw, size_t rawlen, const char *b64, size_t b64len) +static void check(const void *raw, size_t rawlen, const char *b64, size_t b64len, + bool url) { /* +1 for \0, +10 as a redzone to catch out of bounds writes */ char out[b64len + 1 + 10]; @@ -47,7 +48,10 @@ fprintf(stderr, "\n"); fprintf(stderr, "exp: '%s'\n", b64); - base64_encode(out, raw, rawlen); + if (!url) + base64_encode(out, raw, rawlen); + else + base64url_encode(out, raw, rawlen); fprintf(stderr, "got: '%s'\n", out); @@ -58,5 +62,5 @@ void test(const char *ifname, void *in, size_t ilen, const char *iext, const char *ofname, void *out, size_t olen, const char *oext) { - check(in, ilen, out, olen); + check(in, ilen, out, olen, !strcmp(oext, "b64url")); }