All of lore.kernel.org
 help / color / mirror / Atom feed
* [WireGuard] [PATCH] go test: add ICMP ping
@ 2016-07-07  2:57 Jonathan Rudenberg
  2016-07-07 10:20 ` Jason A. Donenfeld
  0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Rudenberg @ 2016-07-07  2:57 UTC (permalink / raw)
  To: wireguard

---
 contrib/external-tests/go/main.go | 72 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 64 insertions(+), 8 deletions(-)

diff --git a/contrib/external-tests/go/main.go b/contrib/external-tests/go/main.go
index 16632bb..68447fe 100644
--- a/contrib/external-tests/go/main.go
+++ b/contrib/external-tests/go/main.go
@@ -12,6 +12,8 @@ import (
 
 	"github.com/dchest/blake2s"
 	"github.com/titanous/noise"
+	"golang.org/x/net/icmp"
+	"golang.org/x/net/ipv4"
 )
 
 func main() {
@@ -36,6 +38,7 @@ func main() {
 	}
 	defer conn.Close()
 
+	// write handshake initiation packet
 	now := time.Now()
 	tai64n := make([]byte, 12)
 	binary.BigEndian.PutUint64(tai64n[:], uint64(now.Unix()))
@@ -53,6 +56,7 @@ func main() {
 		log.Fatalf("error writing initiation packet: %s", err)
 	}
 
+	// read handshake response packet
 	responsePacket := make([]byte, 89)
 	n, err := conn.Read(responsePacket)
 	if err != nil {
@@ -69,7 +73,7 @@ func main() {
 	if ourIndex != 28 {
 		log.Fatalf("response packet index wrong: want %d, got %d", 28, ourIndex)
 	}
-	payload, sendCipher, _, err := hs.ReadMessage(nil, responsePacket[9:57])
+	payload, sendCipher, receiveCipher, err := hs.ReadMessage(nil, responsePacket[9:57])
 	if err != nil {
 		log.Fatalf("error reading handshake message: %s", err)
 	}
@@ -77,12 +81,64 @@ func main() {
 		log.Fatalf("unexpected payload: %x", payload)
 	}
 
-	keepalivePacket := make([]byte, 13)
-	keepalivePacket[0] = 4 // Type: Data
-	binary.LittleEndian.PutUint32(keepalivePacket[1:], theirIndex)
-	binary.LittleEndian.PutUint64(keepalivePacket[5:], 0) // Nonce
-	keepalivePacket = sendCipher.Encrypt(keepalivePacket, nil, nil)
-	if _, err := conn.Write(keepalivePacket); err != nil {
-		log.Fatalf("error writing keepalive packet: %s", err)
+	// write ICMP Echo packet
+	pingMessage, _ := (&icmp.Message{
+		Type: ipv4.ICMPTypeEcho,
+		Body: &icmp.Echo{
+			ID:   1,
+			Seq:  1,
+			Data: []byte("WireGuard"),
+		},
+	}).Marshal(nil)
+	pingHeader, err := (&ipv4.Header{
+		Version:  ipv4.Version,
+		Len:      ipv4.HeaderLen,
+		TotalLen: ipv4.HeaderLen + len(pingMessage),
+		Protocol: 1, // ICMP
+		TTL:      2,
+		Checksum: 0xa15b, // the packet is always the same, hard-code checksum
+		Src:      net.IPv4(10, 189, 129, 2),
+		Dst:      net.IPv4(10, 189, 129, 1),
+	}).Marshal()
+	binary.BigEndian.PutUint16(pingHeader[2:], uint16(ipv4.HeaderLen+len(pingMessage))) // fix the length endianness on BSDs
+	if err != nil {
+		panic(err)
+	}
+	pingPacket := make([]byte, 13)
+	pingPacket[0] = 4 // Type: Data
+	binary.LittleEndian.PutUint32(pingPacket[1:], theirIndex)
+	binary.LittleEndian.PutUint64(pingPacket[5:], 0) // Nonce
+	pingPacket = sendCipher.Encrypt(pingPacket, nil, append(pingHeader, pingMessage...))
+	if _, err := conn.Write(pingPacket); err != nil {
+		log.Fatalf("error writing ping message: %s", err)
+	}
+
+	// read ICMP Echo Reply packet
+	replyPacket := make([]byte, 128)
+	n, err = conn.Read(replyPacket)
+	if err != nil {
+		log.Fatalf("error reading ping reply message: %s", err)
+	}
+	replyPacket = replyPacket[:n]
+	if replyPacket[0] != 4 { // Type: Data
+		log.Fatalf("unexpected reply packet type: %d", replyPacket[0])
+	}
+	replyPacket, err = receiveCipher.Decrypt(nil, nil, replyPacket[13:])
+	if err != nil {
+		log.Fatalf("error decrypting reply packet: %s", err)
+	}
+	replyHeaderLen := int(replyPacket[0]&0x0f) << 2
+	replyLen := binary.BigEndian.Uint16(replyPacket[2:])
+	replyMessage, err := icmp.ParseMessage(1, replyPacket[replyHeaderLen:replyLen])
+	if err != nil {
+		log.Fatalf("error parsing echo: %s", err)
+	}
+	echo, ok := replyMessage.Body.(*icmp.Echo)
+	if !ok {
+		log.Fatalf("unexpected reply body type %T", replyMessage.Body)
+	}
+
+	if echo.ID != 1 || echo.Seq != 1 || string(echo.Data) != "WireGuard" {
+		log.Fatalf("incorrect echo response: %#v", echo)
 	}
 }
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [WireGuard] [PATCH] go test: add ICMP ping
  2016-07-07  2:57 [WireGuard] [PATCH] go test: add ICMP ping Jonathan Rudenberg
@ 2016-07-07 10:20 ` Jason A. Donenfeld
  2016-07-07 11:44   ` Jason A. Donenfeld
  0 siblings, 1 reply; 5+ messages in thread
From: Jason A. Donenfeld @ 2016-07-07 10:20 UTC (permalink / raw)
  To: Jonathan Rudenberg; +Cc: WireGuard mailing list

This is awesome. What fun it was making this yesterday. A couple nits, however:

On Thu, Jul 7, 2016 at 4:57 AM, Jonathan Rudenberg
<jonathan@titanous.com> wrote:
> +               Checksum: 0xa15b, // the packet is always the same, hard-code checksum

Isn't there some Go lib we can use to calculate this for us?

> +       // read ICMP Echo Reply packet
> +       replyPacket := make([]byte, 128)

Is this 128 exact?

> +       replyPacket = replyPacket[:n]

I guess not, since you truncate it to n here.

> +       replyHeaderLen := int(replyPacket[0]&0x0f) << 2
> +       replyLen := binary.BigEndian.Uint16(replyPacket[2:])
> +       replyMessage, err := icmp.ParseMessage(1, replyPacket[replyHeaderLen:replyLen])

I realize this is Go, where nobody cares about indices because the
runtime does checks for you, but... this pops out at me as ugly and
dangerous. replyHeaderLen and replyLen are attacker controlled!

> +       if echo.ID != 1 || echo.Seq != 1 || string(echo.Data) != "WireGuard" {

Can we set ID and Seq to random numbers, and check that we get them back here?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [WireGuard] [PATCH] go test: add ICMP ping
  2016-07-07 10:20 ` Jason A. Donenfeld
