From d47963247d0bd33fa82bff63cfe38b4ab5446577 Mon Sep 17 00:00:00 2001 From: Theo Buehler Date: Sun, 11 Oct 2026 18:05:37 +0200 Subject: [PATCH] challengeauth_response (): move digest to stack Using HMAC ()'s facility of returning the digest in a static array is not thread safe (this can't be fixed) and it is not portable to the OpenSSL forks: BoringSSL removed support for this a decade ago (so aws-lc doesn't support it either) and LibreSSL followed a few years back. There is no downside to having a 32-byte array on the stack and it would make zoitechat safe to use from other forks without the need of patching it. Add an error check for the HMAC () call and handle the error in the caller. --- src/common/proto-irc.c | 5 +++++ src/common/util.c | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index d2491a15..5f1cf62c 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -1288,6 +1288,11 @@ process_named_msg (session *sess, char *type, char *word[], char *word_eol[], char *user = net && net->user ? net->user : prefs.hex_irc_user_name; response = challengeauth_response (user, serv->password, word[5]); + if (response == NULL) + { + PrintTextf (serv->server_session, _("Error building CHALLENGEAUTH for %s"), user); + return; + } tcp_sendf (serv, "PRIVMSG %s :CHALLENGEAUTH %s %s %s\r\n", CHALLENGEAUTH_NICK, diff --git a/src/common/util.c b/src/common/util.c index 001dc083..1f2d32a5 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1453,7 +1453,7 @@ challengeauth_response (const char *username, const char *password, const char * char *passhash; char *key; char *keyhash; - unsigned char *digest; + unsigned char digest[SHA256_DIGEST_LENGTH]; GString *buf = g_string_new_len (NULL, SHA256_DIGEST_LENGTH * 2); user = rfc_strlower (username); /* convert username to lowercase as per the RFC */ @@ -1469,7 +1469,12 @@ challengeauth_response (const char *username, const char *password, const char * keyhash = str_sha256hash (key); g_free (key); - digest = HMAC (EVP_sha256 (), keyhash, strlen (keyhash), (unsigned char *) challenge, strlen (challenge), NULL, NULL); + if (HMAC (EVP_sha256 (), keyhash, strlen (keyhash), (unsigned char *) challenge, strlen (challenge), digest, NULL) == NULL) + { + g_free (keyhash); + g_string_free (buf, TRUE); + return NULL; + } g_free (keyhash); for (i = 0; i < SHA256_DIGEST_LENGTH; i++)