Skip to content

Commit 473b405

Browse files
authored
feat: Add core definitions for dns-account-01 (#8140)
## Summary This PR introduces the foundational components required to support the `dns-account-01` challenge type, as specified in draft-ietf-acme-dns-account-label-00: https://datatracker.ietf.org/doc/draft-ietf-acme-dns-account-label/. It focuses only on core definitions and SA support. PA/VA/RA logic will be in a follow-up change. Core Definitions & Logic: - //core/objects.go: Added `ChallengeTypeDNSAccount01` constant and updated validation methods - //core/challenges.go: Added `DNSAccountChallenge01` constructor and factory support Storage Authority (SA) Support: - //sa/model.go: Added `dns-account-01` to challenge type mappings Testing: - //core/*_test.go: Basic definition and validation tests - //sa/sa_test.go: Database round-trip tests for `dns-account-01` challenges Dependencies: - Updated github.com/eggsampler/acme/v3 to release version v3.6.2
1 parent 440c695 commit 473b405

File tree

10 files changed

+69
-14
lines changed

10 files changed

+69
-14
lines changed

core/challenges.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ func TLSALPNChallenge01(token string) Challenge {
2525
return newChallenge(ChallengeTypeTLSALPN01, token)
2626
}
2727

28+
// DNSAccountChallenge01 constructs a dns-account-01 challenge.
29+
func DNSAccountChallenge01(token string) Challenge {
30+
return newChallenge(ChallengeTypeDNSAccount01, token)
31+
}
32+
2833
// NewChallenge constructs a challenge of the given kind. It returns an
2934
// error if the challenge type is unrecognized.
3035
func NewChallenge(kind AcmeChallenge, token string) (Challenge, error) {
@@ -35,6 +40,8 @@ func NewChallenge(kind AcmeChallenge, token string) (Challenge, error) {
3540
return DNSChallenge01(token), nil
3641
case ChallengeTypeTLSALPN01:
3742
return TLSALPNChallenge01(token), nil
43+
case ChallengeTypeDNSAccount01:
44+
return DNSAccountChallenge01(token), nil
3845
default:
3946
return Challenge{}, fmt.Errorf("unrecognized challenge type %q", kind)
4047
}

core/core_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,16 @@ func TestChallenges(t *testing.T) {
3232
dns01 := DNSChallenge01(token)
3333
test.AssertNotError(t, dns01.CheckPending(), "CheckConsistencyForClientOffer returned an error")
3434

35+
dnsAccount01 := DNSAccountChallenge01(token)
36+
test.AssertNotError(t, dnsAccount01.CheckPending(), "CheckConsistencyForClientOffer returned an error")
37+
3538
tlsalpn01 := TLSALPNChallenge01(token)
3639
test.AssertNotError(t, tlsalpn01.CheckPending(), "CheckConsistencyForClientOffer returned an error")
3740

3841
test.Assert(t, ChallengeTypeHTTP01.IsValid(), "Refused valid challenge")
3942
test.Assert(t, ChallengeTypeDNS01.IsValid(), "Refused valid challenge")
4043
test.Assert(t, ChallengeTypeTLSALPN01.IsValid(), "Refused valid challenge")
44+
test.Assert(t, ChallengeTypeDNSAccount01.IsValid(), "Refused valid challenge")
4145
test.Assert(t, !AcmeChallenge("nonsense-71").IsValid(), "Accepted invalid challenge")
4246
}
4347

core/objects.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,16 @@ type AcmeChallenge string
5353

5454
// These types are the available challenges
5555
const (
56-
ChallengeTypeHTTP01 = AcmeChallenge("http-01")
57-
ChallengeTypeDNS01 = AcmeChallenge("dns-01")
58-
ChallengeTypeTLSALPN01 = AcmeChallenge("tls-alpn-01")
56+
ChallengeTypeHTTP01 = AcmeChallenge("http-01")
57+
ChallengeTypeDNS01 = AcmeChallenge("dns-01")
58+
ChallengeTypeTLSALPN01 = AcmeChallenge("tls-alpn-01")
59+
ChallengeTypeDNSAccount01 = AcmeChallenge("dns-account-01")
5960
)
6061

6162
// IsValid tests whether the challenge is a known challenge
6263
func (c AcmeChallenge) IsValid() bool {
6364
switch c {
64-
case ChallengeTypeHTTP01, ChallengeTypeDNS01, ChallengeTypeTLSALPN01:
65+
case ChallengeTypeHTTP01, ChallengeTypeDNS01, ChallengeTypeTLSALPN01, ChallengeTypeDNSAccount01:
6566
return true
6667
default:
6768
return false
@@ -228,7 +229,7 @@ func (ch Challenge) RecordsSane() bool {
228229
(ch.ValidationRecord[0].AddressUsed == netip.Addr{}) || len(ch.ValidationRecord[0].AddressesResolved) == 0 {
229230
return false
230231
}
231-
case ChallengeTypeDNS01:
232+
case ChallengeTypeDNS01, ChallengeTypeDNSAccount01:
232233
if len(ch.ValidationRecord) > 1 {
233234
return false
234235
}

core/objects_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestChallengeSanityCheck(t *testing.T) {
5959
}`), &accountKey)
6060
test.AssertNotError(t, err, "Error unmarshaling JWK")
6161

62-
types := []AcmeChallenge{ChallengeTypeHTTP01, ChallengeTypeDNS01, ChallengeTypeTLSALPN01}
62+
types := []AcmeChallenge{ChallengeTypeHTTP01, ChallengeTypeDNS01, ChallengeTypeTLSALPN01, ChallengeTypeDNSAccount01}
6363
for _, challengeType := range types {
6464
chall := Challenge{
6565
Type: challengeType,
@@ -152,6 +152,8 @@ func TestChallengeStringID(t *testing.T) {
152152
test.AssertEquals(t, ch.StringID(), "iFVMwA")
153153
ch.Type = ChallengeTypeHTTP01
154154
test.AssertEquals(t, ch.StringID(), "0Gexug")
155+
ch.Type = ChallengeTypeDNSAccount01
156+
test.AssertEquals(t, ch.StringID(), "8z2wSg")
155157
}
156158

157159
func TestFindChallengeByType(t *testing.T) {

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.29.17
88
github.com/aws/aws-sdk-go-v2/service/s3 v1.83.0
99
github.com/aws/smithy-go v1.22.4
10-
github.com/eggsampler/acme/v3 v3.6.2-0.20250208073118-0466a0230941
10+
github.com/eggsampler/acme/v3 v3.6.2
1111
github.com/go-jose/go-jose/v4 v4.1.0
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
@@ -70,8 +70,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
7070
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
7171
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
7272
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
73-
github.com/eggsampler/acme/v3 v3.6.2-0.20250208073118-0466a0230941 h1:CnQwymLMJ3MSfjbZQ/bpaLfuXBZuM3LUgAHJ0gO/7d8=
74-
github.com/eggsampler/acme/v3 v3.6.2-0.20250208073118-0466a0230941/go.mod h1:/qh0rKC/Dh7Jj+p4So7DbWmFNzC4dpcpK53r226Fhuo=
73+
github.com/eggsampler/acme/v3 v3.6.2 h1:gvyZbQ92wNQLDASVftGpHEdFwPSfg0+17P0lLt09Tp8=
74+
github.com/eggsampler/acme/v3 v3.6.2/go.mod h1:/qh0rKC/Dh7Jj+p4So7DbWmFNzC4dpcpK53r226Fhuo=
7575
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
7676
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
7777
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=

sa/model.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -416,15 +416,17 @@ func modelToOrder(om *orderModel) (*corepb.Order, error) {
416416
}
417417

418418
var challTypeToUint = map[string]uint8{
419-
"http-01": 0,
420-
"dns-01": 1,
421-
"tls-alpn-01": 2,
419+
"http-01": 0,
420+
"dns-01": 1,
421+
"tls-alpn-01": 2,
422+
"dns-account-01": 3,
422423
}
423424

424425
var uintToChallType = map[uint8]string{
425426
0: "http-01",
426427
1: "dns-01",
427428
2: "tls-alpn-01",
429+
3: "dns-account-01",
428430
}
429431

430432
var identifierTypeToUint = map[string]uint8{

sa/sa_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,6 +2632,36 @@ func TestGetValidAuthorizations2(t *testing.T) {
26322632
aaa = am.ID
26332633
}
26342634

2635+
var dac int64
2636+
{
2637+
tokenStr := core.NewToken()
2638+
token, err := base64.RawURLEncoding.DecodeString(tokenStr)
2639+
test.AssertNotError(t, err, "computing test authorization challenge token")
2640+
2641+
profile := "test"
2642+
attempted := challTypeToUint[string(core.ChallengeTypeDNSAccount01)]
2643+
attemptedAt := fc.Now()
2644+
vr, _ := json.Marshal([]core.ValidationRecord{})
2645+
2646+
am := authzModel{
2647+
IdentifierType: identifierTypeToUint[string(identifier.TypeDNS)],
2648+
IdentifierValue: "aaa",
2649+
RegistrationID: 3,
2650+
CertificateProfileName: &profile,
2651+
Status: statusToUint[core.StatusValid],
2652+
Expires: fc.Now().Add(24 * time.Hour),
2653+
Challenges: 1 << challTypeToUint[string(core.ChallengeTypeDNSAccount01)],
2654+
Attempted: &attempted,
2655+
AttemptedAt: &attemptedAt,
2656+
Token: token,
2657+
ValidationError: nil,
2658+
ValidationRecord: vr,
2659+
}
2660+
err = sa.dbMap.Insert(context.Background(), &am)
2661+
test.AssertNotError(t, err, "failed to insert valid authz with dns-account-01")
2662+
dac = am.ID
2663+
}
2664+
26352665
for _, tc := range []struct {
26362666
name string
26372667
regID int64
@@ -2648,6 +2678,14 @@ func TestGetValidAuthorizations2(t *testing.T) {
26482678
validUntil: fc.Now().Add(time.Hour),
26492679
wantIDs: []int64{aaa},
26502680
},
2681+
{
2682+
name: "happy path, dns-account-01 challenge",
2683+
regID: 3,
2684+
identifiers: []*corepb.Identifier{identifier.NewDNS("aaa").ToProto()},
2685+
profile: "test",
2686+
validUntil: fc.Now().Add(time.Hour),
2687+
wantIDs: []int64{dac},
2688+
},
26512689
{
26522690
name: "different identifier type",
26532691
regID: 1,

vendor/github.com/eggsampler/acme/v3/Makefile

Lines changed: 2 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
@@ -140,7 +140,7 @@ github.com/cespare/xxhash/v2
140140
# github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f
141141
## explicit
142142
github.com/dgryski/go-rendezvous
143-
# github.com/eggsampler/acme/v3 v3.6.2-0.20250208073118-0466a0230941
143+
# github.com/eggsampler/acme/v3 v3.6.2
144144
## explicit; go 1.11
145145
github.com/eggsampler/acme/v3
146146
# github.com/felixge/httpsnoop v1.0.4

0 commit comments

Comments
 (0)