DoH: implement support for multiples cert hashes
This commit is contained in:
parent
22e63774a1
commit
7a8deebaf1
|
@ -232,21 +232,25 @@ func (serversInfo *ServersInfo) fetchDoHServerInfo(proxy *Proxy, name string, st
|
|||
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 {
|
||||
for _, hash := range stamp.hashes {
|
||||
if len(hash) == len(wantedHash) {
|
||||
copy(wantedHash[:], hash)
|
||||
if h == wantedHash {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(stamp.hash) == 32 && !found {
|
||||
}
|
||||
if found {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found && len(stamp.hashes) > 0 {
|
||||
return ServerInfo{}, fmt.Errorf("Certificate hash [%x] not found for [%s]", wantedHash, name)
|
||||
}
|
||||
respBody, err := ioutil.ReadAll(resp.Body)
|
||||
|
|
|
@ -37,7 +37,7 @@ func (stampProtoType *StampProtoType) String() string {
|
|||
type ServerStamp struct {
|
||||
serverAddrStr string
|
||||
serverPk []uint8
|
||||
hash []uint8
|
||||
hashes [][]uint8
|
||||
providerName string
|
||||
path string
|
||||
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
|
||||
|
||||
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]))
|
||||
binLen := len(bin)
|
||||
|
@ -144,13 +144,19 @@ func newDoHServerStamp(bin []byte) (ServerStamp, error) {
|
|||
stamp.serverAddrStr = fmt.Sprintf("%s:%d", stamp.serverAddrStr, DefaultPort)
|
||||
}
|
||||
|
||||
len = int(bin[pos])
|
||||
for {
|
||||
vlen := int(bin[pos])
|
||||
len = vlen & ^0x80
|
||||
if len >= binLen-pos {
|
||||
return stamp, errors.New("Invalid stamp")
|
||||
}
|
||||
pos++
|
||||
stamp.hash = bin[pos : pos+len]
|
||||
stamp.hashes = append(stamp.hashes, bin[pos:pos+len])
|
||||
pos += len
|
||||
if vlen&0x80 != 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
len = int(bin[pos])
|
||||
if len >= binLen-pos {
|
||||
|
@ -219,8 +225,15 @@ func (stamp *ServerStamp) dohString() string {
|
|||
bin = append(bin, uint8(len(serverAddrStr)))
|
||||
bin = append(bin, []uint8(serverAddrStr)...)
|
||||
|
||||
bin = append(bin, uint8(len(stamp.hash)))
|
||||
bin = append(bin, []uint8(stamp.hash)...)
|
||||
last := len(stamp.hashes) - 1
|
||||
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(stamp.providerName)...)
|
||||
|
|
Loading…
Reference in New Issue