From afc3017e07676ed70aaf86f5b0449af95fe7cbdc Mon Sep 17 00:00:00 2001 From: Andrea Maria Piana Date: Wed, 5 Dec 2018 09:22:49 +0100 Subject: [PATCH] Notify user when the device is missing (#1298) * Notify user when the device is missing * Update services/shhext/chat/encryption.go Co-Authored-By: cammellos --- VERSION | 2 +- _assets/ci/Jenkinsfile | 2 +- services/shhext/api.go | 15 +++-------- services/shhext/chat/encryption.go | 7 +++--- services/shhext/chat/encryption_test.go | 33 +++++++++++++++++++++++++ services/shhext/chat/protocol.go | 32 ++++++++++-------------- services/shhext/chat/protocol_test.go | 9 ++++--- services/shhext/service.go | 10 +++++++- 8 files changed, 69 insertions(+), 41 deletions(-) diff --git a/VERSION b/VERSION index e1edef6db..539c147a4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.18.0-beta +0.18.1-beta diff --git a/_assets/ci/Jenkinsfile b/_assets/ci/Jenkinsfile index ae411aec8..07248d232 100644 --- a/_assets/ci/Jenkinsfile +++ b/_assets/ci/Jenkinsfile @@ -98,7 +98,7 @@ pipeline { usernameVariable: 'GITHUB_USER', passwordVariable: 'GITHUB_TOKEN' ]]) { - sh "yes | make release release_branch=${lib.gitBranch()}" + sh "yes | make release RELEASE_BRANCH=${lib.gitBranch()}" } sh 'make clean-release' } diff --git a/services/shhext/api.go b/services/shhext/api.go index 9d31a575a..a6bd10ecb 100644 --- a/services/shhext/api.go +++ b/services/shhext/api.go @@ -416,11 +416,9 @@ func (api *PublicAPI) processPFSMessage(msg *whisper.Message) error { response, err := api.service.protocol.HandleMessage(privateKey, publicKey, msg.Payload) - handler := EnvelopeSignalHandler{} - // Notify that someone tried to contact us using an invalid bundle - if err == chat.ErrSessionNotFound { - api.log.Warn("Session not found, sending signal", "err", err) + if err == chat.ErrDeviceNotFound && privateKey.PublicKey != *publicKey { + api.log.Warn("Device not found, sending signal", "err", err) keyString := fmt.Sprintf("0x%x", crypto.FromECDSAPub(publicKey)) handler := EnvelopeSignalHandler{} handler.DecryptMessageFailed(keyString) @@ -432,14 +430,7 @@ func (api *PublicAPI) processPFSMessage(msg *whisper.Message) error { } // Add unencrypted payload - msg.Payload = response.Message - - // Notify of added bundles - if response.AddedBundles != nil { - for _, bundle := range response.AddedBundles { - handler.BundleAdded(bundle[0], bundle[1]) - } - } + msg.Payload = response return nil } diff --git a/services/shhext/chat/encryption.go b/services/shhext/chat/encryption.go index ab20abf61..2a0933f8a 100644 --- a/services/shhext/chat/encryption.go +++ b/services/shhext/chat/encryption.go @@ -18,6 +18,7 @@ import ( ) var ErrSessionNotFound = errors.New("session not found") +var ErrDeviceNotFound = errors.New("device not found") // If we have no bundles, we use a constant so that the message can reach any device. const noInstallationID = "none" @@ -53,7 +54,7 @@ func DefaultEncryptionServiceConfig(installationID string) EncryptionServiceConf MaxSkip: 1000, MaxKeep: 3000, MaxMessageKeysPerSession: 2000, - BundleRefreshInterval: 14 * 24 * 60 * 60 * 1000, + BundleRefreshInterval: 6 * 60 * 60 * 1000, InstallationID: installationID, } } @@ -238,8 +239,8 @@ func (s *EncryptionService) DecryptPayload(myIdentityKey *ecdsa.PrivateKey, thei } // We should not be sending a signal if it's coming from us, as we receive our own messages - if msg == nil { - return nil, ErrSessionNotFound + if msg == nil && *theirIdentityKey != myIdentityKey.PublicKey { + return nil, ErrDeviceNotFound } payload := msg.GetPayload() diff --git a/services/shhext/chat/encryption_test.go b/services/shhext/chat/encryption_test.go index 7c5ee825a..ee309ceda 100644 --- a/services/shhext/chat/encryption_test.go +++ b/services/shhext/chat/encryption_test.go @@ -770,6 +770,39 @@ func (s *EncryptionServiceTestSuite) TestBundleNotExisting() { s.Equal(ErrSessionNotFound, err) } +// Device is not included in the bundle +func (s *EncryptionServiceTestSuite) TestDeviceNotIncluded() { + bobDevice2InstallationID := "bob2" + + bobKey, err := crypto.GenerateKey() + s.Require().NoError(err) + + aliceKey, err := crypto.GenerateKey() + s.Require().NoError(err) + + // Create a bundle without saving it + bobBundleContainer, err := NewBundleContainer(bobKey, bobDevice2InstallationID) + s.Require().NoError(err) + + err = SignBundle(bobKey, bobBundleContainer) + s.Require().NoError(err) + + bobBundle := bobBundleContainer.GetBundle() + + // We add bob bundle + _, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle) + s.Require().NoError(err) + + // Alice sends a message + aliceMessage, err := s.alice.EncryptPayload(&bobKey.PublicKey, aliceKey, []byte("does not matter")) + s.Require().NoError(err) + + // Bob receives the message, and returns a bundlenotfound error + _, err = s.bob.DecryptPayload(bobKey, &aliceKey.PublicKey, aliceInstallationID, aliceMessage) + s.Require().Error(err) + s.Equal(ErrDeviceNotFound, err) +} + // A new bundle has been received func (s *EncryptionServiceTestSuite) TestRefreshedBundle() { diff --git a/services/shhext/chat/protocol.go b/services/shhext/chat/protocol.go index 9237b1b22..2e9906991 100644 --- a/services/shhext/chat/protocol.go +++ b/services/shhext/chat/protocol.go @@ -9,21 +9,18 @@ import ( ) type ProtocolService struct { - log log.Logger - encryption *EncryptionService - Enabled bool -} - -type HandleMessageResponse struct { - AddedBundles []IdentityAndIDPair - Message []byte + log log.Logger + encryption *EncryptionService + addedBundlesHandler func([]IdentityAndIDPair) + Enabled bool } // NewProtocolService creates a new ProtocolService instance -func NewProtocolService(encryption *EncryptionService) *ProtocolService { +func NewProtocolService(encryption *EncryptionService, addedBundlesHandler func([]IdentityAndIDPair)) *ProtocolService { return &ProtocolService{ - log: log.New("package", "status-go/services/sshext.chat"), - encryption: encryption, + log: log.New("package", "status-go/services/sshext.chat"), + encryption: encryption, + addedBundlesHandler: addedBundlesHandler, } } @@ -126,13 +123,11 @@ func (p *ProtocolService) DisableInstallation(myIdentityKey *ecdsa.PublicKey, in } // HandleMessage unmarshals a message and processes it, decrypting it if it is a 1:1 message. -func (p *ProtocolService) HandleMessage(myIdentityKey *ecdsa.PrivateKey, theirPublicKey *ecdsa.PublicKey, payload []byte) (*HandleMessageResponse, error) { +func (p *ProtocolService) HandleMessage(myIdentityKey *ecdsa.PrivateKey, theirPublicKey *ecdsa.PublicKey, payload []byte) ([]byte, error) { if p.encryption == nil { return nil, errors.New("encryption service not initialized") } - response := &HandleMessageResponse{} - // Unmarshal message protocolMessage := &ProtocolMessage{} @@ -147,14 +142,14 @@ func (p *ProtocolService) HandleMessage(myIdentityKey *ecdsa.PrivateKey, theirPu if err != nil { return nil, err } - response.AddedBundles = addedBundles + + p.addedBundlesHandler(addedBundles) } // Check if it's a public message if publicMessage := protocolMessage.GetPublicMessage(); publicMessage != nil { - response.Message = publicMessage // Nothing to do, as already in cleartext - return response, nil + return publicMessage, nil } // Decrypt message @@ -163,9 +158,8 @@ func (p *ProtocolService) HandleMessage(myIdentityKey *ecdsa.PrivateKey, theirPu if err != nil { return nil, err } - response.Message = message - return response, nil + return message, nil } // Return error diff --git a/services/shhext/chat/protocol_test.go b/services/shhext/chat/protocol_test.go index 1eee68db2..c1f9c04f6 100644 --- a/services/shhext/chat/protocol_test.go +++ b/services/shhext/chat/protocol_test.go @@ -38,8 +38,10 @@ func (s *ProtocolServiceTestSuite) SetupTest() { panic(err) } - s.alice = NewProtocolService(NewEncryptionService(alicePersistence, DefaultEncryptionServiceConfig("1"))) - s.bob = NewProtocolService(NewEncryptionService(bobPersistence, DefaultEncryptionServiceConfig("2"))) + addedBundlesHandler := func(addedBundles []IdentityAndIDPair) {} + + s.alice = NewProtocolService(NewEncryptionService(alicePersistence, DefaultEncryptionServiceConfig("1")), addedBundlesHandler) + s.bob = NewProtocolService(NewEncryptionService(bobPersistence, DefaultEncryptionServiceConfig("2")), addedBundlesHandler) } func (s *ProtocolServiceTestSuite) TestBuildDirectMessage() { @@ -102,9 +104,8 @@ func (s *ProtocolServiceTestSuite) TestBuildAndReadDirectMessage() { s.NoError(err) // Bob is able to decrypt the message - response, err := s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, marshaledMsg[&bobKey.PublicKey]) + unmarshaledMsg, err := s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, marshaledMsg[&bobKey.PublicKey]) s.NoError(err) - unmarshaledMsg := response.Message s.NotNil(unmarshaledMsg) diff --git a/services/shhext/service.go b/services/shhext/service.go index 00d51a0ef..595053284 100644 --- a/services/shhext/service.go +++ b/services/shhext/service.go @@ -118,7 +118,15 @@ func (s *Service) InitProtocol(address string, password string) error { if err != nil { return err } - s.protocol = chat.NewProtocolService(chat.NewEncryptionService(persistence, chat.DefaultEncryptionServiceConfig(s.installationID))) + + addedBundlesHandler := func(addedBundles []chat.IdentityAndIDPair) { + handler := EnvelopeSignalHandler{} + for _, bundle := range addedBundles { + handler.BundleAdded(bundle[0], bundle[1]) + } + } + + s.protocol = chat.NewProtocolService(chat.NewEncryptionService(persistence, chat.DefaultEncryptionServiceConfig(s.installationID)), addedBundlesHandler) return nil }