From 759a3436e054e8716ac038d1e54cb7d794c4041e Mon Sep 17 00:00:00 2001 From: "aiyion.prime" Date: Sat, 6 Aug 2022 14:14:03 +0200 Subject: [PATCH] gluon-mesh-vpn-wireguard: add gluon-hex-to-b64 gluon-hex-to-b64 takes base64 content such as a fastd private key in legacy form via stdin and emits it in base64 encoded (WireGuard) form. Provides basic return codes. --- package/gluon-mesh-vpn-wireguard/Makefile | 8 +- package/gluon-mesh-vpn-wireguard/src/Makefile | 5 +- .../src/gluon-hex-to-b64.c | 101 ++++++++++++++++++ 3 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 package/gluon-mesh-vpn-wireguard/src/gluon-hex-to-b64.c diff --git a/package/gluon-mesh-vpn-wireguard/Makefile b/package/gluon-mesh-vpn-wireguard/Makefile index 61c53332..9d4e9a79 100644 --- a/package/gluon-mesh-vpn-wireguard/Makefile +++ b/package/gluon-mesh-vpn-wireguard/Makefile @@ -6,7 +6,13 @@ include ../gluon.mk define Package/gluon-mesh-vpn-wireguard TITLE:=Support for connecting meshes via wireguard - DEPENDS:=+gluon-core +libgluonutil +gluon-mesh-vpn-core +wireguard-tools +wgpeerselector +libubus + DEPENDS:=+gluon-core +libgluonutil +gluon-mesh-vpn-core +wireguard-tools +wgpeerselector +libubox +libubus +endef + +define Package/gluon-mesh-vpn-wireguard/install + $(Gluon/Build/Install) + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/gluon-hex-to-b64 $(1)/usr/sbin/ endef $(eval $(call BuildPackageGluon,gluon-mesh-vpn-wireguard)) diff --git a/package/gluon-mesh-vpn-wireguard/src/Makefile b/package/gluon-mesh-vpn-wireguard/src/Makefile index 0b027848..ff847068 100644 --- a/package/gluon-mesh-vpn-wireguard/src/Makefile +++ b/package/gluon-mesh-vpn-wireguard/src/Makefile @@ -1,6 +1,9 @@ -all: respondd.so +all: respondd.so gluon-hex-to-b64 CFLAGS += -Wall -Werror-implicit-function-declaration +gluon-hex-to-b64: gluon-hex-to-b64.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS) -lubox + respondd.so: respondd.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -o $@ $^ $(LDLIBS) -lgluonutil -lubus diff --git a/package/gluon-mesh-vpn-wireguard/src/gluon-hex-to-b64.c b/package/gluon-mesh-vpn-wireguard/src/gluon-hex-to-b64.c new file mode 100644 index 00000000..0bca245e --- /dev/null +++ b/package/gluon-mesh-vpn-wireguard/src/gluon-hex-to-b64.c @@ -0,0 +1,101 @@ +// SPDX-FileCopyrightText: 2022 Jan-Niklas Burfeind +// SPDX-License-Identifier: BSD-2-Clause +// SPDX-FileContributor: read_hex() by Matthias Schiffer + +#include +#include +#include +#include +#include +#include + +/** + * how many blocks should be encoded at once - can be configured + */ +#define BLOCK_AMOUNT 32 + +/** + * smallest possible block size to encode in b64 without further contex + * is three bytes - do not change + */ +#define CHUNK_SIZE (3*BLOCK_AMOUNT) + +/** print usage info and exit as failed */ +static void usage(void) { + fprintf(stderr, "Usage: gluon-hex-to-b64\n"); + exit(1); +} + +/** + * read a string of hexadecimal characters and return them as bytes + * return false in case any non-hexadecimal characters are provided + * return true on success + */ +static bool read_hex(uint8_t key[CHUNK_SIZE], const char *hexstr) { + if (strspn(hexstr, "0123456789abcdefABCDEF") != strlen(hexstr)) + return false; + + size_t i; + for (i = 0; i < CHUNK_SIZE; i++) + sscanf(&hexstr[2 * i], "%02hhx", &key[i]); + + return true; +} + +int main(int argc, char *argv[]) { + if (argc != 1) + usage(); + + unsigned char hex_input[CHUNK_SIZE * 2 + 1]; + uint8_t as_bytes[CHUNK_SIZE]; + int byte_count; + int b64_buflen = B64_ENCODE_LEN(CHUNK_SIZE); + int b64_return; + size_t ret; + + char str[b64_buflen]; + + do { + ret = fread(hex_input, 1, sizeof(hex_input) - 1, stdin); + hex_input[ret] = '\0'; + + /* in case fread did not fill six characters */ + if (ret != sizeof(hex_input)-1) { + /* drop newline by replacing it with a null character */ + hex_input[strcspn(hex_input, "\n")] = 0; + + /* + * count length of resulting string and make sure it's even, + * as bytes are represented using pairs of hex characters + */ + ret = strlen(hex_input); + if (ret % 2 == 1) { + fprintf(stderr, "Error: Incomplete hex representation of a byte.\n"); + exit(EXIT_FAILURE); + } + } + + byte_count = ret / 2; + b64_buflen = B64_ENCODE_LEN(byte_count); + + /* in case read_hex fails due to invalid characters */ + if (!read_hex(as_bytes, hex_input)) { + fprintf(stderr, "Error: Invalid hexadecimal input.\n"); + exit(EXIT_FAILURE); + } + + b64_return = b64_encode(as_bytes, byte_count, str, b64_buflen); + + /* trailing '\0' is not counted by b64_encode(), so we subtract one character */ + if (b64_buflen - 1 != b64_return) { + fprintf(stderr, "Error: Encoding bytes as b64 failed.\n"); + exit(EXIT_FAILURE); + } + + printf("%s", str); + /* repeat until a non full block is read */ + } while (ret == sizeof(hex_input)-1); + printf("\n"); + + exit(EXIT_SUCCESS); +}