Skip to content

Commit 231c89e

Browse files
Update draft-ietf-acme-dns-persist-00 support to 01 (#8725)
Draft-01 adds accounturi as a required field in the challenge object, rather than expecting the client to derive it. Add an AccountURI field to core.Challenge and populate it in prepChallengeForDisplay. Source the value from a new WFE config field, AccountURIPrefix, which must match the first entry of the VA's AccountURIPrefixes since that is the exact string the VA uses as the expected accounturi when validating the TXT record. Leave the new AccountURIPrefix config field optional so existing deployments upgrade without a config change. When AccountURIPrefix is unset, omit the accounturi field from the challenge object, which produces a draft-00-compatible challenge. Track making the field required in Production via TODO(#8724). Also, bump the remaining draft references/citations from 00 to 01. Fixes #8690
1 parent e188b4e commit 231c89e

12 files changed

Lines changed: 49 additions & 11 deletions

File tree

cmd/boulder-wfe2/main.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ type Config struct {
120120
// will differ in configuration for production and staging.
121121
LegacyKeyIDPrefix string `validate:"required,url"`
122122

123+
// AccountURIPrefix is used to construct the "accounturi" field of
124+
// dns-persist-01 challenges (e.g. "https://acme-v02.api.letsencrypt.org/acme/acct/").
125+
// MUST match the first entry of the VA's AccountURIPrefixes field.
126+
//
127+
// TODO(#8724): Once this field has been set in Production we can make
128+
// it required.
129+
AccountURIPrefix string `validate:"omitempty,url,endswith=/"`
130+
123131
// GoodKey is an embedded config stanza for the goodkey library.
124132
GoodKey goodkey.Config
125133

@@ -414,6 +422,7 @@ func main() {
414422
wfe.AllowOrigins = c.WFE.AllowOrigins
415423
wfe.DirectoryWebsite = c.WFE.DirectoryWebsite
416424
wfe.LegacyKeyIDPrefix = c.WFE.LegacyKeyIDPrefix
425+
wfe.AccountURIPrefix = c.WFE.AccountURIPrefix
417426

418427
if c.WFE.ListenAddress == "" {
419428
cmd.Fail("HTTP listen address is not configured")

core/objects.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,10 @@ type Challenge struct {
163163
// by all challenges except dns-persist-01.
164164
Token string `json:"token,omitempty"`
165165

166+
// AccountURI is the account URI the client includes during dns-persist-01
167+
// challenge validation.
168+
AccountURI string `json:"accounturi,omitempty"`
169+
166170
// IssuerDomainNames contains the list of issuer domain name values accepted
167171
// during dns-persist-01 challenge validation.
168172
IssuerDomainNames []string `json:"issuer-domain-names,omitempty"`

core/util.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ func Command() string {
402402
}
403403

404404
// NormalizeIssuerDomainName normalizes an RFC 8659 issuer-domain-name per the
405-
// recommended algorithm in draft-ietf-acme-dns-persist-00, Section 9.1.1:
405+
// recommended algorithm in draft-ietf-acme-dns-persist-01, Section 9.2:
406406
// case-fold to lowercase, apply Unicode NFC normalization, convert to A-label
407407
// (Punycode), remove any trailing dot, and ensure the result is no more than
408408
// 253 octets in length. If normalization fails, an error is returned.

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/aws/aws-sdk-go-v2/config v1.32.6
88
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3
99
github.com/aws/smithy-go v1.24.2
10-
github.com/eggsampler/acme/v3 v3.8.0
10+
github.com/eggsampler/acme/v3 v3.8.1
1111
github.com/go-jose/go-jose/v4 v4.1.4
1212
github.com/go-logr/stdr v1.2.2
1313
github.com/go-sql-driver/mysql v1.9.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
7272
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
7373
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
7474
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
75-
github.com/eggsampler/acme/v3 v3.8.0 h1:MNP3qVZnAl97l86CHkLdh/O9IBXdjL/AEy7c7QgdJj8=
76-
github.com/eggsampler/acme/v3 v3.8.0/go.mod h1:/qh0rKC/Dh7Jj+p4So7DbWmFNzC4dpcpK53r226Fhuo=
75+
github.com/eggsampler/acme/v3 v3.8.1 h1:HmpFs/CIdEXg2NCwSEFBd1BgSzzN8fPzwNZGzp0izrw=
76+
github.com/eggsampler/acme/v3 v3.8.1/go.mod h1:/qh0rKC/Dh7Jj+p4So7DbWmFNzC4dpcpK53r226Fhuo=
7777
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
7878
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
7979
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=

ra/ra.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2212,7 +2212,7 @@ func (ra *RegistrationAuthorityImpl) NewOrder(ctx context.Context, req *rapb.New
22122212
}
22132213

22142214
// Never reuse dns-persist-01 authorizations:
2215-
// draft-ietf-acme-dns-persist-00 section 7.8 caps the reuse period to
2215+
// draft-ietf-acme-dns-persist-01 section 7.8 caps the reuse period to
22162216
// the TXT record's TTL and BRs section 3.2.2.4.22 caps it at 10 days.
22172217
// Since TTLs are typically seconds to minutes, the TTL cap is likely to
22182218
// be the binding constraint; re-validating every order is simpler.

test/config-next/wfe2.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"directoryCAAIdentity": "happy-hacker-ca.invalid",
1212
"directoryWebsite": "https://github.com/letsencrypt/boulder",
1313
"legacyKeyIDPrefix": "http://boulder.service.consul:4000/reg/",
14+
"accountURIPrefix": "http://boulder.service.consul:4001/acme/acct/",
1415
"goodkey": {},
1516
"maxContactsPerRegistration": 3,
1617
"tls": {

va/dns_persist.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func parseDNSPersistRecord(record string) (string, *dnsPersistIssueValueParams,
109109
params.persistUntil = time.Unix(persistUntilVal, 0).UTC()
110110

111111
default:
112-
// Per draft-ietf-acme-dns-persist-00, "the server MUST ignore any
112+
// Per draft-ietf-acme-dns-persist-01, "the server MUST ignore any
113113
// parameter within the issue-value that has an unrecognized tag."
114114
continue
115115
}
@@ -125,10 +125,13 @@ func parseDNSPersistRecord(record string) (string, *dnsPersistIssueValueParams,
125125
// given time. It returns nil if the record authorizes issuance, or a
126126
// berrors.Unauthorized error for authorization failures.
127127
func checkDNSPersistRecord(params *dnsPersistIssueValueParams, validAccountURI string, wildcardName bool, validatedAt time.Time) error {
128+
// Per draft-ietf-acme-dns-persist-01 section 4.1, accounturi values are
129+
// compared using Simple String Comparison per RFC 3986 section 6.2.1, with
130+
// no case-folding or other normalization.
128131
if params.accountURI != validAccountURI {
129132
return berrors.UnauthorizedError("accounturi mismatch: expected %q, got %q", validAccountURI, params.accountURI)
130133
}
131-
// Per draft-ietf-acme-dns-persist-00, the policy parameter's tag and
134+
// Per draft-ietf-acme-dns-persist-01 section 4.1, the policy parameter's
132135
// defined values MUST be treated as case-insensitive. If the policy
133136
// parameter's value is anything other than "wildcard", the CA MUST proceed
134137
// as if the policy parameter were not present.

vendor/github.com/eggsampler/acme/v3/types.go

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/modules.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ github.com/cespare/xxhash/v2
146146
# github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f
147147
## explicit
148148
github.com/dgryski/go-rendezvous
149-
# github.com/eggsampler/acme/v3 v3.8.0
149+
# github.com/eggsampler/acme/v3 v3.8.1
150150
## explicit; go 1.11
151151
github.com/eggsampler/acme/v3
152152
# github.com/felixge/httpsnoop v1.0.4

0 commit comments

Comments
 (0)