The base code has been taken from zstream project which was written by Steven Barth.
Signed-off-by: Luka Perkov <l...@openwrt.org> CC: Steven Barth <ste...@midlink.org> --- changes in v2: Use new API: size_t b64decode(void **out, const char *in, size_t len); size_t b64encode(char **out, const void *in, size_t len); CMakeLists.txt | 2 +- b64.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ b64.h | 26 ++++++++++ 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 b64.c create mode 100644 b64.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 58381da..77f4842 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ IF(JSONC_FOUND) INCLUDE_DIRECTORIES(${JSONC_INCLUDE_DIRS}) ENDIF() -SET(SOURCES avl.c avl-cmp.c blob.c blobmsg.c uloop.c usock.c ustream.c ustream-fd.c vlist.c utils.c safe_list.c runqueue.c md5.c kvlist.c ulog.c) +SET(SOURCES avl.c avl-cmp.c blob.c blobmsg.c uloop.c usock.c ustream.c ustream-fd.c vlist.c utils.c safe_list.c runqueue.c md5.c kvlist.c ulog.c b64.c) ADD_LIBRARY(ubox SHARED ${SOURCES}) ADD_LIBRARY(ubox-static STATIC ${SOURCES}) diff --git a/b64.c b/b64.c new file mode 100644 index 0000000..86593d2 --- /dev/null +++ b/b64.c @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2011 Steven Barth <ste...@midlink.org> + * Copyright (C) 2015 Luka Perkov <l...@openwrt.org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdint.h> +#include <stdlib.h> + +#include "b64.h" + +static const unsigned char b64decode_tbl[] = { + 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, + 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33 +}; + +static inline size_t b64_decode_size(const char *in, size_t len) +{ + size_t ret; + + if ((len == 0) || (len % 4)) + return 0; + + ret = len / 4 * 3; + + if (in[(int) len - 1] == '=') + ret--; + + if (in[(int) len - 2] == '=') + ret--; + + return ret; +} + +size_t b64decode(void **out, const char *in, size_t len) +{ + size_t lenout, i, j; + unsigned char *o; + + lenout = b64_decode_size(in, len); + if (!lenout) { + *out = NULL; + return 0; + } + + *out = calloc(lenout, sizeof(char)); + if (!(*out)) + return 0; + + o = (unsigned char *) *out; + for (i = 0; i < len; i += 4) { + uint32_t cv = 0; + for (j = 0; j < 4; j++) { + unsigned char c = in[i + j] - 43; + if (c > 79 || (c = b64decode_tbl[c]) == 0xff) { + free(*out); + *out = NULL; + return 0; + } + + cv |= c; + if (j != 3) { + cv <<= 6; + } + } + + o[2] = (unsigned char)( cv & 0xff); + o[1] = (unsigned char)((cv >> 8) & 0xff); + o[0] = (unsigned char)((cv >> 16) & 0xff); + o += 3; + } + + return lenout; +} + +static const unsigned char b64encode_tbl[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static inline size_t b64_encode_size(size_t len) +{ + size_t ret; + + if (len == 0) + return 0; + + ret = len / 3; + ret *= 4; + + if (len % 3) + ret += 4; + + return ret; +} + +size_t b64encode(char **out, const void *in, size_t len) +{ + size_t lenout, pad, i; + const uint8_t *data = (const uint8_t *) in; + uint8_t *o; + + lenout = b64_encode_size(len); + if (!lenout) { + *out = NULL; + return 0; + } + + *out = calloc(lenout, sizeof(char)); + if (!(*out)) + return 0; + + o = (uint8_t *) *out; + for (i = 0; i < len; i += 3) { + uint32_t cv = (data[i] << 16) | (data[i + 1] << 8) | data[i + 2]; + o[3] = b64encode_tbl[ cv & 0x3f]; + o[2] = b64encode_tbl[(cv >> 6 ) & 0x3f]; + o[1] = b64encode_tbl[(cv >> 12) & 0x3f]; + o[0] = b64encode_tbl[(cv >> 18) & 0x3f]; + o += 4; + } + + pad = len % 3; + if (pad) { + uint32_t cv = data[len - pad] << 16; + o[-1] = '='; + o[-2] = '='; + if (pad == 2) { + cv |= data[len - pad + 1] << 8; + o[-2] = b64encode_tbl[(cv >> 6) & 0x3f]; + } + o[-3] = b64encode_tbl[(cv >> 12) & 0x3f]; + o[-4] = b64encode_tbl[(cv >> 18) & 0x3f]; + } + + return lenout; +} diff --git a/b64.h b/b64.h new file mode 100644 index 0000000..098f4d8 --- /dev/null +++ b/b64.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2011 Steven Barth <ste...@midlink.org> + * Copyright (C) 2015 Luka Perkov <l...@openwrt.org> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __LIBUBOX_B64_H +#define __LIBUBOX_B64_H + +#include <stddef.h> + +size_t b64decode(void **out, const char *in, size_t len); +size_t b64encode(char **out, const void *in, size_t len); + +#endif -- 2.3.5 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel