diff options
author | Simon Tatham <anakin@pobox.com> | 2022-04-22 13:22:56 +0300 |
---|---|---|
committer | Simon Tatham <anakin@pobox.com> | 2022-04-25 16:10:16 +0300 |
commit | 043c24844a45a209697383e6847f35872232a287 (patch) | |
tree | 0f61255d46d6990a7912e10aebe3a60fbe53b529 /utils | |
parent | 1bd2af1f875b8c7927906eadaf578013df8d999f (diff) |
Improve the base64 utility functions.
The low-level functions to handle a single atom of base64 at a time
have been in 'utils' / misc.h for ages, but the higher-level family of
base64_encode functions that handle a whole data block were hidden
away in sshpubk.c, and there was no higher-level decode function at
all.
Now moved both into 'utils' modules and declared them in misc.h rather
than ssh.h. Also, improved the APIs: they all take ptrlen in place of
separate data and length arguments, their naming is more consistent
and more explicit (the previous base64_encode which didn't name its
destination is now base64_encode_fp), and the encode functions now
accept cpl == 0 as a special case meaning that the output base64 data
is wanted in the form of an unbroken single-line string with no
trailing \n.
Diffstat (limited to 'utils')
-rw-r--r-- | utils/CMakeLists.txt | 2 | ||||
-rw-r--r-- | utils/base64_decode.c | 37 | ||||
-rw-r--r-- | utils/base64_encode.c | 40 |
3 files changed, 79 insertions, 0 deletions
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 9e995e04..74ce4d54 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -2,7 +2,9 @@ add_sources_from_current_dir(utils antispoof.c backend_socket_log.c base64_decode_atom.c + base64_decode.c base64_encode_atom.c + base64_encode.c bufchain.c buildinfo.c burnstr.c diff --git a/utils/base64_decode.c b/utils/base64_decode.c new file mode 100644 index 00000000..4f00f196 --- /dev/null +++ b/utils/base64_decode.c @@ -0,0 +1,37 @@ +#include "misc.h" + +void base64_decode_bs(BinarySink *bs, ptrlen input) +{ + BinarySource src[1]; + BinarySource_BARE_INIT_PL(src, input); + + while (get_avail(src)) { + char b64atom[4]; + unsigned char binatom[3]; + + for (size_t i = 0; i < 4 ;) { + char c = get_byte(src); + if (get_err(src)) + c = '='; + if (c == '\n' || c == '\r') + continue; + b64atom[i++] = c; + } + + put_data(bs, binatom, base64_decode_atom(b64atom, binatom)); + } +} + +void base64_decode_fp(FILE *fp, ptrlen input) +{ + stdio_sink ss; + stdio_sink_init(&ss, fp); + base64_decode_bs(BinarySink_UPCAST(&ss), input); +} + +strbuf *base64_decode_sb(ptrlen input) +{ + strbuf *sb = strbuf_new_nm(); + base64_decode_bs(BinarySink_UPCAST(sb), input); + return sb; +} diff --git a/utils/base64_encode.c b/utils/base64_encode.c new file mode 100644 index 00000000..3db85571 --- /dev/null +++ b/utils/base64_encode.c @@ -0,0 +1,40 @@ +#include "misc.h" + +void base64_encode_bs(BinarySink *bs, ptrlen input, int cpl) +{ + BinarySource src[1]; + BinarySource_BARE_INIT_PL(src, input); + int linelen = 0; + + while (get_avail(src)) { + size_t n = get_avail(src) < 3 ? get_avail(src) : 3; + ptrlen binatom = get_data(src, n); + + char b64atom[4]; + base64_encode_atom(binatom.ptr, binatom.len, b64atom); + for (size_t i = 0; i < 4; i++) { + if (cpl > 0 && linelen >= cpl) { + linelen = 0; + put_byte(bs, '\n'); + } + put_byte(bs, b64atom[i]); + linelen++; + } + } + if (cpl > 0) + put_byte(bs, '\n'); +} + +void base64_encode_fp(FILE *fp, ptrlen input, int cpl) +{ + stdio_sink ss; + stdio_sink_init(&ss, fp); + base64_encode_bs(BinarySink_UPCAST(&ss), input, cpl); +} + +strbuf *base64_encode_sb(ptrlen input, int cpl) +{ + strbuf *sb = strbuf_new_nm(); + base64_encode_bs(BinarySink_UPCAST(sb), input, cpl); + return sb; +} |