Use dumb padding even for GET queries

Resolvers such as Cloudflare always add padding to DoH responses
Resolvers such as Google only do if the question had dumb padding
Resolvers such as Cisco blindly return a copy of the question's padding
Some resolvers don't return any padding no matter what's in the question
Finally, other resolvers return FORMERR

This is a mess. A bad design inherited from DoT, that didn't fix
anything from Unbound's original experiment.

Also, padding with zeros as recommended is a bad idea. When using
GET, escaping makes the actual padding size 3 times as big as needed.
This commit is contained in:
Frank Denis 2019-12-22 17:34:16 +01:00
parent 1585ede954
commit 5118ed21fd
2 changed files with 9 additions and 13 deletions

View File

@ -228,7 +228,8 @@ func addPaddingIfNoneFound(packet *[]byte, paddingLen int) *[]byte {
}
}
ext := new(dns.EDNS0_PADDING)
ext.Padding = make([]byte, paddingLen)
padding := []byte("dnscrypt-proxy.padding:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno")
ext.Padding = padding[:paddingLen]
edns0.Option = append(edns0.Option, ext)
paddedPacket, err := msg.Pack()
if err != nil {

View File

@ -301,7 +301,7 @@ func (xTransport *XTransport) resolveAndUpdateCache(host string) error {
return nil
}
func (xTransport *XTransport) Fetch(method string, url *url.URL, accept string, contentType string, body *[]byte, timeout time.Duration, padding *string) (*http.Response, time.Duration, error) {
func (xTransport *XTransport) Fetch(method string, url *url.URL, accept string, contentType string, body *[]byte, timeout time.Duration) (*http.Response, time.Duration, error) {
if timeout <= 0 {
timeout = xTransport.timeout
}
@ -320,9 +320,6 @@ func (xTransport *XTransport) Fetch(method string, url *url.URL, accept string,
url2 := *url
url2.RawQuery = qs.Encode()
url = &url2
if padding != nil {
body = addPaddingIfNoneFound(body, len(*padding))
}
}
host, _ := ExtractHostAndPort(url.Host, 0)
if xTransport.proxyDialer == nil && strings.HasSuffix(host, ".onion") {
@ -366,29 +363,27 @@ func (xTransport *XTransport) Fetch(method string, url *url.URL, accept string,
}
func (xTransport *XTransport) Get(url *url.URL, accept string, timeout time.Duration) (*http.Response, time.Duration, error) {
return xTransport.Fetch("GET", url, accept, "", nil, timeout, nil)
return xTransport.Fetch("GET", url, accept, "", nil, timeout)
}
func (xTransport *XTransport) Post(url *url.URL, accept string, contentType string, body *[]byte, timeout time.Duration, padding *string) (*http.Response, time.Duration, error) {
return xTransport.Fetch("POST", url, accept, contentType, body, timeout, padding)
func (xTransport *XTransport) Post(url *url.URL, accept string, contentType string, body *[]byte, timeout time.Duration) (*http.Response, time.Duration, error) {
return xTransport.Fetch("POST", url, accept, contentType, body, timeout)
}
func (xTransport *XTransport) DoHQuery(useGet bool, url *url.URL, body []byte, timeout time.Duration) (*http.Response, time.Duration, error) {
padLen := 63 - (len(body)+63)&63
padding := xTransport.makePad(padLen)
dataType := "application/dns-message"
paddedBody := addPaddingIfNoneFound(&body, padLen)
if useGet {
qs := url.Query()
qs.Add("ct", "")
encBody := base64.RawURLEncoding.EncodeToString(body)
encBody := base64.RawURLEncoding.EncodeToString(*paddedBody)
qs.Add("dns", encBody)
qs.Add("padding", *padding)
url2 := *url
url2.RawQuery = qs.Encode()
return xTransport.Get(&url2, dataType, timeout)
}
return xTransport.Post(url, dataType, dataType, &body, timeout, padding)
return xTransport.Post(url, dataType, dataType, paddedBody, timeout)
}
func (xTransport *XTransport) makePad(padLen int) *string {