BUG/MINOR: acme: possible integer underflow in acme_txt_record()

a2base64url() can return a negative value is olen is too short to
accept ilen. This is not supposed to happen since the sha256 should
always fit in a buffer. But this is confusing since a2base64()
returns a signed integer which is pt in output->data which is unsigned.

Fix the issue by setting ret to 0 instead of -1 upon error. And returns
a unsigned integer instead of a signed one.
This patch also checks the return value from the caller in order
to emit an error instead of setting trash.data which is already done
from the function.
This commit is contained in:
William Lallemand 2025-08-03 13:51:44 +02:00
parent 8afd3e588d
commit 66f28dbd3f

View File

@ -898,7 +898,7 @@ int acme_http_req(struct task *task, struct acme_ctx *ctx, struct ist url, enum
* https://datatracker.ietf.org/doc/html/rfc8555/#section-8.4
*
*/
int acme_txt_record(const struct ist thumbprint, const struct ist token, struct buffer *output)
unsigned int acme_txt_record(const struct ist thumbprint, const struct ist token, struct buffer *output)
{
unsigned char md[EVP_MAX_MD_SIZE];
struct buffer *tmp = NULL;
@ -917,7 +917,8 @@ int acme_txt_record(const struct ist thumbprint, const struct ist token, struct
goto out;
ret = a2base64url((const char *)md, size, output->area, output->size);
if (ret < 0)
ret = 0;
output->data = ret;
out:
@ -1583,8 +1584,11 @@ int acme_res_auth(struct task *task, struct acme_ctx *ctx, struct acme_auth *aut
struct sink *dpapi;
struct ist line[7];
if (acme_txt_record(ist(ctx->cfg->account.thumbprint), auth->token, &trash) == 0) {
memprintf(errmsg, "couldn't compute the DNS-01 challenge");
goto error;
}
trash.data = acme_txt_record(ist(ctx->cfg->account.thumbprint), auth->token, &trash);
send_log(NULL, LOG_NOTICE,"acme: %s: DNS-01 requires to set the \"_acme-challenge.%.*s\" TXT record to \"%.*s\" and use the \"acme challenge_ready\" command over the CLI\n",
ctx->store->path, (int)auth->dns.len, auth->dns.ptr, (int)trash.data, trash.area);