2019-11-21 16:19:22 +00:00
|
|
|
package encryption
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
2023-10-02 09:28:42 +00:00
|
|
|
"github.com/status-im/status-go/appdatabase"
|
2019-11-21 16:19:22 +00:00
|
|
|
"github.com/status-im/status-go/protocol/sqlite"
|
2023-10-02 09:28:42 +00:00
|
|
|
"github.com/status-im/status-go/protocol/tt"
|
|
|
|
"github.com/status-im/status-go/t/helpers"
|
2019-11-21 16:19:22 +00:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
2020-01-02 09:10:19 +00:00
|
|
|
"github.com/status-im/status-go/eth-node/crypto"
|
2019-11-21 16:19:22 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestProtocolServiceTestSuite(t *testing.T) {
|
|
|
|
suite.Run(t, new(ProtocolServiceTestSuite))
|
|
|
|
}
|
|
|
|
|
|
|
|
type ProtocolServiceTestSuite struct {
|
|
|
|
suite.Suite
|
2023-10-02 09:28:42 +00:00
|
|
|
alice *Protocol
|
|
|
|
bob *Protocol
|
|
|
|
logger *zap.Logger
|
2019-11-21 16:19:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (s *ProtocolServiceTestSuite) SetupTest() {
|
|
|
|
var err error
|
|
|
|
|
|
|
|
s.logger = tt.MustCreateTestLogger()
|
|
|
|
|
2023-10-02 09:28:42 +00:00
|
|
|
db, err := helpers.SetupTestMemorySQLDB(appdatabase.DbInitializer{})
|
2019-11-21 16:19:22 +00:00
|
|
|
s.Require().NoError(err)
|
2023-10-02 09:28:42 +00:00
|
|
|
err = sqlite.Migrate(db)
|
2019-11-21 16:19:22 +00:00
|
|
|
s.Require().NoError(err)
|
|
|
|
s.alice = New(
|
|
|
|
db,
|
|
|
|
"1",
|
|
|
|
s.logger.With(zap.String("user", "alice")),
|
|
|
|
)
|
|
|
|
|
2023-10-02 09:28:42 +00:00
|
|
|
db, err = helpers.SetupTestMemorySQLDB(appdatabase.DbInitializer{})
|
|
|
|
s.Require().NoError(err)
|
|
|
|
err = sqlite.Migrate(db)
|
2019-11-21 16:19:22 +00:00
|
|
|
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")
|
|
|
|
}
|
|
|
|
|
2021-09-21 15:47:04 +00:00
|
|
|
func (s *ProtocolServiceTestSuite) TestBuildEncryptedMessage() {
|
2019-11-21 16:19:22 +00:00
|
|
|
bobKey, err := crypto.GenerateKey()
|
|
|
|
s.NoError(err)
|
|
|
|
aliceKey, err := crypto.GenerateKey()
|
|
|
|
s.NoError(err)
|
|
|
|
|
|
|
|
payload := []byte("test")
|
|
|
|
|
2021-09-21 15:47:04 +00:00
|
|
|
msgSpec, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, payload)
|
2019-11-21 16:19:22 +00:00
|
|
|
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")
|
|
|
|
|
2021-09-21 15:47:04 +00:00
|
|
|
directMessage := msg.GetEncryptedMessage()
|
2019-11-21 16:19:22 +00:00
|
|
|
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")
|
|
|
|
}
|
|
|
|
|
2021-09-21 15:47:04 +00:00
|
|
|
func (s *ProtocolServiceTestSuite) TestBuildAndReadEncryptedMessage() {
|
2019-11-21 16:19:22 +00:00
|
|
|
bobKey, err := crypto.GenerateKey()
|
|
|
|
s.Require().NoError(err)
|
|
|
|
aliceKey, err := crypto.GenerateKey()
|
|
|
|
s.Require().NoError(err)
|
|
|
|
|
|
|
|
payload := []byte("test")
|
|
|
|
|
|
|
|
// Message is sent with DH
|
2021-09-21 15:47:04 +00:00
|
|
|
msgSpec, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, payload)
|
2019-11-21 16:19:22 +00:00
|
|
|
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")
|
|
|
|
|
2020-07-31 12:22:05 +00:00
|
|
|
_, err = s.bob.Start(bobKey)
|
2020-07-31 09:46:38 +00:00
|
|
|
s.Require().NoError(err)
|
|
|
|
|
2021-09-21 15:47:04 +00:00
|
|
|
msgSpec, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, payload)
|
2019-11-21 16:19:22 +00:00
|
|
|
s.NoError(err)
|
|
|
|
s.NotNil(msgSpec, "It creates a message spec")
|
2020-07-31 12:22:05 +00:00
|
|
|
s.Require().NotNil(msgSpec.SharedSecret)
|
2019-11-21 16:19:22 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2020-07-31 09:46:38 +00:00
|
|
|
s.Require().NoError(s.bob.Stop())
|
2019-11-21 16:19:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
2020-07-31 09:46:38 +00:00
|
|
|
subscriptions, err := s.alice.Start(aliceKey)
|
|
|
|
s.Require().NoError(err)
|
2019-11-21 16:19:22 +00:00
|
|
|
|
2020-07-31 12:22:05 +00:00
|
|
|
secretResponse := subscriptions.SharedSecrets
|
2019-11-21 16:19:22 +00:00
|
|
|
|
|
|
|
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)
|
2020-07-31 09:46:38 +00:00
|
|
|
s.Require().NoError(s.alice.Stop())
|
2019-11-21 16:19:22 +00:00
|
|
|
}
|