@ 2016-07-07 11:44   ` Jason A. Donenfeld
  2016-07-07 11:58     ` [WireGuard] [PATCH] go test: don't rely on undefined append behavior Jonathan Rudenberg
  0 siblings, 1 reply; 5+ messages in thread
From: Jason A. Donenfeld @ 2016-07-07 11:44 UTC (permalink / raw)
  To: Jonathan Rudenberg; +Cc: WireGuard mailing list

On Thu, Jul 7, 2016 at 12:20 PM, Jason A. Donenfeld <Jason@zx2c4.com> wrote:
> This is awesome. What fun it was making this yesterday. A couple nits, however:
>
> On Thu, Jul 7, 2016 at 4:57 AM, Jonathan Rudenberg
> <jonathan@titanous.com> wrote:
>> +               Checksum: 0xa15b, // the packet is always the same, hard-code checksum
>
> Isn't there some Go lib we can use to calculate this for us?

https://git.zx2c4.com/WireGuard/commit/?id=42451879597f58ef6cdd74284c9629c12631d14d
Done.

>> +       if echo.ID != 1 || echo.Seq != 1 || string(echo.Data) != "WireGuard" {
>
> Can we set ID and Seq to random numbers, and check that we get them back here?

https://git.zx2c4.com/WireGuard/commit/?id=df68121676a70b325993e3bfdd51dce4c6bc65eb
Done.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [WireGuard] [PATCH] go test: don't rely on undefined append behavior
  2016-07-07 11:44   ` Jason A. Donenfeld
@ 2016-07-07 11:58     ` Jonathan Rudenberg
  2016-07-07 11:59       ` Jason A. Donenfeld
  0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Rudenberg @ 2016-07-07 11:58 UTC (permalink / raw)
  To: wireguard

---
 contrib/external-tests/go/main.go | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/contrib/external-tests/go/main.go b/contrib/external-tests/go/main.go
index 8e3c195..c1aa293 100644
--- a/contrib/external-tests/go/main.go
+++ b/contrib/external-tests/go/main.go
@@ -118,15 +118,13 @@ func main() {
 		Dst:      net.IPv4(10, 189, 129, 1),
 	}).Marshal()
 	binary.BigEndian.PutUint16(pingHeader[2:], uint16(ipv4.HeaderLen+len(pingMessage))) // fix the length endianness on BSDs
-	binary.BigEndian.PutUint16(pingHeader[10:], ipChecksum(append(pingHeader, pingMessage...)))
-	if err != nil {
-		panic(err)
-	}
+	pingData := append(pingHeader, pingMessage...)
+	binary.BigEndian.PutUint16(pingData[10:], ipChecksum(pingData))
 	pingPacket := make([]byte, 13)
 	pingPacket[0] = 4 // Type: Data
 	binary.LittleEndian.PutUint32(pingPacket[1:], theirIndex)
 	binary.LittleEndian.PutUint64(pingPacket[5:], 0) // Nonce
-	pingPacket = sendCipher.Encrypt(pingPacket, nil, append(pingHeader, pingMessage...))
+	pingPacket = sendCipher.Encrypt(pingPacket, nil, pingData)
 	if _, err := conn.Write(pingPacket); err != nil {
 		log.Fatalf("error writing ping message: %s", err)
 	}
-- 
2.9.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [WireGuard] [PATCH] go test: don't rely on undefined append behavior
  2016-07-07 11:58     ` [WireGuard] [PATCH] go test: don't rely on undefined append behavior Jonathan Rudenberg
@ 2016-07-07 11:59       ` Jason A. Donenfeld
  0 siblings, 0 replies; 5+ messages in thread
From: Jason A. Donenfeld @ 2016-07-07 11:59 UTC (permalink / raw)
  To: Jonathan Rudenberg; +Cc: WireGuard mailing list

Hi Jonathan,

I was wondering about this...

Merged, thanks.

Jason

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-07-07 11:59 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-07  2:57 [WireGuard] [PATCH] go test: add ICMP ping Jonathan Rudenberg
2016-07-07 10:20 ` Jason A. Donenfeld
2016-07-07 11:44   ` Jason A. Donenfeld
2016-07-07 11:58     ` [WireGuard] [PATCH] go test: don't rely on undefined append behavior Jonathan Rudenberg
2016-07-07 11:59       ` Jason A. Donenfeld

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.