From 3225297570a2e21563f9119b0b21723bc0a87fb9 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Thu, 20 Feb 2020 11:05:29 +0700 Subject: [PATCH 1/4] remove the Protector interface, introduce a PSK type --- pnet/protector.go | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/pnet/protector.go b/pnet/protector.go index c443ee8f..2db70bd6 100644 --- a/pnet/protector.go +++ b/pnet/protector.go @@ -1,15 +1,4 @@ // Package pnet provides interfaces for private networking in libp2p. package pnet -import "net" - -// Protector interface is a way for private network implementation to be transparent in -// libp2p. It is created by implementation and use by libp2p-conn to secure connections -// so they can be only established with selected number of peers. -type Protector interface { - // Wraps passed connection to protect it - Protect(net.Conn) (net.Conn, error) - - // Returns key fingerprint that is safe to expose - Fingerprint() []byte -} +type PSK []byte From 2433ed835f2bf1ef5930080e646ee1e7fe8db1c0 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 2 Mar 2020 09:09:31 +0700 Subject: [PATCH 2/4] move decoding of the v1 PSK here --- pnet/codec.go | 66 ++++++++++++++++++++++++ pnet/codec_test.go | 122 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 pnet/codec.go create mode 100644 pnet/codec_test.go diff --git a/pnet/codec.go b/pnet/codec.go new file mode 100644 index 00000000..81bbf165 --- /dev/null +++ b/pnet/codec.go @@ -0,0 +1,66 @@ +package pnet + +import ( + "bufio" + "bytes" + "encoding/base64" + "encoding/hex" + "fmt" + "io" +) + +var ( + pathPSKv1 = []byte("/key/swarm/psk/1.0.0/") + pathBin = "/bin/" + pathBase16 = "/base16/" + pathBase64 = "/base64/" +) + +func readHeader(r *bufio.Reader) ([]byte, error) { + header, err := r.ReadBytes('\n') + if err != nil { + return nil, err + } + + return bytes.TrimRight(header, "\r\n"), nil +} + +func expectHeader(r *bufio.Reader, expected []byte) error { + header, err := readHeader(r) + if err != nil { + return err + } + if !bytes.Equal(header, expected) { + return fmt.Errorf("expected file header %s, got: %s", pathPSKv1, header) + } + return nil +} + +// DecodeV1PSK reads a Multicodec encoded V1 PSK. +func DecodeV1PSK(in io.Reader) ([]byte, error) { + reader := bufio.NewReader(in) + if err := expectHeader(reader, pathPSKv1); err != nil { + return nil, err + } + header, err := readHeader(reader) + if err != nil { + return nil, err + } + + var decoder io.Reader + switch string(header) { + case pathBase16: + decoder = hex.NewDecoder(reader) + case pathBase64: + decoder = base64.NewDecoder(base64.StdEncoding, reader) + case pathBin: + decoder = reader + default: + return nil, fmt.Errorf("unknown encoding: %s", header) + } + out := make([]byte, 32) + if _, err = io.ReadFull(decoder, out[:]); err != nil { + return nil, err + } + return out, nil +} diff --git a/pnet/codec_test.go b/pnet/codec_test.go new file mode 100644 index 00000000..b4b9272d --- /dev/null +++ b/pnet/codec_test.go @@ -0,0 +1,122 @@ +package pnet + +import ( + "bytes" + "encoding/base64" + "testing" +) + +func bufWithBase(base string, windows bool) *bytes.Buffer { + b := &bytes.Buffer{} + b.Write(pathPSKv1) + if windows { + b.WriteString("\r") + } + b.WriteString("\n") + b.WriteString(base) + if windows { + b.WriteString("\r") + } + b.WriteString("\n") + return b +} + +func TestDecodeHex(t *testing.T) { + testDecodeHex(t, true) + testDecodeHex(t, false) +} + +func TestDecodeBad(t *testing.T) { + testDecodeBad(t, true) + testDecodeBad(t, false) +} + +func testDecodeBad(t *testing.T, windows bool) { + b := bufWithBase("/verybadbase/", windows) + b.WriteString("Have fun decoding that key") + + _, err := DecodeV1PSK(b) + if err == nil { + t.Fatal("expected 'unknown encoding' got nil") + } +} + +func testDecodeHex(t *testing.T, windows bool) { + b := bufWithBase("/base16/", windows) + for i := 0; i < 32; i++ { + b.WriteString("FF") + } + + psk, err := DecodeV1PSK(b) + if err != nil { + t.Fatal(err) + } + + for _, b := range psk { + if b != 255 { + t.Fatal("byte was wrong") + } + } +} + +func TestDecodeB64(t *testing.T) { + testDecodeB64(t, true) + testDecodeB64(t, false) +} + +func testDecodeB64(t *testing.T, windows bool) { + b := bufWithBase("/base64/", windows) + key := make([]byte, 32) + for i := 0; i < 32; i++ { + key[i] = byte(i) + } + + e := base64.NewEncoder(base64.StdEncoding, b) + _, err := e.Write(key) + if err != nil { + t.Fatal(err) + } + err = e.Close() + if err != nil { + t.Fatal(err) + } + + psk, err := DecodeV1PSK(b) + if err != nil { + t.Fatal(err) + } + + for i, b := range psk { + if b != psk[i] { + t.Fatal("byte was wrong") + } + } + +} + +func TestDecodeBin(t *testing.T) { + testDecodeBin(t, true) + testDecodeBin(t, false) +} + +func testDecodeBin(t *testing.T, windows bool) { + b := bufWithBase("/bin/", windows) + key := make([]byte, 32) + for i := 0; i < 32; i++ { + key[i] = byte(i) + } + + b.Write(key) + + psk, err := DecodeV1PSK(b) + if err != nil { + t.Fatal(err) + } + + for i, b := range psk { + if b != psk[i] { + t.Fatal("byte was wrong") + } + } + +} From e3b5ffc01cd813f2614c81c1be2be6543bf2c680 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Mon, 2 Mar 2020 09:11:26 +0700 Subject: [PATCH 3/4] add docs for PSK --- pnet/protector.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pnet/protector.go b/pnet/protector.go index 2db70bd6..9d9dce92 100644 --- a/pnet/protector.go +++ b/pnet/protector.go @@ -1,4 +1,7 @@ // Package pnet provides interfaces for private networking in libp2p. package pnet +// A PSK enables private network implementation to be transparent in libp2p. +// It is used to ensure that peers can only establish connections to other peers +// that are using the same PSK. type PSK []byte From 0715d983f9ca16a996a70ca9058be2ad515e12d8 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Tue, 3 Mar 2020 10:44:21 +0700 Subject: [PATCH 4/4] change the return type of DecodeV1PSK to PSK --- pnet/codec.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pnet/codec.go b/pnet/codec.go index 81bbf165..e741aba9 100644 --- a/pnet/codec.go +++ b/pnet/codec.go @@ -37,7 +37,7 @@ func expectHeader(r *bufio.Reader, expected []byte) error { } // DecodeV1PSK reads a Multicodec encoded V1 PSK. -func DecodeV1PSK(in io.Reader) ([]byte, error) { +func DecodeV1PSK(in io.Reader) (PSK, error) { reader := bufio.NewReader(in) if err := expectHeader(reader, pathPSKv1); err != nil { return nil, err