[OpenWrt-Devel] [PATCH] [libubox] b64: add base64 support

Luka Perkov luka at openwrt.org
Mon Mar 16 13:48:57 EDT 2015


The code has been taken from zstream project which
was written by Steven Barth.

Signed-off-by: Luka Perkov <luka at openwrt.org>
CC: Steven Barth <steven at midlink.org>
CC: John Crispin <blogic at openwrt.org>
---
 CMakeLists.txt |   2 +-
 b64.c          | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 b64.h          |  25 +++++++++++
 3 files changed, 162 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..9b6defe
--- /dev/null
+++ b/b64.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2011 Steven Barth <steven at midlink.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 <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "b64.h"
+
+static const unsigned char b64encode_tbl[] =
+	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+char *b64encode(const void *in, size_t *len)
+{
+	size_t lenout, pad, i;
+	const uint8_t *data = (const uint8_t *) in;
+	uint8_t *o;
+	char *out;
+
+	lenout = *len / 3;
+	lenout *= 4;
+	pad = *len % 3;
+
+	if (*len == 0)
+		return strdup("");
+	else if (pad)
+		lenout += 4;
+
+	out = calloc(lenout + 1, sizeof(char));
+	if (!out)
+		return NULL;
+
+	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;
+	}
+
+	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];
+	}
+
+	out[lenout] = '\0';
+	*len = lenout;
+	return out;
+}
+
+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
+};
+
+void *b64decode(const char *in, size_t *len)
+{
+	size_t lenout, i, j;
+	unsigned char *out, *o;
+
+	if (*len == 0) {
+		return strdup("");
+	} else if (*len % 4) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	lenout = *len / 4 * 3;
+
+	out = calloc(lenout + 1, sizeof(char));
+	if (!out)
+		return NULL;
+
+	o = 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);
+				errno = EINVAL;
+				return NULL;
+			}
+
+			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;
+	}
+
+	if (in[*len - 1] == '=')
+		lenout--;
+
+	if (in[*len - 2] == '=')
+		lenout--;
+
+	*len = lenout;
+	return out;
+}
diff --git a/b64.h b/b64.h
new file mode 100644
index 0000000..bf690de
--- /dev/null
+++ b/b64.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 Steven Barth <steven at midlink.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>
+
+char *b64encode(const void *in, size_t *len);
+void *b64decode(const char *in, size_t *len);
+
+#endif
-- 
2.3.3
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list