DoHstamps

This commit is contained in:
Frank Denis 2018-01-26 20:38:31 +01:00
parent 3bbecdcde7
commit e16155e22a
2 changed files with 98 additions and 10 deletions

View File

@ -198,7 +198,7 @@ func (source *Source) parseV1(prefix string) ([]RegisteredServer, error) {
if strings.EqualFold(record[8], "yes") {
props |= ServerInformalPropertyNoLog
}
stamp, err := NewServerStampFromDNSCryptLegacy(serverAddrStr, serverPkStr, providerName, props)
stamp, err := NewDNSCryptServerStampFromLegacy(serverAddrStr, serverPkStr, providerName, props)
if err != nil {
return registeredServers, err
}

View File

@ -9,6 +9,7 @@ import (
"net"
"strings"
"github.com/jedisct1/dlog"
"golang.org/x/crypto/ed25519"
)
@ -23,13 +24,14 @@ const (
type ServerStamp struct {
serverAddrStr string
serverPk []uint8
hash []uint8
providerName string
path string
props ServerInformalProperties
proto StampProtoType
}
func NewServerStampFromDNSCryptLegacy(serverAddrStr string, serverPkStr string, providerName string, props ServerInformalProperties) (ServerStamp, error) {
func NewDNSCryptServerStampFromLegacy(serverAddrStr string, serverPkStr string, providerName string, props ServerInformalProperties) (ServerStamp, error) {
if net.ParseIP(serverAddrStr) != nil {
serverAddrStr = fmt.Sprintf("%s:%d", serverAddrStr, DefaultPort)
}
@ -46,22 +48,29 @@ func NewServerStampFromDNSCryptLegacy(serverAddrStr string, serverPkStr string,
}, nil
}
// id(u8) props addrLen(1) serverAddr pkStrlen(1) pkStr providerNameLen(1) providerName
func NewServerStampFromString(stampStr string) (ServerStamp, error) {
stamp := ServerStamp{}
if !strings.HasPrefix(stampStr, "sdns://") && !strings.HasPrefix(stampStr, "dnsc://") {
return stamp, errors.New("Stamps are expected to start with sdns://")
return ServerStamp{}, errors.New("Stamps are expected to start with sdns://")
}
bin, err := base64.RawURLEncoding.DecodeString(stampStr[7:])
if err != nil {
return stamp, err
return ServerStamp{}, err
}
if len(bin) < 24 {
return stamp, errors.New("Stamp is too short")
if len(bin) < 1 {
return ServerStamp{}, errors.New("Stamp is too short")
}
if bin[0] != uint8(StampProtoTypeDNSCrypt) {
return stamp, errors.New("Unsupported stamp version")
return newDNSCryptServerStamp(bin)
}
return ServerStamp{}, errors.New("Unsupported stamp version or protocol")
}
// id(u8)=0x02 props addrLen(1) serverAddr pkStrlen(1) pkStr providerNameLen(1) providerName
func newDNSCryptServerStamp(bin []byte) (ServerStamp, error) {
stamp := ServerStamp{}
if len(bin) < 24 {
return stamp, errors.New("Stamp is too short")
}
stamp.props = ServerInformalProperties(binary.LittleEndian.Uint64(bin[1:9]))
binLen := len(bin)
@ -97,7 +106,64 @@ func NewServerStampFromString(stampStr string) (ServerStamp, error) {
return stamp, nil
}
// id(u8)=0x02 props addrLen(1) serverAddr hashLen(1) hash providerNameLen(1) providerName pathLen(1) path
func newDoHServerStamp(bin []byte) (ServerStamp, error) {
stamp := ServerStamp{}
stamp.props = ServerInformalProperties(binary.LittleEndian.Uint64(bin[1:9]))
binLen := len(bin)
pos := 9
len := int(bin[pos])
if len >= binLen-pos {
return stamp, errors.New("Invalid stamp")
}
pos++
stamp.serverAddrStr = string(bin[pos : pos+len])
pos += len
len = int(bin[pos])
if len >= binLen-pos {
return stamp, errors.New("Invalid stamp")
}
pos++
stamp.hash = bin[pos : pos+len]
pos += len
len = int(bin[pos])
if len >= binLen-pos {
return stamp, errors.New("Invalid stamp")
}
pos++
stamp.providerName = string(bin[pos : pos+len])
pos += len
len = int(bin[pos])
if len >= binLen-pos {
return stamp, errors.New("Invalid stamp")
}
pos++
stamp.path = string(bin[pos : pos+len])
pos += len
if pos != binLen {
return stamp, errors.New("Invalid stamp (garbage after end)")
}
return stamp, nil
}
func (stamp *ServerStamp) String() string {
if stamp.proto == StampProtoTypeDNSCrypt {
return stamp.dnsCryptString()
} else if stamp.proto == StampProtoTypeDoH {
return stamp.dohString()
}
dlog.Fatal("Unsupported protocol")
return ""
}
func (stamp *ServerStamp) dnsCryptString() string {
bin := make([]uint8, 9)
bin[0] = uint8(StampProtoTypeDNSCrypt)
binary.LittleEndian.PutUint64(bin[1:9], uint64(stamp.props))
@ -115,3 +181,25 @@ func (stamp *ServerStamp) String() string {
return "sdns://" + str
}
func (stamp *ServerStamp) dohString() string {
bin := make([]uint8, 9)
bin[0] = uint8(StampProtoTypeDoH)
binary.LittleEndian.PutUint64(bin[1:9], uint64(stamp.props))
bin = append(bin, uint8(len(stamp.serverAddrStr)))
bin = append(bin, []uint8(stamp.serverAddrStr)...)
bin = append(bin, uint8(len(stamp.hash)))
bin = append(bin, []uint8(stamp.hash)...)
bin = append(bin, uint8(len(stamp.providerName)))
bin = append(bin, []uint8(stamp.providerName)...)
bin = append(bin, uint8(len(stamp.path)))
bin = append(bin, []uint8(stamp.path)...)
str := base64.RawURLEncoding.EncodeToString(bin)
return "sdns://" + str
}