-
-
Notifications
You must be signed in to change notification settings - Fork 594
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix dns value encoding to be compliant with acme v01 spec #1295
Conversation
"The record provisioned to the DNS is the base64url encoding of this digest"
f10d7af
to
ab31d1c
Compare
ab31d1c
to
8fa7b01
Compare
Nice catch, thanks! |
Actually, I realized this problem should be caught by more than just the integration test. Can you check if there's an appropriate unittest for this code path? If so, please fix it to make sure it catches this bug. If not, could you write one? Thanks, |
I think I saw some unit test for dns01 but it was marked as 'coverage' only test since it relies on network data.
|
Thank for this change! Please write a unit test. It's important for the long health of this project and the DNS challenge itself. Integration tests won't cover all the possibilities now or in the future as the project grows. On top of that, deploys to production are going to be, at most, very rare and narrow in their purview over the holidays. The DNS challenge is very unlikely to be turned in prod on anytime before January. But even if that were not the case, it's important for us to take a deliberate, calm path of forward momentum. We're helping encrypt the entire web! A big deal! Anyway, thanks again for handling this! |
Your schedule, of course, is not ours. We may beat you to having time to fix this with a test in place. |
1ce7298
to
79a7db4
Compare
now with some test You should update the |
LGTM Thank you! |
merged with master |
@@ -425,7 +426,7 @@ func (va *ValidationAuthorityImpl) validateDNS01(identifier core.AcmeIdentifier, | |||
// Compute the digest of the key authorization file | |||
h := sha256.New() | |||
h.Write([]byte(challenge.KeyAuthorization.String())) | |||
authorizedKeysDigest := hex.EncodeToString(h.Sum(nil)) | |||
authorizedKeysDigest := base64.RawURLEncoding.EncodeToString(h.Sum(nil)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
base64.RawURLEncoding
omits the pad character(s). This should use base64.URLEncoding
to be really compliant with the acme spec.
According to acme v01 spec the "(t)he record provisioned to the DNS is the base64url encoding of [the SHA-256 digest]." "base64url" encoding is specified in RFC 4648 section 5 and is subject to the section 3.2 provisions concerning padding of encoded data:
The acme 01 specification does not state to omit pad characters in the dns value, accordingly a compliant implementation of the dns-01 challenge has to use padded base64url encoded data when provisioning/validating the TXT record. Since boulder does a byte-to-byte comparison of the encoded data this is critical! |
The spec says: "For Base64 encoding, we use the variant defined in [RFC7515]. The important features of this encoding are (1) that it uses the URL-safe character set, and (2) that "=" padding characters are stripped." I think it also applies for dns value But perhaps the best solution would be to accept both variants ?
|
+1 for being tolerant to both. |
@r0ro I don't see how that provision applies to encoding of key authorization resources. When read in context it specifies the encoding of JSON message data: "Since JSON is a text-based format, binary fields are Base64-encoded. For Base64 encoding, we use the variant defined in {{RFC7515}}. The important features of this encoding are (1) that it uses the URL-safe character set, and (2) that "=" padding characters are stripped." But i see how the spec leaves room for interpretation in that regard. And i agree that the safest solution is to accept both forms. |
No, we will only allow the one that lines up with all of the other challenges as implemented. The spec is in draft and can be clarified and Postel's Law is a quick way to build insecure software. |
so the current pull request is ok ? |
@@ -37,6 +37,12 @@ func (mock *DNSResolver) LookupTXT(hostname string) ([]string, error) { | |||
if hostname == "_acme-challenge.servfail.com" { | |||
return nil, fmt.Errorf("SERVFAIL") | |||
} | |||
if hostname == "_acme-challenge.good-dns01.com" { | |||
// base64(sha254("LoqXcYV8q5ONbJQxbmR7SCTNo3tiAXDfowyjxAjEuX0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*sha256
Basically LGTM. There's a small comment typo, and this needs update to latest master anyhow. |
Fix dns value encoding to be compliant with acme v01 spec
Don't forget to update the TXT entry for |
|
Update is rolling out; sorry I missed this. |
"The record provisioned to the DNS is the base64url encoding of this digest"