]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: acme: skip auth/challenge steps when newOrder returns a certificate
authorWilliam Lallemand <wlallemand@haproxy.com>
Wed, 29 Apr 2026 16:10:07 +0000 (18:10 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Wed, 29 Apr 2026 16:22:45 +0000 (18:22 +0200)
When an ACME server returns a certificate URL directly in the newOrder
response (order already validated), parse it and transition straight to
ACME_CERTIFICATE, bypassing the auth/challenge steps.

This needs to be backported to 3.2.

src/acme.c

index def664aa747b75279a2749eab50d35d7ef22f75a..5d5bfa7d3fc9ebbc597eb3226a0ad6029604a4a7 100644 (file)
@@ -2127,10 +2127,25 @@ int acme_res_neworder(struct task *task, struct acme_ctx *ctx, char **errmsg)
                goto error;
        }
 
+       /* if the order already has a certificate URL, the validation was
+        * already done: skip the auth/challenge steps entirely */
+       ret = mjson_get_string(hc->res.buf.area, hc->res.buf.data, "$.certificate", trash.area, trash.size);
+       if (ret != -1) {
+               trash.data = ret;
+               istfree(&ctx->certificate);
+               ctx->certificate = istdup(ist2(trash.area, trash.data));
+               if (!isttest(ctx->certificate)) {
+                       memprintf(errmsg, "out of memory");
+                       goto error;
+               }
+               goto end;
+       }
+
        if (!isttest(ctx->order)) {
                memprintf(errmsg, "couldn't get an order Location during newOrder");
                goto error;
        }
+
        /* get the multiple authorizations URL and tokens */
        for (i = 0; ; i++) {
                struct acme_auth *auth;
@@ -2179,7 +2194,7 @@ int acme_res_neworder(struct task *task, struct acme_ctx *ctx, char **errmsg)
                memprintf(errmsg, "out of memory");
                goto error;
        }
-
+end:
        ret = 0;
 
 error:
@@ -2497,7 +2512,7 @@ re:
                                if (acme_res_neworder(task, ctx, &errmsg) != 0) {
                                        goto retry;
                                }
-                               st = ACME_AUTH;
+                               st = isttest(ctx->certificate) ? ACME_CERTIFICATE : ACME_AUTH;
                                goto nextreq;
                        }
                break;