diff --git a/core/challenges.go b/core/challenges.go index d5e7a8729..75a20373f 100644 --- a/core/challenges.go +++ b/core/challenges.go @@ -25,6 +25,11 @@ func TLSALPNChallenge01(token string) Challenge { return newChallenge(ChallengeTypeTLSALPN01, token) } +// DNSAccountChallenge01 constructs a dns-account-01 challenge. +func DNSAccountChallenge01(token string) Challenge { + return newChallenge(ChallengeTypeDNSAccount01, token) +} + // NewChallenge constructs a challenge of the given kind. It returns an // error if the challenge type is unrecognized. func NewChallenge(kind AcmeChallenge, token string) (Challenge, error) { @@ -35,6 +40,8 @@ func NewChallenge(kind AcmeChallenge, token string) (Challenge, error) { return DNSChallenge01(token), nil case ChallengeTypeTLSALPN01: return TLSALPNChallenge01(token), nil + case ChallengeTypeDNSAccount01: + return DNSAccountChallenge01(token), nil default: return Challenge{}, fmt.Errorf("unrecognized challenge type %q", kind) } diff --git a/core/core_test.go b/core/core_test.go index 889f9c9fe..1b7ff0cb5 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -32,12 +32,16 @@ func TestChallenges(t *testing.T) { dns01 := DNSChallenge01(token) test.AssertNotError(t, dns01.CheckPending(), "CheckConsistencyForClientOffer returned an error") + dnsAccount01 := DNSAccountChallenge01(token) + test.AssertNotError(t, dnsAccount01.CheckPending(), "CheckConsistencyForClientOffer returned an error") + tlsalpn01 := TLSALPNChallenge01(token) test.AssertNotError(t, tlsalpn01.CheckPending(), "CheckConsistencyForClientOffer returned an error") test.Assert(t, ChallengeTypeHTTP01.IsValid(), "Refused valid challenge") test.Assert(t, ChallengeTypeDNS01.IsValid(), "Refused valid challenge") test.Assert(t, ChallengeTypeTLSALPN01.IsValid(), "Refused valid challenge") + test.Assert(t, ChallengeTypeDNSAccount01.IsValid(), "Refused valid challenge") test.Assert(t, !AcmeChallenge("nonsense-71").IsValid(), "Accepted invalid challenge") } diff --git a/core/objects.go b/core/objects.go index ca4c06b2d..6f123b077 100644 --- a/core/objects.go +++ b/core/objects.go @@ -53,15 +53,16 @@ type AcmeChallenge string // These types are the available challenges const ( - ChallengeTypeHTTP01 = AcmeChallenge("http-01") - ChallengeTypeDNS01 = AcmeChallenge("dns-01") - ChallengeTypeTLSALPN01 = AcmeChallenge("tls-alpn-01") + ChallengeTypeHTTP01 = AcmeChallenge("http-01") + ChallengeTypeDNS01 = AcmeChallenge("dns-01") + ChallengeTypeTLSALPN01 = AcmeChallenge("tls-alpn-01") + ChallengeTypeDNSAccount01 = AcmeChallenge("dns-account-01") ) // IsValid tests whether the challenge is a known challenge func (c AcmeChallenge) IsValid() bool { switch c { - case ChallengeTypeHTTP01, ChallengeTypeDNS01, ChallengeTypeTLSALPN01: + case ChallengeTypeHTTP01, ChallengeTypeDNS01, ChallengeTypeTLSALPN01, ChallengeTypeDNSAccount01: return true default: return false @@ -228,7 +229,7 @@ func (ch Challenge) RecordsSane() bool { (ch.ValidationRecord[0].AddressUsed == netip.Addr{}) || len(ch.ValidationRecord[0].AddressesResolved) == 0 { return false } - case ChallengeTypeDNS01: + case ChallengeTypeDNS01, ChallengeTypeDNSAccount01: if len(ch.ValidationRecord) > 1 { return false } diff --git a/core/objects_test.go b/core/objects_test.go index 2d3194e63..302934a66 100644 --- a/core/objects_test.go +++ b/core/objects_test.go @@ -59,7 +59,7 @@ func TestChallengeSanityCheck(t *testing.T) { }`), &accountKey) test.AssertNotError(t, err, "Error unmarshaling JWK") - types := []AcmeChallenge{ChallengeTypeHTTP01, ChallengeTypeDNS01, ChallengeTypeTLSALPN01} + types := []AcmeChallenge{ChallengeTypeHTTP01, ChallengeTypeDNS01, ChallengeTypeTLSALPN01, ChallengeTypeDNSAccount01} for _, challengeType := range types { chall := Challenge{ Type: challengeType, @@ -152,6 +152,8 @@ func TestChallengeStringID(t *testing.T) { test.AssertEquals(t, ch.StringID(), "iFVMwA") ch.Type = ChallengeTypeHTTP01 test.AssertEquals(t, ch.StringID(), "0Gexug") + ch.Type = ChallengeTypeDNSAccount01 + test.AssertEquals(t, ch.StringID(), "8z2wSg") } func TestFindChallengeByType(t *testing.T) { diff --git a/go.mod b/go.mod index 3455eaec2..c0cf9f3df 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/aws/aws-sdk-go-v2/config v1.29.17 github.com/aws/aws-sdk-go-v2/service/s3 v1.83.0 github.com/aws/smithy-go v1.22.4 - github.com/eggsampler/acme/v3 v3.6.2-0.20250208073118-0466a0230941 + github.com/eggsampler/acme/v3 v3.6.2 github.com/go-jose/go-jose/v4 v4.1.0 github.com/go-logr/stdr v1.2.2 github.com/go-sql-driver/mysql v1.9.1 diff --git a/go.sum b/go.sum index 4ed2bdfc6..cd79d4585 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/eggsampler/acme/v3 v3.6.2-0.20250208073118-0466a0230941 h1:CnQwymLMJ3MSfjbZQ/bpaLfuXBZuM3LUgAHJ0gO/7d8= -github.com/eggsampler/acme/v3 v3.6.2-0.20250208073118-0466a0230941/go.mod h1:/qh0rKC/Dh7Jj+p4So7DbWmFNzC4dpcpK53r226Fhuo= +github.com/eggsampler/acme/v3 v3.6.2 h1:gvyZbQ92wNQLDASVftGpHEdFwPSfg0+17P0lLt09Tp8= +github.com/eggsampler/acme/v3 v3.6.2/go.mod h1:/qh0rKC/Dh7Jj+p4So7DbWmFNzC4dpcpK53r226Fhuo= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= diff --git a/sa/model.go b/sa/model.go index 83c5962ba..0fb9d18c8 100644 --- a/sa/model.go +++ b/sa/model.go @@ -416,15 +416,17 @@ func modelToOrder(om *orderModel) (*corepb.Order, error) { } var challTypeToUint = map[string]uint8{ - "http-01": 0, - "dns-01": 1, - "tls-alpn-01": 2, + "http-01": 0, + "dns-01": 1, + "tls-alpn-01": 2, + "dns-account-01": 3, } var uintToChallType = map[uint8]string{ 0: "http-01", 1: "dns-01", 2: "tls-alpn-01", + 3: "dns-account-01", } var identifierTypeToUint = map[string]uint8{ diff --git a/sa/sa_test.go b/sa/sa_test.go index d850b4421..b7c724638 100644 --- a/sa/sa_test.go +++ b/sa/sa_test.go @@ -2632,6 +2632,36 @@ func TestGetValidAuthorizations2(t *testing.T) { aaa = am.ID } + var dac int64 + { + tokenStr := core.NewToken() + token, err := base64.RawURLEncoding.DecodeString(tokenStr) + test.AssertNotError(t, err, "computing test authorization challenge token") + + profile := "test" + attempted := challTypeToUint[string(core.ChallengeTypeDNSAccount01)] + attemptedAt := fc.Now() + vr, _ := json.Marshal([]core.ValidationRecord{}) + + am := authzModel{ + IdentifierType: identifierTypeToUint[string(identifier.TypeDNS)], + IdentifierValue: "aaa", + RegistrationID: 3, + CertificateProfileName: &profile, + Status: statusToUint[core.StatusValid], + Expires: fc.Now().Add(24 * time.Hour), + Challenges: 1 << challTypeToUint[string(core.ChallengeTypeDNSAccount01)], + Attempted: &attempted, + AttemptedAt: &attemptedAt, + Token: token, + ValidationError: nil, + ValidationRecord: vr, + } + err = sa.dbMap.Insert(context.Background(), &am) + test.AssertNotError(t, err, "failed to insert valid authz with dns-account-01") + dac = am.ID + } + for _, tc := range []struct { name string regID int64 @@ -2648,6 +2678,14 @@ func TestGetValidAuthorizations2(t *testing.T) { validUntil: fc.Now().Add(time.Hour), wantIDs: []int64{aaa}, }, + { + name: "happy path, dns-account-01 challenge", + regID: 3, + identifiers: []*corepb.Identifier{identifier.NewDNS("aaa").ToProto()}, + profile: "test", + validUntil: fc.Now().Add(time.Hour), + wantIDs: []int64{dac}, + }, { name: "different identifier type", regID: 1, diff --git a/vendor/github.com/eggsampler/acme/v3/Makefile b/vendor/github.com/eggsampler/acme/v3/Makefile index c0f3c920f..1f56d9b9b 100644 --- a/vendor/github.com/eggsampler/acme/v3/Makefile +++ b/vendor/github.com/eggsampler/acme/v3/Makefile @@ -60,10 +60,11 @@ boulder_setup: -git clone --depth 1 https://github.com/letsencrypt/boulder.git $(BOULDER_PATH) (cd $(BOULDER_PATH); git checkout -f main && git reset --hard HEAD && git pull -q) make boulder_stop + (cd $(BOULDER_PATH); docker compose run --rm bsetup) # runs an instance of boulder boulder_start: - docker-compose -f $(BOULDER_PATH)/docker-compose.yml -f docker-compose.boulder-temp.yml up -d + docker-compose -f $(BOULDER_PATH)/docker-compose.yml -f $(BOULDER_PATH)/docker-compose.next.yml -f docker-compose.boulder-temp.yml up -d # waits until boulder responds boulder_wait: diff --git a/vendor/modules.txt b/vendor/modules.txt index 532c0b27b..1c654eff2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -140,7 +140,7 @@ github.com/cespare/xxhash/v2 # github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f ## explicit github.com/dgryski/go-rendezvous -# github.com/eggsampler/acme/v3 v3.6.2-0.20250208073118-0466a0230941 +# github.com/eggsampler/acme/v3 v3.6.2 ## explicit; go 1.11 github.com/eggsampler/acme/v3 # github.com/felixge/httpsnoop v1.0.4