2022-12-16 00:53:35 +00:00
package noise
import (
"bytes"
"context"
"crypto/rand"
"sync"
"testing"
"time"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/peerstore"
"github.com/stretchr/testify/require"
2022-12-21 18:47:43 +00:00
n "github.com/waku-org/go-noise"
2022-12-16 00:53:35 +00:00
"github.com/waku-org/go-waku/tests"
v2 "github.com/waku-org/go-waku/waku/v2"
"github.com/waku-org/go-waku/waku/v2/protocol/relay"
"github.com/waku-org/go-waku/waku/v2/timesource"
"github.com/waku-org/go-waku/waku/v2/utils"
)
func createRelayNode ( t * testing . T ) ( host . Host , * relay . WakuRelay ) {
port , err := tests . FindFreePort ( t , "" , 5 )
require . NoError ( t , err )
host , err := tests . MakeHost ( context . Background ( ) , port , rand . Reader )
require . NoError ( t , err )
2023-01-06 22:37:57 +00:00
relay := relay . NewWakuRelay ( host , v2 . NewBroadcaster ( 1024 ) , 0 , timesource . NewDefaultClock ( ) , utils . Logger ( ) )
err = relay . Start ( context . Background ( ) )
2022-12-16 00:53:35 +00:00
require . NoError ( t , err )
return host , relay
}
func TestPairingObj1Success ( t * testing . T ) {
host1 , relay1 := createRelayNode ( t )
host2 , relay2 := createRelayNode ( t )
defer host1 . Close ( )
defer host2 . Close ( )
defer relay1 . Stop ( )
defer relay2 . Stop ( )
host1 . Peerstore ( ) . AddAddr ( host2 . ID ( ) , tests . GetHostAddress ( host2 ) , peerstore . PermanentAddrTTL )
2023-02-16 16:17:52 +00:00
err := host1 . Peerstore ( ) . AddProtocols ( host2 . ID ( ) , relay . WakuRelayID_v200 )
2022-12-16 00:53:35 +00:00
require . NoError ( t , err )
_ , err = host1 . Network ( ) . DialPeer ( context . Background ( ) , host2 . ID ( ) )
require . NoError ( t , err )
time . Sleep ( 2 * time . Second ) // Wait for relay to form mesh
2022-12-21 18:47:43 +00:00
bobStaticKey , _ := n . DH25519 . GenerateKeypair ( )
bobEphemeralKey , _ := n . DH25519 . GenerateKeypair ( )
2022-12-16 00:53:35 +00:00
bobMessenger , err := NewWakuRelayMessenger ( context . Background ( ) , relay1 , nil , timesource . NewDefaultClock ( ) )
require . NoError ( t , err )
bobPairingObj , err := NewPairing ( bobStaticKey , bobEphemeralKey , WithDefaultResponderParameters ( ) , bobMessenger , utils . Logger ( ) )
require . NoError ( t , err )
authCodeCheckCh := make ( chan string , 2 )
time . Sleep ( 1 * time . Second )
wg := sync . WaitGroup { }
wg . Add ( 1 )
go func ( ) {
defer wg . Done ( )
// Check that authcodes match
authcode1 := <- authCodeCheckCh
authcode2 := <- authCodeCheckCh
require . Equal ( t , authcode1 , authcode2 )
} ( )
// Execute in separate go routine
wg . Add ( 1 )
go func ( ) {
defer wg . Done ( )
ctx , cancel := context . WithTimeout ( context . Background ( ) , 10 * time . Second )
defer cancel ( )
err := bobPairingObj . Execute ( ctx )
require . NoError ( t , err )
} ( )
// Confirmation is done by manually
go func ( ) {
authCode := <- bobPairingObj . AuthCode ( )
authCodeCheckCh <- authCode
err := bobPairingObj . ConfirmAuthCode ( true )
require . NoError ( t , err )
} ( )
2022-12-21 18:47:43 +00:00
aliceStaticKey , _ := n . DH25519 . GenerateKeypair ( )
aliceEphemeralKey , _ := n . DH25519 . GenerateKeypair ( )
2022-12-16 00:53:35 +00:00
aliceMessenger , err := NewWakuRelayMessenger ( context . Background ( ) , relay2 , nil , timesource . NewDefaultClock ( ) )
require . NoError ( t , err )
qrString , qrMessageNameTag := bobPairingObj . PairingInfo ( )
alicePairingObj , err := NewPairing ( aliceStaticKey , aliceEphemeralKey , WithInitiatorParameters ( qrString , qrMessageNameTag ) , aliceMessenger , utils . Logger ( ) )
require . NoError ( t , err )
// Execute in separate go routine
wg . Add ( 1 )
go func ( ) {
defer wg . Done ( )
ctx , cancel := context . WithTimeout ( context . Background ( ) , 10 * time . Second )
defer cancel ( )
err := alicePairingObj . Execute ( ctx )
require . NoError ( t , err )
} ( )
// Alice waits for authcode and confirms it
wg . Add ( 1 )
go func ( ) {
defer wg . Done ( )
authCode := <- alicePairingObj . AuthCode ( )
authCodeCheckCh <- authCode
err := alicePairingObj . ConfirmAuthCode ( true )
require . NoError ( t , err )
} ( )
wg . Wait ( )
// We test read/write of random messages exchanged between Alice and Bob
// Note that we exchange more than the number of messages contained in the nametag buffer to test if they are filled correctly as the communication proceeds
// We assume messages are sent via one of waku protocols
2022-12-21 18:47:43 +00:00
for i := 0 ; i < 10 * n . MessageNametagBufferSize ; i ++ {
2022-12-16 00:53:35 +00:00
// Alice writes to Bob
message := generateRandomBytes ( t , 32 )
msg , err := alicePairingObj . Encrypt ( message )
require . NoError ( t , err )
readMessage , err := bobPairingObj . Decrypt ( msg )
require . NoError ( t , err )
require . True ( t , bytes . Equal ( message , readMessage ) )
// Bob writes to Alice
message = generateRandomBytes ( t , 32 )
msg , err = alicePairingObj . Encrypt ( message )
require . NoError ( t , err )
readMessage , err = bobPairingObj . Decrypt ( msg )
require . NoError ( t , err )
require . True ( t , bytes . Equal ( message , readMessage ) )
}
}
func TestPairingObj1ShouldTimeout ( t * testing . T ) {
host1 , relay1 := createRelayNode ( t )
host2 , relay2 := createRelayNode ( t )
defer host1 . Close ( )
defer host2 . Close ( )
defer relay1 . Stop ( )
defer relay2 . Stop ( )
host1 . Peerstore ( ) . AddAddr ( host2 . ID ( ) , tests . GetHostAddress ( host2 ) , peerstore . PermanentAddrTTL )
2023-02-16 16:17:52 +00:00
err := host1 . Peerstore ( ) . AddProtocols ( host2 . ID ( ) , relay . WakuRelayID_v200 )
2022-12-16 00:53:35 +00:00
require . NoError ( t , err )
_ , err = host1 . Network ( ) . DialPeer ( context . Background ( ) , host2 . ID ( ) )
require . NoError ( t , err )
time . Sleep ( 2 * time . Second ) // Wait for relay to form mesh
2022-12-21 18:47:43 +00:00
bobStaticKey , _ := n . DH25519 . GenerateKeypair ( )
bobEphemeralKey , _ := n . DH25519 . GenerateKeypair ( )
2022-12-16 00:53:35 +00:00
bobMessenger , err := NewWakuRelayMessenger ( context . Background ( ) , relay1 , nil , timesource . NewDefaultClock ( ) )
require . NoError ( t , err )
bobPairingObj , err := NewPairing ( bobStaticKey , bobEphemeralKey , WithDefaultResponderParameters ( ) , bobMessenger , utils . Logger ( ) )
require . NoError ( t , err )
2022-12-21 18:47:43 +00:00
aliceStaticKey , _ := n . DH25519 . GenerateKeypair ( )
aliceEphemeralKey , _ := n . DH25519 . GenerateKeypair ( )
2022-12-16 00:53:35 +00:00
aliceMessenger , err := NewWakuRelayMessenger ( context . Background ( ) , relay2 , nil , timesource . NewDefaultClock ( ) )
require . NoError ( t , err )
qrString , qrMessageNameTag := bobPairingObj . PairingInfo ( )
alicePairingObj , err := NewPairing ( aliceStaticKey , aliceEphemeralKey , WithInitiatorParameters ( qrString , qrMessageNameTag ) , aliceMessenger , utils . Logger ( ) )
require . NoError ( t , err )
wg := sync . WaitGroup { }
wg . Add ( 2 )
go func ( ) {
defer wg . Done ( )
ctx , cancel := context . WithTimeout ( context . Background ( ) , 1 * time . Second )
defer cancel ( )
err := bobPairingObj . Execute ( ctx )
require . ErrorIs ( t , err , ErrPairingTimeout )
} ( )
go func ( ) {
defer wg . Done ( )
ctx , cancel := context . WithTimeout ( context . Background ( ) , 1 * time . Second )
defer cancel ( )
err := alicePairingObj . Execute ( ctx )
require . ErrorIs ( t , err , ErrPairingTimeout )
} ( )
wg . Wait ( )
}