From ad7fb045add90c3e4b3b7abe2a20eea3d05cfb1d Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Thu, 9 Mar 2023 01:14:10 +0100 Subject: [PATCH] Move decode_hex into its own file - Error detection against strotul(3) has been improved, as done in other places. - New function encode_hex has been implemented, which will be used by future commits. --- CMakeLists.txt | 1 + Makefile | 1 + auth.c | 29 +++++++---------------------- hex.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ hex.h | 9 +++++++++ 5 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 hex.c create mode 100644 hex.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2578291..83c25b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ add_executable(${PROJECT_NAME} base64.c cftw.c handler.c + hex.c html.c http.c jwt.c diff --git a/Makefile b/Makefile index fc00b3a..517959c 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ OBJECTS = \ base64.o \ cftw.o \ handler.o \ + hex.o \ html.o \ http.o \ jwt.o \ diff --git a/auth.c b/auth.c index b56e072..64e9a26 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,5 @@ #include "auth.h" +#include "hex.h" #include "http.h" #include "jwt.h" #include @@ -70,22 +71,6 @@ end: return ret; } -static int decode_hex(const char *const hex, unsigned char *buf, size_t n) -{ - for (const char *s = hex; *s; s += 2) - { - const char nibble[sizeof "00"] = {*s, *(s + 1)}; - - if (!n) - return -1; - - *buf++ = strtoul(nibble, NULL, 16); - n--; - } - - return n ? -1 : 0; -} - static int find_cookie(const cJSON *const users, const char *const cookie) { const cJSON *u; @@ -107,9 +92,9 @@ static int find_cookie(const cJSON *const users, const char *const cookie) fprintf(stderr, "%s: missing key\n", __func__); return -1; } - else if (decode_hex(key, dkey, sizeof dkey)) + else if (hex_decode(key, dkey, sizeof dkey)) { - fprintf(stderr, "%s: decode_hex failed\n", __func__); + fprintf(stderr, "%s: hex_decode failed\n", __func__); return -1; } @@ -177,9 +162,9 @@ static int generate_cookie(const cJSON *const json, const char *const path, int ret = -1; char *jwt = NULL; - if (decode_hex(key, dkey, sizeof dkey)) + if (hex_decode(key, dkey, sizeof dkey)) { - fprintf(stderr, "%s: decode_hex failed\n", __func__); + fprintf(stderr, "%s: hex_decode failed\n", __func__); goto end; } else if (!(jwt = jwt_encode(name, dkey, sizeof dkey))) @@ -220,9 +205,9 @@ static int compare_pwd(const char *const salt, const char *const password, fprintf(stderr, "%s: malloc(3): %s\n", __func__, strerror(errno)); goto end; } - else if (decode_hex(salt, dec_salt, sizeof dec_salt)) + else if (hex_decode(salt, dec_salt, sizeof dec_salt)) { - fprintf(stderr, "%s: decode_hex failed\n", __func__); + fprintf(stderr, "%s: hex_decode failed\n", __func__); goto end; } diff --git a/hex.c b/hex.c new file mode 100644 index 0000000..61cf55f --- /dev/null +++ b/hex.c @@ -0,0 +1,49 @@ +#include "hex.h" +#include +#include +#include +#include + +int hex_encode(const void *const b, char *hex, const size_t buflen, + size_t hexlen) +{ + const char *buf = b; + + for (size_t i = 0; i < buflen; i++) + { + const int r = snprintf(hex, hexlen, "%02hhx", *(const char *)buf++); + + if (r < 0 || r >= hexlen) + return -1; + + hexlen -= r; + hex += 2; + } + + return 0; +} + +int hex_decode(const char *const hex, void *const b, size_t n) +{ + unsigned char *buf = b; + + for (const char *s = hex; *s; s += 2) + { + const char nibble[sizeof "00"] = {*s, *(s + 1)}; + + if (!n) + return -1; + + char *end; + + errno = 0; + *buf++ = strtoul(nibble, &end, 16); + + if (errno || *end) + return -1; + + n--; + } + + return n ? -1 : 0; +} diff --git a/hex.h b/hex.h new file mode 100644 index 0000000..2195415 --- /dev/null +++ b/hex.h @@ -0,0 +1,9 @@ +#ifndef HEX_H +#define HEX_H + +#include + +int hex_encode(const void *buf, char *hex, size_t buflen, size_t hexlen); +int hex_decode(const char *hex, void *buf, size_t n); + +#endif /* HEX_H */