From 6112ca0289bdfad8170405ad3578c4a6e6790382 Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Tue, 27 Nov 2018 09:54:20 +0100 Subject: [PATCH] Add tests for multi-device and refactor encryption service config (#1277) --- services/shhext/chat/encryption.go | 120 +++++----- .../chat/encryption_multi_device_test.go | 226 ++++++++++++------ services/shhext/chat/encryption_test.go | 16 +- services/shhext/chat/persistence.go | 2 +- services/shhext/chat/protocol.go | 6 +- services/shhext/chat/protocol_test.go | 4 +- services/shhext/chat/sql_lite_persistence.go | 2 +- services/shhext/service.go | 2 +- 8 files changed, 233 insertions(+), 145 deletions(-) diff --git a/services/shhext/chat/encryption.go b/services/shhext/chat/encryption.go index 2105b8f15..7df9ba0da 100644 --- a/services/shhext/chat/encryption.go +++ b/services/shhext/chat/encryption.go @@ -19,40 +19,51 @@ import ( var ErrSessionNotFound = errors.New("session not found") -// Max number of installations we keep synchronized. -const maxInstallations = 5 - // If we have no bundles, we use a constant so that the message can reach any device. const noInstallationID = "none" -// How many consecutive messages can be skipped in the receiving chain. -const maxSkip = 1000 - -// Any message with seqNo <= currentSeq - maxKeep will be deleted. -const maxKeep = 3000 - -// How many keys do we store in total per session. -const maxMessageKeysPerSession = 2000 - // EncryptionService defines a service that is responsible for the encryption aspect of the protocol. type EncryptionService struct { - log log.Logger - persistence PersistenceService - installationID string - mutex sync.Mutex + log log.Logger + persistence PersistenceService + config EncryptionServiceConfig + mutex sync.Mutex +} + +type EncryptionServiceConfig struct { + InstallationID string + // Max number of installations we keep synchronized. + MaxInstallations int + // How many consecutive messages can be skipped in the receiving chain. + MaxSkip int + // Any message with seqNo <= currentSeq - maxKeep will be deleted. + MaxKeep int + // How many keys do we store in total per session. + MaxMessageKeysPerSession int } type IdentityAndIDPair [2]string +// DefaultEncryptionServiceConfig returns the default values used by the encryption service +func DefaultEncryptionServiceConfig(installationID string) EncryptionServiceConfig { + return EncryptionServiceConfig{ + MaxInstallations: 5, + MaxSkip: 1000, + MaxKeep: 3000, + MaxMessageKeysPerSession: 2000, + InstallationID: installationID, + } +} + // NewEncryptionService creates a new EncryptionService instance. -func NewEncryptionService(p PersistenceService, installationID string) *EncryptionService { +func NewEncryptionService(p PersistenceService, config EncryptionServiceConfig) *EncryptionService { logger := log.New("package", "status-go/services/sshext.chat") - logger.Info("Initialized encryption service", "installationID", installationID) + logger.Info("Initialized encryption service", "installationID", config.InstallationID) return &EncryptionService{ - log: logger, - persistence: p, - installationID: installationID, - mutex: sync.Mutex{}, + log: logger, + persistence: p, + config: config, + mutex: sync.Mutex{}, } } @@ -65,16 +76,30 @@ func (s *EncryptionService) keyFromActiveX3DH(theirIdentityKey []byte, theirSign return sharedKey, ephemeralPubKey, nil } +func (s *EncryptionService) getDRSession(id []byte) (dr.Session, error) { + sessionStorage := s.persistence.GetSessionStorage() + return dr.Load( + id, + sessionStorage, + dr.WithKeysStorage(s.persistence.GetKeysStorage()), + dr.WithMaxSkip(s.config.MaxSkip), + dr.WithMaxKeep(s.config.MaxKeep), + dr.WithMaxMessageKeysPerSession(s.config.MaxMessageKeysPerSession), + dr.WithCrypto(crypto.EthereumCrypto{}), + ) + +} + // CreateBundle retrieves or creates an X3DH bundle given a private key func (s *EncryptionService) CreateBundle(privateKey *ecdsa.PrivateKey) (*Bundle, error) { ourIdentityKeyC := ecrypto.CompressPubkey(&privateKey.PublicKey) - installationIDs, err := s.persistence.GetActiveInstallations(maxInstallations-1, ourIdentityKeyC) + installationIDs, err := s.persistence.GetActiveInstallations(s.config.MaxInstallations-1, ourIdentityKeyC) if err != nil { return nil, err } - installationIDs = append(installationIDs, s.installationID) + installationIDs = append(installationIDs, s.config.InstallationID) bundleContainer, err := s.persistence.GetAnyPrivateBundle(ourIdentityKeyC, installationIDs) if err != nil { @@ -98,7 +123,7 @@ func (s *EncryptionService) CreateBundle(privateKey *ecdsa.PrivateKey) (*Bundle, // needs transaction/mutex to avoid creating multiple bundles // although not a problem - bundleContainer, err = NewBundleContainer(privateKey, s.installationID) + bundleContainer, err = NewBundleContainer(privateKey, s.config.InstallationID) if err != nil { return nil, err } @@ -182,7 +207,7 @@ func (s *EncryptionService) ProcessPublicBundle(myIdentityKey *ecdsa.PrivateKey, fromOurIdentity := identity != myIdentityStr for installationID := range signedPreKeys { - if installationID != s.installationID { + if installationID != s.config.InstallationID { installationIDs = append(installationIDs, installationID) response = append(response, IdentityAndIDPair{identity, installationID}) } @@ -204,7 +229,7 @@ func (s *EncryptionService) DecryptPayload(myIdentityKey *ecdsa.PrivateKey, thei s.mutex.Lock() defer s.mutex.Unlock() - msg := msgs[s.installationID] + msg := msgs[s.config.InstallationID] if msg == nil { msg = msgs[noInstallationID] } @@ -293,9 +318,9 @@ func (s *EncryptionService) createNewSession(drInfo *RatchetInfo, sk [32]byte, k keyPair, s.persistence.GetSessionStorage(), dr.WithKeysStorage(s.persistence.GetKeysStorage()), - dr.WithMaxSkip(maxSkip), - dr.WithMaxKeep(maxKeep), - dr.WithMaxMessageKeysPerSession(maxMessageKeysPerSession), + dr.WithMaxSkip(s.config.MaxSkip), + dr.WithMaxKeep(s.config.MaxKeep), + dr.WithMaxMessageKeysPerSession(s.config.MaxMessageKeysPerSession), dr.WithCrypto(crypto.EthereumCrypto{})) } else { session, err = dr.NewWithRemoteKey( @@ -304,9 +329,9 @@ func (s *EncryptionService) createNewSession(drInfo *RatchetInfo, sk [32]byte, k keyPair.PubKey, s.persistence.GetSessionStorage(), dr.WithKeysStorage(s.persistence.GetKeysStorage()), - dr.WithMaxSkip(maxSkip), - dr.WithMaxKeep(maxKeep), - dr.WithMaxMessageKeysPerSession(maxMessageKeysPerSession), + dr.WithMaxSkip(s.config.MaxSkip), + dr.WithMaxKeep(s.config.MaxKeep), + dr.WithMaxMessageKeysPerSession(s.config.MaxMessageKeysPerSession), dr.WithCrypto(crypto.EthereumCrypto{})) } @@ -327,17 +352,9 @@ func (s *EncryptionService) encryptUsingDR(theirIdentityKey *ecdsa.PublicKey, dr PubKey: publicKey, } - sessionStorage := s.persistence.GetSessionStorage() // Load session from store first - session, err = dr.Load( - drInfo.ID, - sessionStorage, - dr.WithKeysStorage(s.persistence.GetKeysStorage()), - dr.WithMaxSkip(maxSkip), - dr.WithMaxKeep(maxKeep), - dr.WithMaxMessageKeysPerSession(maxMessageKeysPerSession), - dr.WithCrypto(crypto.EthereumCrypto{}), - ) + session, err = s.getDRSession(drInfo.ID) + if err != nil { return nil, nil, err } @@ -379,16 +396,7 @@ func (s *EncryptionService) decryptUsingDR(theirIdentityKey *ecdsa.PublicKey, dr PubKey: publicKey, } - sessionStorage := s.persistence.GetSessionStorage() - session, err = dr.Load( - drInfo.ID, - sessionStorage, - dr.WithKeysStorage(s.persistence.GetKeysStorage()), - dr.WithMaxSkip(maxSkip), - dr.WithMaxKeep(maxKeep), - dr.WithMaxMessageKeysPerSession(maxMessageKeysPerSession), - dr.WithCrypto(crypto.EthereumCrypto{}), - ) + session, err = s.getDRSession(drInfo.ID) if err != nil { return nil, err } @@ -447,7 +455,7 @@ func (s *EncryptionService) EncryptPayload(theirIdentityKey *ecdsa.PublicKey, my theirIdentityKeyC := ecrypto.CompressPubkey(theirIdentityKey) - installationIDs, err := s.persistence.GetActiveInstallations(maxInstallations, theirIdentityKeyC) + installationIDs, err := s.persistence.GetActiveInstallations(s.config.MaxInstallations, theirIdentityKeyC) if err != nil { return nil, err } @@ -466,7 +474,7 @@ func (s *EncryptionService) EncryptPayload(theirIdentityKey *ecdsa.PublicKey, my response := make(map[string]*DirectMessageProtocol) for installationID, signedPreKeyContainer := range theirBundle.GetSignedPreKeys() { - if s.installationID == installationID { + if s.config.InstallationID == installationID { continue } @@ -516,7 +524,7 @@ func (s *EncryptionService) EncryptPayload(theirIdentityKey *ecdsa.PublicKey, my Id: theirSignedPreKey, } - drInfo, err = s.persistence.GetAnyRatchetInfo(theirIdentityKeyC, installationID) + drInfo, err = s.persistence.GetRatchetInfo(theirSignedPreKey, theirIdentityKeyC, installationID) if err != nil { return nil, err } diff --git a/services/shhext/chat/encryption_multi_device_test.go b/services/shhext/chat/encryption_multi_device_test.go index 7f0bb626c..80dc6e4db 100644 --- a/services/shhext/chat/encryption_multi_device_test.go +++ b/services/shhext/chat/encryption_multi_device_test.go @@ -1,6 +1,8 @@ package chat import ( + "crypto/ecdsa" + "fmt" "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/suite" "os" @@ -8,114 +10,106 @@ import ( "testing" ) +const ( + aliceUser = "alice" + bobUser = "bob" +) + func TestEncryptionServiceMultiDeviceSuite(t *testing.T) { suite.Run(t, new(EncryptionServiceMultiDeviceSuite)) } +type serviceAndKey struct { + encryptionServices []*EncryptionService + key *ecdsa.PrivateKey +} + type EncryptionServiceMultiDeviceSuite struct { suite.Suite - alice1 *EncryptionService - bob1 *EncryptionService - alice2 *EncryptionService - bob2 *EncryptionService - alice3 *EncryptionService + services map[string]*serviceAndKey +} + +func setupUser(user string, s *EncryptionServiceMultiDeviceSuite, n int) error { + key, err := crypto.GenerateKey() + if err != nil { + return err + } + + s.services[user] = &serviceAndKey{ + key: key, + encryptionServices: make([]*EncryptionService, n), + } + + for i := 0; i < n; i++ { + installationID := fmt.Sprintf("%s%d", user, i+1) + dbPath := fmt.Sprintf("/tmp/%s.db", installationID) + + os.Remove(dbPath) + + persistence, err := NewSQLLitePersistence(dbPath, "key") + if err != nil { + return err + } + + config := DefaultEncryptionServiceConfig(installationID) + config.MaxInstallations = n - 1 + + s.services[user].encryptionServices[i] = NewEncryptionService(persistence, config) + + } + + return nil } func (s *EncryptionServiceMultiDeviceSuite) SetupTest() { - const ( - aliceDBPath1 = "/tmp/alice1.db" - aliceDBKey1 = "alice1" - aliceDBPath2 = "/tmp/alice2.db" - aliceDBKey2 = "alice2" - aliceDBPath3 = "/tmp/alice3.db" - aliceDBKey3 = "alice3" - bobDBPath1 = "/tmp/bob1.db" - bobDBKey1 = "bob1" - bobDBPath2 = "/tmp/bob2.db" - bobDBKey2 = "bob2" - ) + s.services = make(map[string]*serviceAndKey) + err := setupUser(aliceUser, s, 4) + s.Require().NoError(err) - os.Remove(aliceDBPath1) - os.Remove(bobDBPath1) - os.Remove(aliceDBPath2) - os.Remove(bobDBPath2) - os.Remove(aliceDBPath3) - - alicePersistence1, err := NewSQLLitePersistence(aliceDBPath1, aliceDBKey1) - if err != nil { - panic(err) - } - - alicePersistence2, err := NewSQLLitePersistence(aliceDBPath2, aliceDBKey2) - if err != nil { - panic(err) - } - - alicePersistence3, err := NewSQLLitePersistence(aliceDBPath3, aliceDBKey3) - if err != nil { - panic(err) - } - - bobPersistence1, err := NewSQLLitePersistence(bobDBPath1, bobDBKey1) - if err != nil { - panic(err) - } - - bobPersistence2, err := NewSQLLitePersistence(bobDBPath2, bobDBKey2) - if err != nil { - panic(err) - } - - s.alice1 = NewEncryptionService(alicePersistence1, "alice1") - s.bob1 = NewEncryptionService(bobPersistence1, "bob1") - - s.alice2 = NewEncryptionService(alicePersistence2, "alice2") - s.bob2 = NewEncryptionService(bobPersistence2, "bob2") - - s.alice3 = NewEncryptionService(alicePersistence3, "alice3") + err = setupUser(bobUser, s, 4) + s.Require().NoError(err) } func (s *EncryptionServiceMultiDeviceSuite) TestProcessPublicBundle() { - aliceKey, err := crypto.GenerateKey() - s.Require().NoError(err) + aliceKey := s.services[aliceUser].key - alice2Bundle, err := s.alice2.CreateBundle(aliceKey) + alice2Bundle, err := s.services[aliceUser].encryptionServices[1].CreateBundle(aliceKey) s.Require().NoError(err) alice2Identity, err := ExtractIdentity(alice2Bundle) s.Require().NoError(err) - alice3Bundle, err := s.alice3.CreateBundle(aliceKey) + alice3Bundle, err := s.services[aliceUser].encryptionServices[2].CreateBundle(aliceKey) s.Require().NoError(err) alice3Identity, err := ExtractIdentity(alice2Bundle) s.Require().NoError(err) // Add alice2 bundle - response, err := s.alice1.ProcessPublicBundle(aliceKey, alice2Bundle) + response, err := s.services[aliceUser].encryptionServices[0].ProcessPublicBundle(aliceKey, alice2Bundle) s.Require().NoError(err) s.Require().Equal(IdentityAndIDPair{alice2Identity, "alice2"}, response[0]) // Add alice3 bundle - response, err = s.alice1.ProcessPublicBundle(aliceKey, alice3Bundle) + response, err = s.services[aliceUser].encryptionServices[0].ProcessPublicBundle(aliceKey, alice3Bundle) s.Require().NoError(err) s.Require().Equal(IdentityAndIDPair{alice3Identity, "alice3"}, response[0]) // No installation is enabled - alice1MergedBundle1, err := s.alice1.CreateBundle(aliceKey) + alice1MergedBundle1, err := s.services[aliceUser].encryptionServices[0].CreateBundle(aliceKey) s.Require().NoError(err) s.Require().Equal(1, len(alice1MergedBundle1.GetSignedPreKeys())) s.Require().NotNil(alice1MergedBundle1.GetSignedPreKeys()["alice1"]) // We enable the installations - err = s.alice1.EnableInstallation(&aliceKey.PublicKey, "alice2") + err = s.services[aliceUser].encryptionServices[0].EnableInstallation(&aliceKey.PublicKey, "alice2") s.Require().NoError(err) - err = s.alice1.EnableInstallation(&aliceKey.PublicKey, "alice3") + err = s.services[aliceUser].encryptionServices[0].EnableInstallation(&aliceKey.PublicKey, "alice3") s.Require().NoError(err) - alice1MergedBundle2, err := s.alice1.CreateBundle(aliceKey) + alice1MergedBundle2, err := s.services[aliceUser].encryptionServices[0].CreateBundle(aliceKey) s.Require().NoError(err) // We get back a bundle with all the installations @@ -124,7 +118,7 @@ func (s *EncryptionServiceMultiDeviceSuite) TestProcessPublicBundle() { s.Require().NotNil(alice1MergedBundle2.GetSignedPreKeys()["alice2"]) s.Require().NotNil(alice1MergedBundle2.GetSignedPreKeys()["alice3"]) - response, err = s.alice1.ProcessPublicBundle(aliceKey, alice1MergedBundle2) + response, err = s.services[aliceUser].encryptionServices[0].ProcessPublicBundle(aliceKey, alice1MergedBundle2) s.Require().NoError(err) sort.Slice(response, func(i, j int) bool { return response[i][1] < response[j][1] @@ -135,10 +129,10 @@ func (s *EncryptionServiceMultiDeviceSuite) TestProcessPublicBundle() { s.Require().Equal(IdentityAndIDPair{alice2Identity, "alice3"}, response[1]) // We disable the installations - err = s.alice1.DisableInstallation(&aliceKey.PublicKey, "alice2") + err = s.services[aliceUser].encryptionServices[0].DisableInstallation(&aliceKey.PublicKey, "alice2") s.Require().NoError(err) - alice1MergedBundle3, err := s.alice1.CreateBundle(aliceKey) + alice1MergedBundle3, err := s.services[aliceUser].encryptionServices[0].CreateBundle(aliceKey) s.Require().NoError(err) // We get back a bundle with all the installations @@ -152,25 +146,111 @@ func (s *EncryptionServiceMultiDeviceSuite) TestProcessPublicBundleOutOfOrder() s.Require().NoError(err) // Alice1 creates a bundle - alice1Bundle, err := s.alice1.CreateBundle(aliceKey) + alice1Bundle, err := s.services[aliceUser].encryptionServices[0].CreateBundle(aliceKey) s.Require().NoError(err) // Alice2 Receives the bundle - _, err = s.alice2.ProcessPublicBundle(aliceKey, alice1Bundle) + _, err = s.services[aliceUser].encryptionServices[1].ProcessPublicBundle(aliceKey, alice1Bundle) s.Require().NoError(err) // Alice2 Creates a Bundle - _, err = s.alice2.CreateBundle(aliceKey) + _, err = s.services[aliceUser].encryptionServices[1].CreateBundle(aliceKey) s.Require().NoError(err) // We enable the installation - err = s.alice2.EnableInstallation(&aliceKey.PublicKey, "alice1") + err = s.services[aliceUser].encryptionServices[1].EnableInstallation(&aliceKey.PublicKey, "alice1") s.Require().NoError(err) // It should contain both bundles - alice2MergedBundle1, err := s.alice2.CreateBundle(aliceKey) + alice2MergedBundle1, err := s.services[aliceUser].encryptionServices[1].CreateBundle(aliceKey) s.Require().NoError(err) s.Require().NotNil(alice2MergedBundle1.GetSignedPreKeys()["alice1"]) s.Require().NotNil(alice2MergedBundle1.GetSignedPreKeys()["alice2"]) } + +func pairDevices(s *serviceAndKey, target int) error { + device := s.encryptionServices[target] + for i := 0; i < len(s.encryptionServices); i++ { + b, err := s.encryptionServices[i].CreateBundle(s.key) + + if err != nil { + return err + } + + _, err = device.ProcessPublicBundle(s.key, b) + if err != nil { + return err + } + + err = device.EnableInstallation(&s.key.PublicKey, s.encryptionServices[i].config.InstallationID) + if err != nil { + return nil + } + } + return nil +} + +func (s *EncryptionServiceMultiDeviceSuite) TestMaxDevices() { + err := pairDevices(s.services[aliceUser], 0) + s.Require().NoError(err) + alice1 := s.services[aliceUser].encryptionServices[0] + bob1 := s.services[bobUser].encryptionServices[0] + aliceKey := s.services[aliceUser].key + bobKey := s.services[bobUser].key + + // Check bundle is ok + // No installation is enabled + aliceBundle, err := alice1.CreateBundle(aliceKey) + s.Require().NoError(err) + + // Check all installations are correctly working, and that the oldest device is not there + preKeys := aliceBundle.GetSignedPreKeys() + s.Require().Equal(3, len(preKeys)) + s.Require().NotNil(preKeys["alice1"]) + // alice2 being the oldest device is rotated out, as we reached the maximum + s.Require().Nil(preKeys["alice2"]) + s.Require().NotNil(preKeys["alice3"]) + s.Require().NotNil(preKeys["alice4"]) + + // We propagate this to bob + _, err = bob1.ProcessPublicBundle(bobKey, aliceBundle) + s.Require().NoError(err) + + // Bob sends a message to alice + payload, err := bob1.EncryptPayload(&aliceKey.PublicKey, bobKey, []byte("test")) + s.Require().NoError(err) + s.Require().Equal(3, len(payload)) + s.Require().NotNil(payload["alice1"]) + s.Require().NotNil(payload["alice3"]) + s.Require().NotNil(payload["alice4"]) + + // We disable the last installation + err = s.services[aliceUser].encryptionServices[0].DisableInstallation(&aliceKey.PublicKey, "alice4") + s.Require().NoError(err) + + // We check the bundle is updated + aliceBundle, err = alice1.CreateBundle(aliceKey) + s.Require().NoError(err) + + // Check all installations are there + preKeys = aliceBundle.GetSignedPreKeys() + s.Require().Equal(3, len(preKeys)) + s.Require().NotNil(preKeys["alice1"]) + s.Require().NotNil(preKeys["alice2"]) + s.Require().NotNil(preKeys["alice3"]) + // alice4 is disabled at this point, alice2 is back in + s.Require().Nil(preKeys["alice4"]) + + // We propagate this to bob + _, err = bob1.ProcessPublicBundle(bobKey, aliceBundle) + s.Require().NoError(err) + + // Bob sends a message to alice + payload, err = bob1.EncryptPayload(&aliceKey.PublicKey, bobKey, []byte("test")) + s.Require().NoError(err) + s.Require().Equal(3, len(payload)) + s.Require().NotNil(payload["alice1"]) + s.Require().NotNil(payload["alice2"]) + s.Require().NotNil(payload["alice3"]) +} diff --git a/services/shhext/chat/encryption_test.go b/services/shhext/chat/encryption_test.go index de28c3ac7..29ae76626 100644 --- a/services/shhext/chat/encryption_test.go +++ b/services/shhext/chat/encryption_test.go @@ -47,8 +47,8 @@ func (s *EncryptionServiceTestSuite) initDatabases() { panic(err) } - s.alice = NewEncryptionService(alicePersistence, aliceInstallationID) - s.bob = NewEncryptionService(bobPersistence, bobInstallationID) + s.alice = NewEncryptionService(alicePersistence, DefaultEncryptionServiceConfig(aliceInstallationID)) + s.bob = NewEncryptionService(bobPersistence, DefaultEncryptionServiceConfig(bobInstallationID)) } func (s *EncryptionServiceTestSuite) SetupTest() { @@ -346,7 +346,7 @@ func (s *EncryptionServiceTestSuite) TestMaxSkipKeys() { // Bob sends a message - for i := 0; i < maxSkip; i++ { + for i := 0; i < s.alice.config.MaxSkip; i++ { _, err = s.bob.EncryptPayload(&aliceKey.PublicKey, bobKey, bobText) s.Require().NoError(err) } @@ -401,7 +401,7 @@ func (s *EncryptionServiceTestSuite) TestMaxSkipKeysError() { // Bob sends a message - for i := 0; i < maxSkip+1; i++ { + for i := 0; i < s.alice.config.MaxSkip+1; i++ { _, err = s.bob.EncryptPayload(&aliceKey.PublicKey, bobKey, bobText) s.Require().NoError(err) } @@ -442,7 +442,7 @@ func (s *EncryptionServiceTestSuite) TestMaxMessageKeysPerSession() { // We create just enough messages so that the first key should be deleted - nMessages := maxMessageKeysPerSession + maxMessageKeysPerSession/maxSkip + 2 + nMessages := s.alice.config.MaxMessageKeysPerSession + s.alice.config.MaxMessageKeysPerSession/s.alice.config.MaxSkip + 2 messages := make([]map[string]*DirectMessageProtocol, nMessages) for i := 0; i < nMessages; i++ { m, err := s.bob.EncryptPayload(&aliceKey.PublicKey, bobKey, bobText) @@ -451,7 +451,7 @@ func (s *EncryptionServiceTestSuite) TestMaxMessageKeysPerSession() { messages[i] = m // We decrypt some messages otherwise we hit maxSkip limit - if i%maxSkip == 0 { + if i%s.alice.config.MaxSkip == 0 { _, err = s.alice.DecryptPayload(aliceKey, &bobKey.PublicKey, bobInstallationID, m) s.Require().NoError(err) } @@ -499,8 +499,8 @@ func (s *EncryptionServiceTestSuite) TestMaxKeep() { s.Require().NoError(err) // We decrypt all messages but 1 & 2 - messages := make([]map[string]*DirectMessageProtocol, maxKeep) - for i := 0; i < maxKeep; i++ { + messages := make([]map[string]*DirectMessageProtocol, s.alice.config.MaxKeep) + for i := 0; i < s.alice.config.MaxKeep; i++ { m, err := s.bob.EncryptPayload(&aliceKey.PublicKey, bobKey, bobText) messages[i] = m s.Require().NoError(err) diff --git a/services/shhext/chat/persistence.go b/services/shhext/chat/persistence.go index b274fec05..cc44de086 100644 --- a/services/shhext/chat/persistence.go +++ b/services/shhext/chat/persistence.go @@ -50,7 +50,7 @@ type PersistenceService interface { RatchetInfoConfirmed([]byte, []byte, string) error // GetActiveInstallations returns the active installations for a given identity. - GetActiveInstallations(maxInstallations uint, identity []byte) ([]string, error) + GetActiveInstallations(maxInstallations int, identity []byte) ([]string, error) // AddInstallations adds the installations for a given identity. AddInstallations(identity []byte, timestamp int64, installationIDs []string, enabled bool) error // EnableInstallation enables the installation. diff --git a/services/shhext/chat/protocol.go b/services/shhext/chat/protocol.go index 569956b5e..9237b1b22 100644 --- a/services/shhext/chat/protocol.go +++ b/services/shhext/chat/protocol.go @@ -51,7 +51,7 @@ func (p *ProtocolService) addBundleAndMarshal(myIdentityKey *ecdsa.PrivateKey, m func (p *ProtocolService) BuildPublicMessage(myIdentityKey *ecdsa.PrivateKey, payload []byte) ([]byte, error) { // Build message not encrypted protocolMessage := &ProtocolMessage{ - InstallationId: p.encryption.installationID, + InstallationId: p.encryption.config.InstallationID, PublicMessage: payload, } @@ -71,7 +71,7 @@ func (p *ProtocolService) BuildDirectMessage(myIdentityKey *ecdsa.PrivateKey, pa // Build message protocolMessage := &ProtocolMessage{ - InstallationId: p.encryption.installationID, + InstallationId: p.encryption.config.InstallationID, DirectMessage: encryptionResponse, } @@ -98,7 +98,7 @@ func (p *ProtocolService) BuildPairingMessage(myIdentityKey *ecdsa.PrivateKey, p // Build message protocolMessage := &ProtocolMessage{ - InstallationId: p.encryption.installationID, + InstallationId: p.encryption.config.InstallationID, DirectMessage: encryptionResponse, } diff --git a/services/shhext/chat/protocol_test.go b/services/shhext/chat/protocol_test.go index fed946234..1eee68db2 100644 --- a/services/shhext/chat/protocol_test.go +++ b/services/shhext/chat/protocol_test.go @@ -38,8 +38,8 @@ func (s *ProtocolServiceTestSuite) SetupTest() { panic(err) } - s.alice = NewProtocolService(NewEncryptionService(alicePersistence, "1")) - s.bob = NewProtocolService(NewEncryptionService(bobPersistence, "2")) + s.alice = NewProtocolService(NewEncryptionService(alicePersistence, DefaultEncryptionServiceConfig("1"))) + s.bob = NewProtocolService(NewEncryptionService(bobPersistence, DefaultEncryptionServiceConfig("2"))) } func (s *ProtocolServiceTestSuite) TestBuildDirectMessage() { diff --git a/services/shhext/chat/sql_lite_persistence.go b/services/shhext/chat/sql_lite_persistence.go index 7a1a30ded..16d20fab4 100644 --- a/services/shhext/chat/sql_lite_persistence.go +++ b/services/shhext/chat/sql_lite_persistence.go @@ -709,7 +709,7 @@ func (s *SQLLiteSessionStorage) Load(id []byte) (*dr.State, error) { } // GetActiveInstallations returns the active installations for a given identity -func (s *SQLLitePersistence) GetActiveInstallations(maxInstallations uint, identity []byte) ([]string, error) { +func (s *SQLLitePersistence) GetActiveInstallations(maxInstallations int, identity []byte) ([]string, error) { stmt, err := s.db.Prepare("SELECT installation_id FROM installations WHERE enabled = 1 AND identity = ? ORDER BY timestamp DESC LIMIT ?") if err != nil { return nil, err diff --git a/services/shhext/service.go b/services/shhext/service.go index 1b43a0760..4bdb444b1 100644 --- a/services/shhext/service.go +++ b/services/shhext/service.go @@ -102,7 +102,7 @@ func (s *Service) InitProtocol(address string, password string) error { if err != nil { return err } - s.protocol = chat.NewProtocolService(chat.NewEncryptionService(persistence, s.installationID)) + s.protocol = chat.NewProtocolService(chat.NewEncryptionService(persistence, chat.DefaultEncryptionServiceConfig(s.installationID))) return nil }