lnd.xprv/brontide/noise_test.go
Olaoluwa Osuntokun 49f9f496fb
brontide: modify the max payload length to be 65535 bytes total
This commit modifies the current implementation of the p2p crypto
protocol to further constrain the max allowed payload size. With this
change we now use 16-bits (2-bytes) for the maximum payload length.
This change puts us closer to strict adherence of the Noise spec, and
simplifies the memory management w.r.t implementing the current version
of our scheme.

Note that this doesn’t restrict the size of messages that are able to
be sent over the wire within the LN p2p protocol. Larger message can
safely be encapsulated within the crypt messages via fragmentation that
will detected take place if a larger message is detected.
2016-11-07 18:50:26 -08:00

142 lines
3.9 KiB
Go

package brontide
import (
"bytes"
"math"
"net"
"testing"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/roasbeef/btcd/btcec"
)
func TestConnectionCorrectness(t *testing.T) {
// First, generate the long-term private keys both ends of the connection
// within our test.
localPriv, err := btcec.NewPrivateKey(btcec.S256())
if err != nil {
t.Fatalf("unable to generate local priv key: %v", err)
}
remotePriv, err := btcec.NewPrivateKey(btcec.S256())
if err != nil {
t.Fatalf("unable to generate remote priv key: %v", err)
}
// Having a port of ":0" means a random port, and interface will be
// chosen for our listener.
addr := ":0"
// Our listener will be local, and the connection remote.
listener, err := NewListener(localPriv, addr)
if err != nil {
t.Fatalf("unable to create listener: %v", err)
}
defer listener.Close()
netAddr := &lnwire.NetAddress{
IdentityKey: localPriv.PubKey(),
Address: listener.Addr().(*net.TCPAddr),
}
// Initiate a connection with a separate goroutine, and listen with our
// main one. If both errors are nil, then encryption+auth was succesful.
errChan := make(chan error)
connChan := make(chan net.Conn)
go func() {
conn, err := Dial(remotePriv, netAddr)
errChan <- err
connChan <- conn
}()
localConn, listenErr := listener.Accept()
if listenErr != nil {
t.Fatalf("unable to accept connection: %v", listenErr)
}
if dialErr := <-errChan; err != nil {
t.Fatalf("unable to establish connection: %v", dialErr)
}
conn := <-connChan
// Test out some message full-message reads.
for i := 0; i < 10; i++ {
msg := []byte("hello" + string(i))
if _, err := conn.Write(msg); err != nil {
t.Fatalf("remote conn failed to write: %v", err)
}
readBuf := make([]byte, len(msg))
if _, err := localConn.Read(readBuf); err != nil {
t.Fatalf("local conn failed to read: %v", err)
}
if !bytes.Equal(readBuf, msg) {
t.Fatalf("messages don't match, %v vs %v",
string(readBuf), string(msg))
}
}
// Now try incremental message reads. This simulates first writing a
// message header, then a message body.
outMsg := []byte("hello world")
if _, err := conn.Write(outMsg); err != nil {
t.Fatalf("remote conn failed to write: %v", err)
}
readBuf := make([]byte, len(outMsg))
if _, err := localConn.Read(readBuf[:len(outMsg)/2]); err != nil {
t.Fatalf("local conn failed to read: %v", err)
}
if _, err := localConn.Read(readBuf[len(outMsg)/2:]); err != nil {
t.Fatalf("local conn failed to read: %v", err)
}
if !bytes.Equal(outMsg, readBuf) {
t.Fatalf("messages don't match, %v vs %v",
string(readBuf), string(outMsg))
}
}
func TestMaxPayloadLength(t *testing.T) {
b := BrontideMachine{}
b.split()
// Create a payload that's juust over the maximum alloted payload
// length.
payloadToReject := make([]byte, math.MaxUint16+1)
var buf bytes.Buffer
// A write of the payload generated above to the state machine should
// be rejected as it's over the max payload length.
err := b.WriteMessage(&buf, payloadToReject)
if err != ErrMaxMessageLengthExceeded {
t.Fatalf("payload is over the max allowed length, the write " +
"should have been rejected")
}
// Generate another payload which with the MAC acounted for, should be
// accepted as a valid payload.
payloadToAccept := make([]byte, math.MaxUint16-macSize)
if err := b.WriteMessage(&buf, payloadToAccept); err != nil {
t.Fatalf("write for payload was rejected, should have been " +
"accepted")
}
// Generate a final payload which is juuust over the max payload length
// when the MAC is accounted for.
payloadToReject = make([]byte, math.MaxUint16-macSize+1)
// This payload should be rejected.
err = b.WriteMessage(&buf, payloadToReject)
if err != ErrMaxMessageLengthExceeded {
t.Fatalf("payload is over the max allowed length, the write " +
"should have been rejected")
}
}
func TestNoiseIdentityHiding(t *testing.T) {
// TODO(roasbeef): fin
}