Validate DoH certificate hashes

This commit is contained in:
Frank Denis 2018-01-27 17:48:53 +01:00
parent 5e3e66ac71
commit 3c2cf2a1dc
1 changed files with 27 additions and 2 deletions

View File

@ -2,6 +2,7 @@ package main
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
@ -208,8 +209,11 @@ func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, st
preReq := &http.Request{
Method: "HEAD",
URL: url,
Close: false,
Host: stamp.providerName,
Header: map[string][]string{
"User-Agent": {"dnscrypt-proxy"},
},
Close: false,
Host: stamp.providerName,
}
if _, err := client.Do(preReq); err != nil {
return ServerInfo{}, err
@ -239,6 +243,27 @@ func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, st
} else if resp == nil {
return ServerInfo{}, errors.New("Webserver returned an error")
}
tls := resp.TLS
if tls == nil || !tls.HandshakeComplete {
return ServerInfo{}, errors.New("TLS handshake failed")
}
if len(stamp.hash) > 0 && len(stamp.hash) != 32 {
dlog.Criticalf("Unsupported certificate hash for [%s]: [%x]", name, stamp.hash)
}
found := false
var wantedHash [32]byte
copy(wantedHash[:], stamp.hash)
for _, cert := range tls.PeerCertificates {
h := sha256.Sum256(cert.RawTBSCertificate)
dlog.Debugf("Advertised cert: [%s] [%x]", cert.Subject, h)
if len(stamp.hash) == 32 && h == wantedHash {
found = true
break
}
}
if len(stamp.hash) == 32 && !found {
return ServerInfo{}, fmt.Errorf("Certificate hash [%x] not found for [%s]", wantedHash, name)
}
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return ServerInfo{}, err