DoH: implement support for multiples cert hashes

This commit is contained in:
Frank Denis 2018-01-31 18:16:54 +01:00
parent 22e63774a1
commit 7a8deebaf1
2 changed files with 34 additions and 17 deletions

View File

@ -232,21 +232,25 @@ func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, st
if tls == nil || !tls.HandshakeComplete { if tls == nil || !tls.HandshakeComplete {
return ServerInfo{}, errors.New("TLS handshake failed") 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 found := false
var wantedHash [32]byte var wantedHash [32]byte
copy(wantedHash[:], stamp.hash)
for _, cert := range tls.PeerCertificates { for _, cert := range tls.PeerCertificates {
h := sha256.Sum256(cert.RawTBSCertificate) h := sha256.Sum256(cert.RawTBSCertificate)
dlog.Debugf("Advertised cert: [%s] [%x]", cert.Subject, h) dlog.Debugf("Advertised cert: [%s] [%x]", cert.Subject, h)
if len(stamp.hash) == 32 && h == wantedHash { for _, hash := range stamp.hashes {
found = true if len(hash) == len(wantedHash) {
copy(wantedHash[:], hash)
if h == wantedHash {
found = true
break
}
}
}
if found {
break break
} }
} }
if len(stamp.hash) == 32 && !found { if !found && len(stamp.hashes) > 0 {
return ServerInfo{}, fmt.Errorf("Certificate hash [%x] not found for [%s]", wantedHash, name) return ServerInfo{}, fmt.Errorf("Certificate hash [%x] not found for [%s]", wantedHash, name)
} }
respBody, err := ioutil.ReadAll(resp.Body) respBody, err := ioutil.ReadAll(resp.Body)

View File

@ -37,7 +37,7 @@ func (stampProtoType *StampProtoType) String() string {
type ServerStamp struct { type ServerStamp struct {
serverAddrStr string serverAddrStr string
serverPk []uint8 serverPk []uint8
hash []uint8 hashes [][]uint8
providerName string providerName string
path string path string
props ServerInformalProperties props ServerInformalProperties
@ -127,7 +127,7 @@ func newDNSCryptServerStamp(bin []byte) (ServerStamp, error) {
// id(u8)=0x02 props addrLen(1) serverAddr hashLen(1) hash providerNameLen(1) providerName pathLen(1) path // id(u8)=0x02 props addrLen(1) serverAddr hashLen(1) hash providerNameLen(1) providerName pathLen(1) path
func newDoHServerStamp(bin []byte) (ServerStamp, error) { func newDoHServerStamp(bin []byte) (ServerStamp, error) {
stamp := ServerStamp{proto: StampProtoTypeDoH} stamp := ServerStamp{proto: StampProtoTypeDoH, hashes: [][]byte{}}
stamp.props = ServerInformalProperties(binary.LittleEndian.Uint64(bin[1:9])) stamp.props = ServerInformalProperties(binary.LittleEndian.Uint64(bin[1:9]))
binLen := len(bin) binLen := len(bin)
@ -144,13 +144,19 @@ func newDoHServerStamp(bin []byte) (ServerStamp, error) {
stamp.serverAddrStr = fmt.Sprintf("%s:%d", stamp.serverAddrStr, DefaultPort) stamp.serverAddrStr = fmt.Sprintf("%s:%d", stamp.serverAddrStr, DefaultPort)
} }
len = int(bin[pos]) for {
if len >= binLen-pos { vlen := int(bin[pos])
return stamp, errors.New("Invalid stamp") len = vlen & ^0x80
if len >= binLen-pos {
return stamp, errors.New("Invalid stamp")
}
pos++
stamp.hashes = append(stamp.hashes, bin[pos:pos+len])
pos += len
if vlen&0x80 != 0x80 {
break
}
} }
pos++
stamp.hash = bin[pos : pos+len]
pos += len
len = int(bin[pos]) len = int(bin[pos])
if len >= binLen-pos { if len >= binLen-pos {
@ -219,8 +225,15 @@ func (stamp *ServerStamp) dohString() string {
bin = append(bin, uint8(len(serverAddrStr))) bin = append(bin, uint8(len(serverAddrStr)))
bin = append(bin, []uint8(serverAddrStr)...) bin = append(bin, []uint8(serverAddrStr)...)
bin = append(bin, uint8(len(stamp.hash))) last := len(stamp.hashes) - 1
bin = append(bin, []uint8(stamp.hash)...) for i, hash := range stamp.hashes {
vlen := len(hash)
if i < last {
vlen |= 0x80
}
bin = append(bin, uint8(vlen))
bin = append(bin, hash...)
}
bin = append(bin, uint8(len(stamp.providerName))) bin = append(bin, uint8(len(stamp.providerName)))
bin = append(bin, []uint8(stamp.providerName)...) bin = append(bin, []uint8(stamp.providerName)...)