feat: Support for dns-account-01 Challenge#8149
feat: Support for dns-account-01 Challenge#8149aarongable merged 32 commits intoletsencrypt:mainfrom
Conversation
1b542cc to
749bbf9
Compare
va/dns_account_test.go
Outdated
|
|
||
| // Assert the specific error type | ||
| prob := detailedError(err) | ||
| test.AssertEquals(t, prob.Type, probs.ConnectionProblem) |
There was a problem hiding this comment.
When accountURI is missing in validateDNSAccount01, it triggers an InternalServerError. The test TestDNSAccount01ValidationEmptyAccountURI verifies that the resulting client-facing error is mapped to ConnectionProblem (via the WFE mapping). Is ConnectionProblem the most suitable error type for the client, or should we consider a more specific internal error, such as MissingParameter, which could map to a different client-facing error (e.g., Malformed) if needed in the future? However, since the accountURI originates from the JWS, this error scenario should theoretically never occur.
There was a problem hiding this comment.
ConnectionProblem is what we use as a catch-all for all 500s during validation, so it's fine to test for that here. But I think it would be even better to drop the call to detailedError, and instead directly assert that the returned error is of type berrors.ServerInternal.
aarongable
left a comment
There was a problem hiding this comment.
Note to fellow reviewers: when reviewing, ignore the first two commits in this PR. They are copied from #8140.
Similar to that other PR, I mostly have small editorial suggestions, and one big overarching comment. This time I've left that comment on va.proto; take a look.
va/dns.go
Outdated
| // Compute the digest of the key authorization file | ||
| h := sha256.New() | ||
| h.Write([]byte(keyAuthorization)) | ||
| authorizedKeysDigest := base64.RawURLEncoding.EncodeToString(h.Sum(nil)) |
There was a problem hiding this comment.
This code can also be shared inside the new validateDNS helper method.
3b5bb07 to
2c19389
Compare
3f7cef6 to
2e16e53
Compare
eaba1cd to
c56430c
Compare
- Add `ChallengeTypeDNSAccount01` constant, `IsValid` update, and `RecordsSane` logic in `core/objects.go` - Add `DNSAccountChallenge01` function and handling in `core/challenges.go` - Add tests for the new challenge type in `core/core_test.go` and `core/objects_test.go` Implements core components for draft-ietf-acme-dns-account-label-00
- Add dns-account-01 challenge type to challTypeToUint map - Add dns-account-01 challenge type to uintToChallType map
…tions2 Extends the existing TestGetValidAuthorizations2 function to verify that authorizations with dns-account-01 challenges can be properly stored in and retrieved from the database.
This change consolidates configuration by removing the separate dnsAccountChallengeURIPrefix field and using the first element of the existing AccountURIPrefixes slice for dns-account-01 challenge validation. Changes: - Removed dnsAccountChallengeURIPrefix from va/config/config.go - Updated va/va.go to use accountURIPrefixes[0] for dns-account-01 challenges - Removed the field from NewValidationAuthorityImpl constructors - Updated test configurations to align with simplified logic - Added RegID to initial IsAnyNilOrZero validation check for robustness - Added documentation clarifying AccountURIPrefixes dual usage This addresses startup-time validation concerns since AccountURIPrefixes is already required to have at least one element, eliminating the risk of runtime failures due to missing configuration.
va/dns_account_test.go
Outdated
|
|
||
| // Assert the specific error type | ||
| prob := detailedError(err) | ||
| test.AssertEquals(t, prob.Type, probs.ConnectionProblem) |
There was a problem hiding this comment.
ConnectionProblem is what we use as a catch-all for all 500s during validation, so it's fine to test for that here. But I think it would be even better to drop the call to detailedError, and instead directly assert that the returned error is of type berrors.ServerInternal.
… very end of each JSON configuration to match config struct ordering and maintain consistency across service configs
Address pull request review comments: - Remove unnecessary info log in validateDNSAccount01 - Refactor validateDNS to take challengePrefix instead of full domain - Update spec reference to draft-ietf-acme-dns-account-label-01 - Remove unnecessary base32 padding configuration - Fix error message formatting to use %q instead of %s - Remove obsolete log line in validateDNS01 - Consolidate DNS validation logic for better maintainability
Convert individual test functions to table-driven tests and update error messages to follow Go style guide recommendations: - Consolidate separate test functions into single table-driven test - Update error messages to use Go Style Guide pattern - Use strings.Contains for robust error message checking - Fix error type assertion to use berrors.InternalServer directly - Remove unused constants and fix code formatting
Enhance integration tests based on pull request feedback: - Add environment variable checks for better test configuration reliability - Simplify test validation to focus on authorization status changes - Replace complex certificate generation flows with targeted validation - Remove unused crypto imports after test simplification - Change from t.Skip to t.Fatal for clearer error handling
The comment for `validateDNSAccount01` now references CAB/F Ballot SC-84, which allows the use of the `dns-account-01` challenge method. This provides better context for why this challenge type is implemented.
Was unidiomatic Co-authored-by: Aaron Gable <aaron@aarongable.com>
Co-authored-by: Aaron Gable <aaron@aarongable.com>
|
Amazing to see this merged. Is there a timeline for when this might appear in https://github.com/letsencrypt/pebble ? EDIT: My bad, looks like this has been in pebble for well over a year letsencrypt/pebble#435 |
| // Calculate the DNS prefix label based on the account URI | ||
| sha256sum := sha256.Sum256([]byte(accountURI)) | ||
| prefixBytes := sha256sum[0:10] // First 10 bytes | ||
| prefixLabel := strings.ToLower(base32.StdEncoding.EncodeToString(prefixBytes)) |
There was a problem hiding this comment.
I'm looking into using this validation method, and possibly this is a dumb question (😰 go is not my native language), but should this be removing padding = at the end of the output? Something like:
base32.StdEncoding.WithPadding(base32.NoPadding).EncodeToString(prefixBytes)There was a problem hiding this comment.
It's a reasonable question! But with 10 bytes of input, base32 will never need padding. This is because base32 uses one character to represent every 5 bits of input. Five bytes of input is 40 bits, which is evenly divisible by 5, so can be represented by eight base32 characters with no padding. Ten bytes of input is the same.
As documented in the Internet Draft, the 10-byte prefix length was chosen specifically because it has this property.
This pull request introduces support for the
dns-account-01challenge type as specified in draft-ietf-acme-dns-account-label-01 (https://datatracker.ietf.org/doc/draft-ietf-acme-dns-account-label/01/), building upon PR #8140 which introduced the core type definitions.Core Implementation:
policy/pa.gois updated to offer thedns-account-01challenge for both standard and wildcard domains.va/va.gois updated to recognizedns-account-01challenges and route them to the correct validation routine, passing the necessary account information.dns-account-01is implemented inva/dns.go, which calculates the account-specific DNS label and verifies the corresponding TXT record.Configuration:
PAConfigis updated to recognizedns-account-01as a valid challenge type which can be enabled in the PA config.DNSAccount01Enabledfeature flag is introduced infeatures/features.go. If this flag is not set, then the PA will not offer the new challenge type, and the VA will refuse to validate this challenge type.Testing:
test/integration/dns_account_01_test.go) has been added to cover various scenarios, including successful validation, incorrect TXT records, and wildcard domains.dns-account-01feature is both enabled and disabled.va/dns_account_test.go, specifically targeting thedns-account-01validation logic.bdns/mocks.go) has been updated to simulate variousdns-account-01responses.test/chall-test-srv-client/client.go) now includes methods for adding and removingdns-account-01challenge responses.These changes provide a complete implementation of the
dns-account-01challenge, including the necessary logic, configuration, and comprehensive testing to ensure its correctness and reliability.