Skip to content

Commit

Permalink
Add versioning & tests, migrate db files (#1293)
Browse files Browse the repository at this point in the history
We are preparing for the release of this to general public, so a few
things have been added:

1) Add versioning for bundles, and make refresh interval configurable
2) Move files to installationID so no metadata is leaked
3) Re-key using user password db
  • Loading branch information
cammellos authored Nov 28, 2018
1 parent e60dbe3 commit 38bb4d8
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 74 deletions.
5 changes: 4 additions & 1 deletion services/shhext/chat/encryption.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type EncryptionServiceConfig struct {
MaxKeep int
// How many keys do we store in total per session.
MaxMessageKeysPerSession int
// How long before we refresh the interval in milliseconds
BundleRefreshInterval int64
}

type IdentityAndIDPair [2]string
Expand All @@ -51,6 +53,7 @@ func DefaultEncryptionServiceConfig(installationID string) EncryptionServiceConf
MaxSkip: 1000,
MaxKeep: 3000,
MaxMessageKeysPerSession: 2000,
BundleRefreshInterval: 14 * 24 * 60 * 60 * 1000,
InstallationID: installationID,
}
}
Expand Down Expand Up @@ -107,7 +110,7 @@ func (s *EncryptionService) CreateBundle(privateKey *ecdsa.PrivateKey) (*Bundle,
}

// If the bundle has expired we create a new one
if bundleContainer != nil && bundleContainer.GetBundle().Timestamp < time.Now().AddDate(0, 0, -14).UnixNano() {
if bundleContainer != nil && bundleContainer.GetBundle().Timestamp < time.Now().Add(-1*time.Duration(s.config.BundleRefreshInterval)*time.Millisecond).UnixNano() {
// Mark sessions has expired
if err := s.persistence.MarkBundleExpired(bundleContainer.GetBundle().GetIdentity()); err != nil {
return nil, err
Expand Down
79 changes: 53 additions & 26 deletions services/shhext/chat/encryption_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/ecdsa"
"errors"
"fmt"
"io/ioutil"
"math/rand"
"os"
"reflect"
Expand All @@ -25,16 +26,33 @@ func TestEncryptionServiceTestSuite(t *testing.T) {

type EncryptionServiceTestSuite struct {
suite.Suite
alice *EncryptionService
bob *EncryptionService
alice *EncryptionService
bob *EncryptionService
aliceDBPath string
bobDBPath string
}

func (s *EncryptionServiceTestSuite) initDatabases() {
func (s *EncryptionServiceTestSuite) initDatabases(baseConfig *EncryptionServiceConfig) {

aliceDBFile, err := ioutil.TempFile(os.TempDir(), "alice")
s.Require().NoError(err)
aliceDBPath := aliceDBFile.Name()

bobDBFile, err := ioutil.TempFile(os.TempDir(), "bob")
s.Require().NoError(err)
bobDBPath := bobDBFile.Name()

s.aliceDBPath = aliceDBPath
s.bobDBPath = bobDBPath

if baseConfig == nil {
config := DefaultEncryptionServiceConfig(aliceInstallationID)
baseConfig = &config
}

const (
aliceDBPath = "/tmp/alice.db"
aliceDBKey = "alice"
bobDBPath = "/tmp/bob.db"
bobDBKey = "bob"
aliceDBKey = "alice"
bobDBKey = "bob"
)

alicePersistence, err := NewSQLLitePersistence(aliceDBPath, aliceDBKey)
Expand All @@ -47,14 +65,20 @@ func (s *EncryptionServiceTestSuite) initDatabases() {
panic(err)
}

s.alice = NewEncryptionService(alicePersistence, DefaultEncryptionServiceConfig(aliceInstallationID))
s.bob = NewEncryptionService(bobPersistence, DefaultEncryptionServiceConfig(bobInstallationID))
baseConfig.InstallationID = aliceInstallationID
s.alice = NewEncryptionService(alicePersistence, *baseConfig)

baseConfig.InstallationID = bobInstallationID
s.bob = NewEncryptionService(bobPersistence, *baseConfig)
}

func (s *EncryptionServiceTestSuite) SetupTest() {
os.Remove("/tmp/alice.db")
os.Remove("/tmp/bob.db")
s.initDatabases()
s.initDatabases(nil)
}

func (s *EncryptionServiceTestSuite) TearDownTest() {
os.Remove(s.aliceDBPath)
os.Remove(s.bobDBPath)
}

func (s *EncryptionServiceTestSuite) TestCreateBundle() {
Expand Down Expand Up @@ -749,30 +773,33 @@ func (s *EncryptionServiceTestSuite) TestBundleNotExisting() {
// A new bundle has been received
func (s *EncryptionServiceTestSuite) TestRefreshedBundle() {

config := DefaultEncryptionServiceConfig("none")
// Set up refresh interval to "always"
config.BundleRefreshInterval = 1000

s.initDatabases(&config)

bobKey, err := crypto.GenerateKey()
s.Require().NoError(err)

aliceKey, err := crypto.GenerateKey()
s.Require().NoError(err)

// Create bundles
bobBundle1, err := NewBundleContainer(bobKey, bobInstallationID)
bobBundle1, err := s.bob.CreateBundle(bobKey)
s.Require().NoError(err)
s.Require().Equal(uint32(1), bobBundle1.GetSignedPreKeys()[bobInstallationID].GetVersion())

err = SignBundle(bobKey, bobBundle1)
s.Require().NoError(err)
// Sleep the required time so that bundle is refreshed
time.Sleep(time.Duration(config.BundleRefreshInterval) * time.Millisecond)

bobBundle2, err := NewBundleContainer(bobKey, bobInstallationID)
s.Require().NoError(err)
// We set the version

bobBundle2.GetBundle().GetSignedPreKeys()[bobInstallationID].Version = 1

err = SignBundle(bobKey, bobBundle2)
// Create bundles
bobBundle2, err := s.bob.CreateBundle(bobKey)
s.Require().NoError(err)
s.Require().Equal(uint32(2), bobBundle2.GetSignedPreKeys()[bobInstallationID].GetVersion())

// We add the first bob bundle
_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle1.GetBundle())
_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle1)
s.Require().NoError(err)

// Alice sends a message
Expand All @@ -786,10 +813,10 @@ func (s *EncryptionServiceTestSuite) TestRefreshedBundle() {

x3dhHeader1 := installationResponse1.GetX3DHHeader()
s.NotNil(x3dhHeader1)
s.Equal(bobBundle1.GetBundle().GetSignedPreKeys()[bobInstallationID].GetSignedPreKey(), x3dhHeader1.GetId())
s.Equal(bobBundle1.GetSignedPreKeys()[bobInstallationID].GetSignedPreKey(), x3dhHeader1.GetId())

// We add the second bob bundle
_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle2.GetBundle())
_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle2)
s.Require().NoError(err)

// Alice sends a message
Expand All @@ -803,6 +830,6 @@ func (s *EncryptionServiceTestSuite) TestRefreshedBundle() {

x3dhHeader2 := installationResponse2.GetX3DHHeader()
s.NotNil(x3dhHeader2)
s.Equal(bobBundle2.GetBundle().GetSignedPreKeys()[bobInstallationID].GetSignedPreKey(), x3dhHeader2.GetId())
s.Equal(bobBundle2.GetSignedPreKeys()[bobInstallationID].GetSignedPreKey(), x3dhHeader2.GetId())

}
Loading

0 comments on commit 38bb4d8

Please sign in to comment.