1
0
Fork 0
mirror of https://github.com/SamTherapy/dnscrypt.git synced 2024-07-02 21:56:06 +00:00

fix dependency

This commit is contained in:
Andrey Meshkov 2018-12-25 01:39:34 +03:00
parent a12971f563
commit 227ce1fa8f
6 changed files with 178 additions and 20 deletions

View file

@ -11,8 +11,8 @@ import (
"strings"
"time"
"github.com/ameshkov/dnscrypt/xsecretbox"
"github.com/jedisct1/go-dnsstamps"
"github.com/jedisct1/xsecretbox"
"github.com/miekg/dns"
"golang.org/x/crypto/curve25519"
"golang.org/x/crypto/ed25519"
@ -51,7 +51,7 @@ const (
// <min-query-len> is a variable length, initially set to 256 bytes, and
// must be a multiple of 64 bytes. (see https://dnscrypt.info/protocol)
// Some servers do not work if padded length is less than 256. Example: Quad9
minUdpQuestionSize = 256
minUDPQuestionSize = 256
)
// Client contains parameters for a DNSCrypt client
@ -198,9 +198,9 @@ func (c *Client) ExchangeConn(m *dns.Msg, s *ServerInfo, conn net.Conn) (*dns.Ms
return nil, 0, err
}
} else {
length, err := conn.Read(encryptedResponse)
if err != nil {
return nil, 0, err
length, readErr := conn.Read(encryptedResponse)
if readErr != nil {
return nil, 0, readErr
}
encryptedResponse = encryptedResponse[:length]
}
@ -315,7 +315,7 @@ func (s *ServerInfo) encrypt(packet []byte) (encrypted []byte, clientNonce []byt
minQuestionSize := queryOverhead + len(packet)
if s.Proto == "udp" {
minQuestionSize = max(minUdpQuestionSize, minQuestionSize)
minQuestionSize = max(minUDPQuestionSize, minQuestionSize)
} else {
var xpad [1]byte
rand.Read(xpad[:])
@ -378,7 +378,6 @@ func (s *ServerInfo) decrypt(encrypted []byte, nonce []byte) ([]byte, error) {
}
func txtToCertInfo(answerRr dns.RR, serverInfo *ServerInfo) (CertInfo, error) {
now := uint32(time.Now().Unix())
certInfo := CertInfo{CryptoConstruction: UndefinedConstruction}

View file

@ -11,7 +11,6 @@ import (
)
func TestParseStamp(t *testing.T) {
// Google DoH
stampStr := "sdns://AgUAAAAAAAAAAAAOZG5zLmdvb2dsZS5jb20NL2V4cGVyaW1lbnRhbA"
stamp, err := dnsstamps.NewServerStampFromString(stampStr)
@ -43,7 +42,6 @@ func TestParseStamp(t *testing.T) {
}
func TestInvalidStamp(t *testing.T) {
client := Client{}
_, _, err := client.Dial("sdns://AQIAAAAAAAAAFDE")
if err == nil {
@ -52,7 +50,6 @@ func TestInvalidStamp(t *testing.T) {
}
func TestTimeoutOnDialError(t *testing.T) {
// AdGuard DNS pointing to a wrong IP
stampStr := "sdns://AQIAAAAAAAAADDguOC44Ljg6NTQ0MyDRK0fyUtzywrv4mRCG6vec5EldixbIoMQyLlLKPzkIcyIyLmRuc2NyeXB0LmRlZmF1bHQubnMxLmFkZ3VhcmQuY29t"
client := Client{Timeout: 300 * time.Millisecond}
@ -68,7 +65,6 @@ func TestTimeoutOnDialError(t *testing.T) {
}
func TestTimeoutOnDialExchange(t *testing.T) {
// AdGuard DNS
stampStr := "sdns://AQIAAAAAAAAAFDE3Ni4xMDMuMTMwLjEzMDo1NDQzINErR_JS3PLCu_iZEIbq95zkSV2LFsigxDIuUso_OQhzIjIuZG5zY3J5cHQuZGVmYXVsdC5uczEuYWRndWFyZC5jb20"
client := Client{Timeout: 300 * time.Millisecond}
@ -100,7 +96,6 @@ func TestTimeoutOnDialExchange(t *testing.T) {
}
func TestDnsCryptResolver(t *testing.T) {
stamps := []struct {
stampStr string
}{
@ -135,14 +130,14 @@ func TestDnsCryptResolver(t *testing.T) {
}
for _, test := range stamps {
checkDnsCryptServer(t, test.stampStr, "")
checkDnsCryptServer(t, test.stampStr, "tcp")
t.Run(test.stampStr, func(t *testing.T) {
checkDNSCryptServer(t, test.stampStr, "")
checkDNSCryptServer(t, test.stampStr, "tcp")
})
}
}
func checkDnsCryptServer(t *testing.T, stampStr string, proto string) {
func checkDNSCryptServer(t *testing.T, stampStr string, proto string) {
client := Client{Proto: proto, Timeout: 10 * time.Second, AdjustPayloadSize: true}
serverInfo, rtt, err := client.Dial(stampStr)
if err != nil {

5
go.mod
View file

@ -1,10 +1,9 @@
module github.com/ameshkov/dnscrypt
require (
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 // indirect
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da
github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635
github.com/jedisct1/go-dnsstamps v0.0.0-20180418170050-1e4999280f86
github.com/jedisct1/xsecretbox v0.0.0-20180508184500-7a679c0bcd9a
github.com/miekg/dns v1.1.1
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9
golang.org/x/net v0.0.0-20181213202711-891ebc4b82d6 // indirect

24
xsecretbox/sharedkey.go Normal file
View file

@ -0,0 +1,24 @@
package xsecretbox
import (
"errors"
"github.com/aead/chacha20/chacha"
"golang.org/x/crypto/curve25519"
)
// SharedKey computes a shared secret compatible with the one used by `crypto_box_xchacha20poly1305``
func SharedKey(secretKey [32]byte, publicKey [32]byte) ([32]byte, error) {
var sharedKey [32]byte
curve25519.ScalarMult(&sharedKey, &secretKey, &publicKey)
c := byte(0)
for i := 0; i < 32; i++ {
c |= sharedKey[i]
}
if c == 0 {
return sharedKey, errors.New("weak public key")
}
var nonce [16]byte
chacha.HChaCha20(&sharedKey, &nonce, &sharedKey)
return sharedKey, nil
}

115
xsecretbox/xsecretbox.go Normal file
View file

@ -0,0 +1,115 @@
package xsecretbox
import (
"crypto/subtle"
"errors"
"github.com/aead/chacha20/chacha"
"github.com/aead/poly1305"
)
const (
// KeySize is what the name suggests
KeySize = 32
// NonceSize is what the name suggests
NonceSize = 24
// TagSize is what the name suggests
TagSize = 16
)
// Seal does what the name suggests
func Seal(out, nonce, message, key []byte) []byte {
if len(nonce) != NonceSize {
panic("unsupported nonce size")
}
if len(key) != KeySize {
panic("unsupported key size")
}
var firstBlock [64]byte
cipher, _ := chacha.NewCipher(nonce, key, 20)
cipher.XORKeyStream(firstBlock[:], firstBlock[:])
var polyKey [32]byte
copy(polyKey[:], firstBlock[:32])
ret, out := sliceForAppend(out, TagSize+len(message))
firstMessageBlock := message
if len(firstMessageBlock) > 32 {
firstMessageBlock = firstMessageBlock[:32]
}
tagOut := out
out = out[poly1305.TagSize:]
for i, x := range firstMessageBlock {
out[i] = firstBlock[32+i] ^ x
}
message = message[len(firstMessageBlock):]
ciphertext := out
out = out[len(firstMessageBlock):]
cipher.SetCounter(1)
cipher.XORKeyStream(out, message)
var tag [TagSize]byte
hash := poly1305.New(polyKey)
hash.Write(ciphertext)
hash.Sum(tag[:0])
copy(tagOut, tag[:])
return ret
}
// Open does what the name suggests
func Open(out, nonce, box, key []byte) ([]byte, error) {
if len(nonce) != NonceSize {
panic("unsupported nonce size")
}
if len(key) != KeySize {
panic("unsupported key size")
}
if len(box) < TagSize {
return nil, errors.New("ciphertext is too short")
}
var firstBlock [64]byte
cipher, _ := chacha.NewCipher(nonce, key, 20)
cipher.XORKeyStream(firstBlock[:], firstBlock[:])
var polyKey [32]byte
copy(polyKey[:], firstBlock[:32])
var tag [TagSize]byte
ciphertext := box[TagSize:]
hash := poly1305.New(polyKey)
hash.Write(ciphertext)
hash.Sum(tag[:0])
if subtle.ConstantTimeCompare(tag[:], box[:TagSize]) != 1 {
return nil, errors.New("ciphertext authentication failed")
}
ret, out := sliceForAppend(out, len(ciphertext))
firstMessageBlock := ciphertext
if len(firstMessageBlock) > 32 {
firstMessageBlock = firstMessageBlock[:32]
}
for i, x := range firstMessageBlock {
out[i] = firstBlock[32+i] ^ x
}
ciphertext = ciphertext[len(firstMessageBlock):]
out = out[len(firstMessageBlock):]
cipher.SetCounter(1)
cipher.XORKeyStream(out, ciphertext)
return ret, nil
}
func sliceForAppend(in []byte, n int) (head, tail []byte) {
if total := len(in) + n; cap(in) >= total {
head = in[:total]
} else {
head = make([]byte, total)
copy(head, in)
}
tail = head[len(in):]
return
}

View file

@ -0,0 +1,26 @@
package xsecretbox
import (
"bytes"
"testing"
)
func TestSecretbox(t *testing.T) {
key := [32]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}
nonce := [24]byte{23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
src := []byte{42, 42, 42, 42, 42, 42, 42, 42, 42, 42}
dst := Seal(nil, nonce[:], src[:], key[:])
dec, err := Open(nil, nonce[:], dst[:], key[:])
if err != nil || !bytes.Equal(src, dec) {
t.Errorf("got %x instead of %x", dec, src)
}
dst[0]++
_, err = Open(nil, nonce[:], dst[:], key[:])
if err == nil {
t.Errorf("tag validation failed")
}
_, _ = SharedKey(key, key)
}