Go100%

Commit activity

Last 12 weeks · 9 commits

Full graph →

Community health

2 of 6 standards met

Community profile →
42
✓README✓License○Contributing○Code of Conduct○Issue Template○PR Template

Recent PRs & issues

Active · 2 in progress · Last activity 1w ago
See all on GitHub →
SashaMIT

NewOrder marshaled the whole order. A new order then included expires as year 1, authorizations as null, and empty finalize and certificate strings. RFC 8555 section 7.4 says the new-order body is a subset of the order object. A strict server rejects those response fields as malformed. The request now sends identifiers, and notBefore, notAfter, profile, and replaces when they are set. The response is still decoded into the order. Fixes #59.

SashaMIT · 1w ago
breodoyo

This fixes an issue where could wait longer than the configured when the server returned a long value. The polling interval is now limited to the time remaining before expires. I also added a regression test using a short timeout and a longer value to make sure the polling doesn't block past the configured timeout. I ran , , and successfully.

breodoyo · 1w ago
feisar91

What happens is documented to block "until that happens or until the configured timeout" (, default 5 minutes). It can block much longer: the timeout is only checked at the top of the loop, and the wait inside the loop uses the server's uncapped. has the same pattern. https://github.com/mholt/acmez/blob/v3.1.7/acme/authorization.go#L184-L206 https://github.com/mholt/acmez/blob/v3.1.7/acme/order.go#L233-L243 https://github.com/mholt/acmez/blob/v3.1.7/acme/http.go#L383-L396 ( returns with no upper bound) We hit this with ZeroSSL, which answered polls on two pending authorizations with . acmez then sleeps for 24 hours instead of returning after 5 minutes. During that time the certificate isn't obtained, the issuance lock stays held (other cluster instances wait on it), and the solver's doesn't run, so the DNS-01 TXT records stay in the zone. A Caddy config reload cancels the context and ends the wait; without one, the wait runs for the full . Environment Caddy v2.11.4, certmagic v0.25.3, acmez v3.1.6 (this code is identical in v3.1.7) CA: ZeroSSL (), DNS-01 challenge 3-node Caddy cluster with shared Redis storage Evidence 1. The response that sets the wait (acmez debug log, logger ). These are the only two identifiers in the batch that never finalized ( and ): The other 10 authorizations in the same batch got and finalized about 17 s later. 2. The goroutines then sleep past ( on , about 6 minutes after the poll above): In an earlier occurrence for the same two identifiers (before debug logging was on), the same goroutines reached 92 minutes before a config reload cancelled them: Expected Once has elapsed, the poll returns "authorization took too long" (or "order took too long") regardless of , so the caller can clean up, deactivate the authorization, and retry. Suggested fix Cap each wait at the time remaining, before the in both loops: Related: #12 had a similar symptom (ZeroSSL hanging after "trying to solve challenge"), but a different cause: a certmagic solver mutex, fixed in caddyserver/certmagic@dce2de2.

feisar91 · 1w ago
Aalivexy

Fixes #63 fails with when the server is not ready to finalize at that moment, e.g. with asynchronous finalization (Let's Encrypt Staging). RFC 8555 §7.4 makes the order status the source of truth for the next action: means POST-as-GET the order, means submit a finalization request. now follows that: it refreshes the order after and re-submits the CSR while the order is . The first request is always a finalize request, even when the caller's cached status is stale. bounds only the polling that follows it. Note the behavior change: is no longer fatal. Against a server that keeps answering , the client re-submits the CSR every poll until elapses, relying on server-side idempotency. Tested with , including the Pebble integration tests ( covers the stale cached-status path).

Aalivexy · 1w ago
Aalivexy

When finalizing an order against a server that uses asynchronous finalization (e.g. Let's Encrypt Staging), can fail with: RFC 8555 §7.4: A request to finalize an order will result in error if the order is not in the "ready" state. In such cases, the server MUST return a 403 (Forbidden) error with a problem document of type "orderNotReady". The client should then send a POST-as-GET request to the order resource to obtain its current state. The status of the order will indicate what action the client should take (see below). For the order object returned by a successful finalize: "ready": The server agrees that the requirements have been fulfilled, and is awaiting finalization. Submit a finalization request. Current behavior in : 1. When finalize returns , the error is ignored but the order is never refreshed with a POST-as-GET, as §7.4 requires. Because returns early for without decoding the body into the , the local order remains the stale object. 2. treats as terminal and returns an error, so finalization aborts instead of re-submitting the finalize request. I'd be happy to open a PR for this.

Aalivexy · 1w ago
ropoctl

Summary treats a failed alternate chain download as fatal, and on failure returns — discarding the primary chain it already downloaded successfully. Per RFC 8555 §7.4.2 alternates are optional, so an advertised-but-unavailable alternate should not fail the whole issuance. This is currently reachable against Let's Encrypt production: during the ongoing YE/YR intermediate rollout, LE intermittently advertises a whose URL then answers . Impact The order is finalized and the certificate is issued — validation has already succeeded and the primary chain has already been fetched — but the client throws it away and reports failure. The caller then retries from scratch, burning a fresh order and a Let's Encrypt issuance quota slot each time, for a certificate that was already sitting in memory. Observed via Caddy 2.11.4 (acmez v3.1.6) obtaining a wildcard over DNS-01: Because it is intermittent, a subsequent retry usually succeeds — which makes this show up as random, unexplained issuance/renewal failures rather than a hard break. lego users are hitting the same LE behaviour (DirectAdmin forum thread). Root cause , in (v3.1.6): Two problems: 1. A failed alternate aborts the call, even though the spec says the server "MAY" provide alternates and "Clients can fetch these alternates and use their own heuristics to decide which is optimal." 2. It returns rather than , so the primary chain — already validated and downloaded — is lost. Note the primary-chain error path just above deliberately returns . Suggested fix Skip an alternate that cannot be retrieved and keep going. appends before it can fail on a nested fetch, so the partial entry needs rolling back: This preserves existing behaviour whenever alternates are healthy, and degrades to "use the chains we could actually get" when they are not. Callers that require a specific chain already express that through their own preference logic over the returned slice, and are free to reject the result if their preferred chain is absent. I am running this patch against LE production and it behaves as expected. Happy to send it as a PR, with a test covering the 404-on-advertised-alternate case, if the approach looks right. Versions acmez v3.1.6 Go 1.27.1, linux/amd64 CA: Let's Encrypt production ()

ropoctl · 3w ago
Structured data for AI agents

Repository: mholt/acmez. Description: Premier ACME client library for Go Stars: 354, Forks: 55. Primary language: Go. Languages: Go (100%). License: Apache-2.0. Homepage: https://pkg.go.dev/github.com/mholt/acmez/v3 Topics: acme, acme-client, lets-encrypt, rfc8555, rfc8737, tls. Latest release: v3.1.7 (3w ago). Open PRs: 2, open issues: 2. Last activity: 1w ago. Community health: 42%. Top contributors: mholt, datrixlab, hslatman, samuhvarta, Aalivexy, deining, arpitjain099, cpach, dtchanpura, n0cloud and others.