mirror of https://github.com/status-im/go-waku.git
206 lines
6.2 KiB
Go
206 lines
6.2 KiB
Go
package noise
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"crypto/rand"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/waku-org/noise"
|
|
)
|
|
|
|
func generateRandomBytes(t *testing.T, n int) []byte {
|
|
b := make([]byte, n)
|
|
_, err := rand.Read(b)
|
|
require.NoError(t, err)
|
|
return b
|
|
}
|
|
|
|
func TestSerialization(t *testing.T) {
|
|
handshakeMessages := make([]*NoisePublicKey, 2)
|
|
|
|
pk1, _, _ := ed25519.GenerateKey(rand.Reader)
|
|
|
|
pk2, _, _ := ed25519.GenerateKey(rand.Reader)
|
|
|
|
handshakeMessages[0] = Ed25519PubKeyToNoisePublicKey(pk1)
|
|
handshakeMessages[1] = Ed25519PubKeyToNoisePublicKey(pk2)
|
|
|
|
p1 := &PayloadV2{
|
|
ProtocolId: Noise_K1K1_25519_ChaChaPoly_SHA256,
|
|
HandshakeMessage: handshakeMessages,
|
|
TransportMessage: []byte{9, 8, 7, 6, 5, 4, 3, 2, 1},
|
|
}
|
|
|
|
serializedPayload, err := p1.Serialize()
|
|
require.NoError(t, err)
|
|
|
|
deserializedPayload, err := DeserializePayloadV2(serializedPayload)
|
|
require.NoError(t, err)
|
|
require.Equal(t, p1, deserializedPayload)
|
|
}
|
|
|
|
func handshakeTest(t *testing.T, hsAlice *Handshake, hsBob *Handshake) {
|
|
// ###############
|
|
// # 1st step
|
|
// ###############
|
|
|
|
// By being the handshake initiator, Alice writes a Waku2 payload v2 containing her handshake message
|
|
// and the (encrypted) transport message
|
|
sentTransportMessage := generateRandomBytes(t, 32)
|
|
aliceStep, err := hsAlice.Step(nil, sentTransportMessage, nil)
|
|
require.NoError(t, err)
|
|
|
|
// Bob reads Alice's payloads, and returns the (decrypted) transport message Alice sent to him
|
|
bobStep, err := hsBob.Step(&aliceStep.Payload2, nil, nil)
|
|
require.NoError(t, err)
|
|
|
|
// check:
|
|
require.Equal(t, sentTransportMessage, bobStep.TransportMessage)
|
|
|
|
// ###############
|
|
// # 2nd step
|
|
// ###############
|
|
|
|
// At this step, Bob writes and returns a payload
|
|
sentTransportMessage = generateRandomBytes(t, 32)
|
|
bobStep, err = hsBob.Step(nil, sentTransportMessage, nil)
|
|
require.NoError(t, err)
|
|
|
|
// While Alice reads and returns the (decrypted) transport message
|
|
aliceStep, err = hsAlice.Step(&bobStep.Payload2, nil, nil)
|
|
require.NoError(t, err)
|
|
|
|
// check:
|
|
require.Equal(t, sentTransportMessage, aliceStep.TransportMessage)
|
|
|
|
// ###############
|
|
// # 3rd step
|
|
// ###############
|
|
|
|
// Similarly as in first step, Alice writes a Waku2 payload containing the handshake message and the (encrypted) transport message
|
|
sentTransportMessage = generateRandomBytes(t, 32)
|
|
aliceStep, err = hsAlice.Step(nil, sentTransportMessage, nil)
|
|
require.NoError(t, err)
|
|
|
|
// Bob reads Alice's payloads, and returns the (decrypted) transport message Alice sent to him
|
|
bobStep, err = hsBob.Step(&aliceStep.Payload2, nil, nil)
|
|
require.NoError(t, err)
|
|
|
|
// check:
|
|
require.Equal(t, sentTransportMessage, bobStep.TransportMessage)
|
|
|
|
// Note that for this handshake pattern, no more message patterns are left for processing
|
|
// We test that extra calls to stepHandshake do not affect parties' handshake states
|
|
require.True(t, hsAlice.HandshakeComplete())
|
|
require.True(t, hsBob.HandshakeComplete())
|
|
|
|
_, err = hsAlice.Step(nil, generateRandomBytes(t, 32), nil)
|
|
require.ErrorIs(t, err, ErrorHandshakeComplete)
|
|
|
|
_, err = hsBob.Step(nil, generateRandomBytes(t, 32), nil)
|
|
require.ErrorIs(t, err, ErrorHandshakeComplete)
|
|
|
|
// #########################
|
|
// After Handshake
|
|
// #########################
|
|
|
|
// We test read/write of random messages exchanged between Alice and Bob
|
|
|
|
defaultMessageNametagBuffer := NewMessageNametagBuffer(nil)
|
|
|
|
for i := 0; i < 10; i++ {
|
|
// Alice writes to Bob
|
|
message := generateRandomBytes(t, 32)
|
|
|
|
encryptedPayload, err := hsAlice.Encrypt(message, defaultMessageNametagBuffer)
|
|
require.NoError(t, err)
|
|
|
|
plaintext, err := hsBob.Decrypt(encryptedPayload, defaultMessageNametagBuffer)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, message, plaintext)
|
|
|
|
// Bob writes to Alice
|
|
message = generateRandomBytes(t, 32)
|
|
|
|
encryptedPayload, err = hsBob.Encrypt(message, defaultMessageNametagBuffer)
|
|
require.NoError(t, err)
|
|
|
|
plaintext, err = hsAlice.Decrypt(encryptedPayload, defaultMessageNametagBuffer)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, message, plaintext)
|
|
}
|
|
}
|
|
|
|
func TestNoiseXXHandshakeRoundtrip(t *testing.T) {
|
|
aliceKP, _ := noise.DH25519.GenerateKeypair(rand.Reader)
|
|
bobKP, _ := noise.DH25519.GenerateKeypair(rand.Reader)
|
|
|
|
hsAlice, err := NewHandshake_XX_25519_ChaChaPoly_SHA256(aliceKP, true, nil)
|
|
require.NoError(t, err)
|
|
|
|
hsBob, err := NewHandshake_XX_25519_ChaChaPoly_SHA256(bobKP, false, nil)
|
|
require.NoError(t, err)
|
|
|
|
handshakeTest(t, hsAlice, hsBob)
|
|
}
|
|
|
|
func TestNoiseXXpsk0HandshakeRoundtrip(t *testing.T) {
|
|
aliceKP, _ := noise.DH25519.GenerateKeypair(rand.Reader)
|
|
bobKP, _ := noise.DH25519.GenerateKeypair(rand.Reader)
|
|
|
|
// We generate a random psk
|
|
psk := generateRandomBytes(t, 32)
|
|
|
|
hsAlice, err := NewHandshake_XXpsk0_25519_ChaChaPoly_SHA256(aliceKP, true, psk, nil)
|
|
require.NoError(t, err)
|
|
|
|
hsBob, err := NewHandshake_XXpsk0_25519_ChaChaPoly_SHA256(bobKP, false, psk, nil)
|
|
require.NoError(t, err)
|
|
|
|
handshakeTest(t, hsAlice, hsBob)
|
|
}
|
|
|
|
func TestNoiseK1K1HandshakeRoundtrip(t *testing.T) {
|
|
aliceKP, _ := noise.DH25519.GenerateKeypair(rand.Reader)
|
|
bobKP, _ := noise.DH25519.GenerateKeypair(rand.Reader)
|
|
|
|
hsAlice, err := NewHandshake_K1K1_25519_ChaChaPoly_SHA256(aliceKP, true, bobKP.Public, nil)
|
|
require.NoError(t, err)
|
|
|
|
hsBob, err := NewHandshake_K1K1_25519_ChaChaPoly_SHA256(bobKP, false, aliceKP.Public, nil)
|
|
require.NoError(t, err)
|
|
|
|
handshakeTest(t, hsAlice, hsBob)
|
|
}
|
|
|
|
func TestNoiseXK1HandshakeRoundtrip(t *testing.T) {
|
|
aliceKP, _ := noise.DH25519.GenerateKeypair(rand.Reader)
|
|
bobKP, _ := noise.DH25519.GenerateKeypair(rand.Reader)
|
|
|
|
hsAlice, err := NewHandshake_XK1_25519_ChaChaPoly_SHA256(aliceKP, true, bobKP.Public, nil)
|
|
require.NoError(t, err)
|
|
|
|
hsBob, err := NewHandshake_XK1_25519_ChaChaPoly_SHA256(bobKP, false, nil, nil)
|
|
require.NoError(t, err)
|
|
|
|
handshakeTest(t, hsAlice, hsBob)
|
|
}
|
|
|
|
func TestPKCSPaddingUnpadding(t *testing.T) {
|
|
maxMessageLength := 3 * NoisePaddingBlockSize
|
|
for messageLen := 0; messageLen <= maxMessageLength; messageLen++ {
|
|
message := generateRandomBytes(t, messageLen)
|
|
padded, err := PKCS7_Pad(message, NoisePaddingBlockSize)
|
|
require.NoError(t, err)
|
|
unpadded, err := PKCS7_Unpad(padded, NoisePaddingBlockSize)
|
|
require.NoError(t, err)
|
|
|
|
require.Greater(t, len(padded), 0)
|
|
require.Equal(t, len(padded)%NoisePaddingBlockSize, 0)
|
|
require.Equal(t, message, unpadded)
|
|
}
|
|
}
|