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 {
|
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)
|
||||||
|
|
|
@ -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)...)
|
||||||
|
|
Loading…
Reference in New Issue