status-im/status-go

View on GitHub
protocol/encryption/protocol_test.go

Summary

Maintainability
A
0 mins
Test Coverage
package encryption

import (
    "testing"

    "github.com/status-im/status-go/appdatabase"
    "github.com/status-im/status-go/protocol/sqlite"
    "github.com/status-im/status-go/protocol/tt"
    "github.com/status-im/status-go/t/helpers"

    "github.com/stretchr/testify/suite"
    "go.uber.org/zap"

    "github.com/status-im/status-go/eth-node/crypto"
)

func TestProtocolServiceTestSuite(t *testing.T) {
    suite.Run(t, new(ProtocolServiceTestSuite))
}

type ProtocolServiceTestSuite struct {
    suite.Suite
    alice  *Protocol
    bob    *Protocol
    logger *zap.Logger
}

func (s *ProtocolServiceTestSuite) SetupTest() {
    var err error

    s.logger = tt.MustCreateTestLogger()

    db, err := helpers.SetupTestMemorySQLDB(appdatabase.DbInitializer{})
    s.Require().NoError(err)
    err = sqlite.Migrate(db)
    s.Require().NoError(err)
    s.alice = New(
        db,
        "1",
        s.logger.With(zap.String("user", "alice")),
    )

    db, err = helpers.SetupTestMemorySQLDB(appdatabase.DbInitializer{})
    s.Require().NoError(err)
    err = sqlite.Migrate(db)
    s.Require().NoError(err)
    s.bob = New(
        db,
        "2",
        s.logger.With(zap.String("user", "bob")),
    )
}

func (s *ProtocolServiceTestSuite) TearDownTest() {
    _ = s.logger.Sync()
}

func (s *ProtocolServiceTestSuite) TestBuildPublicMessage() {
    aliceKey, err := crypto.GenerateKey()
    s.NoError(err)

    payload := []byte("test")
    s.NoError(err)

    msg, err := s.alice.BuildPublicMessage(aliceKey, payload)
    s.NoError(err)
    s.NotNil(msg, "It creates a message")

    s.NotNilf(msg.Message.GetBundles(), "It adds a bundle to the message")
}

func (s *ProtocolServiceTestSuite) TestBuildEncryptedMessage() {
    bobKey, err := crypto.GenerateKey()
    s.NoError(err)
    aliceKey, err := crypto.GenerateKey()
    s.NoError(err)

    payload := []byte("test")

    msgSpec, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, payload)
    s.NoError(err)
    s.NotNil(msgSpec, "It creates a message spec")

    msg := msgSpec.Message
    s.NotNil(msg, "It creates a messages")

    s.NotNilf(msg.GetBundles(), "It adds a bundle to the message")

    directMessage := msg.GetEncryptedMessage()
    s.NotNilf(directMessage, "It sets the direct message")

    encryptedPayload := directMessage["none"].GetPayload()
    s.NotNilf(encryptedPayload, "It sets the payload of the message")

    s.NotEqualf(payload, encryptedPayload, "It encrypts the payload")
}

func (s *ProtocolServiceTestSuite) TestBuildAndReadEncryptedMessage() {
    bobKey, err := crypto.GenerateKey()
    s.Require().NoError(err)
    aliceKey, err := crypto.GenerateKey()
    s.Require().NoError(err)

    payload := []byte("test")

    // Message is sent with DH
    msgSpec, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, payload)
    s.Require().NoError(err)
    s.Require().NotNil(msgSpec)

    msg := msgSpec.Message
    s.Require().NotNil(msg)

    // Bob is able to decrypt the message
    unmarshaledMsg, err := s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, msg, []byte("message-id"))
    s.NoError(err)
    s.NotNil(unmarshaledMsg)

    recoveredPayload := []byte("test")
    s.Equalf(payload, recoveredPayload, "It successfully unmarshal the decrypted message")
}

func (s *ProtocolServiceTestSuite) TestSecretNegotiation() {
    bobKey, err := crypto.GenerateKey()
    s.NoError(err)
    aliceKey, err := crypto.GenerateKey()
    s.NoError(err)

    payload := []byte("test")

    _, err = s.bob.Start(bobKey)
    s.Require().NoError(err)

    msgSpec, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, payload)
    s.NoError(err)
    s.NotNil(msgSpec, "It creates a message spec")
    s.Require().NotNil(msgSpec.SharedSecret)

    bundle := msgSpec.Message.GetBundles()[0]
    s.Require().NotNil(bundle)

    signedPreKeys := bundle.GetSignedPreKeys()
    s.Require().NotNil(signedPreKeys)

    signedPreKey := signedPreKeys["1"]
    s.Require().NotNil(signedPreKey)

    s.Require().Equal(uint32(1), signedPreKey.GetProtocolVersion())

    _, err = s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, msgSpec.Message, []byte("message-id"))
    s.NoError(err)

    s.Require().NoError(s.bob.Stop())
}

func (s *ProtocolServiceTestSuite) TestPropagatingSavedSharedSecretsOnStart() {
    aliceKey, err := crypto.GenerateKey()
    s.NoError(err)
    bobKey, err := crypto.GenerateKey()
    s.NoError(err)

    // Generate and save a shared secret.
    generatedSecret, err := s.alice.secret.Generate(aliceKey, &bobKey.PublicKey, "installation-1")
    s.NoError(err)

    subscriptions, err := s.alice.Start(aliceKey)
    s.Require().NoError(err)

    secretResponse := subscriptions.SharedSecrets

    s.Require().NotNil(secretResponse)
    s.Require().Len(secretResponse, 1)
    s.Equal(crypto.FromECDSAPub(generatedSecret.Identity), crypto.FromECDSAPub(secretResponse[0].Identity))
    s.Equal(generatedSecret.Key, secretResponse[0].Key)
    s.Require().NoError(s.alice.Stop())
}