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 <andrea.maria.piana@gmail.com>
This commit is contained in:
Andrea Maria Piana 2018-12-05 09:22:49 +01:00 committed by GitHub
parent 49cfcd3e24
commit afc3017e07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 69 additions and 41 deletions

View File

@ -1 +1 @@
0.18.0-beta 0.18.1-beta

View File

@ -98,7 +98,7 @@ pipeline {
usernameVariable: 'GITHUB_USER', usernameVariable: 'GITHUB_USER',
passwordVariable: 'GITHUB_TOKEN' passwordVariable: 'GITHUB_TOKEN'
]]) { ]]) {
sh "yes | make release release_branch=${lib.gitBranch()}" sh "yes | make release RELEASE_BRANCH=${lib.gitBranch()}"
} }
sh 'make clean-release' sh 'make clean-release'
} }

View File

@ -416,11 +416,9 @@ func (api *PublicAPI) processPFSMessage(msg *whisper.Message) error {
response, err := api.service.protocol.HandleMessage(privateKey, publicKey, msg.Payload) response, err := api.service.protocol.HandleMessage(privateKey, publicKey, msg.Payload)
handler := EnvelopeSignalHandler{}
// Notify that someone tried to contact us using an invalid bundle // Notify that someone tried to contact us using an invalid bundle
if err == chat.ErrSessionNotFound { if err == chat.ErrDeviceNotFound && privateKey.PublicKey != *publicKey {
api.log.Warn("Session not found, sending signal", "err", err) api.log.Warn("Device not found, sending signal", "err", err)
keyString := fmt.Sprintf("0x%x", crypto.FromECDSAPub(publicKey)) keyString := fmt.Sprintf("0x%x", crypto.FromECDSAPub(publicKey))
handler := EnvelopeSignalHandler{} handler := EnvelopeSignalHandler{}
handler.DecryptMessageFailed(keyString) handler.DecryptMessageFailed(keyString)
@ -432,14 +430,7 @@ func (api *PublicAPI) processPFSMessage(msg *whisper.Message) error {
} }
// Add unencrypted payload // Add unencrypted payload
msg.Payload = response.Message msg.Payload = response
// Notify of added bundles
if response.AddedBundles != nil {
for _, bundle := range response.AddedBundles {
handler.BundleAdded(bundle[0], bundle[1])
}
}
return nil return nil
} }

View File

@ -18,6 +18,7 @@ import (
) )
var ErrSessionNotFound = errors.New("session not found") 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. // If we have no bundles, we use a constant so that the message can reach any device.
const noInstallationID = "none" const noInstallationID = "none"
@ -53,7 +54,7 @@ func DefaultEncryptionServiceConfig(installationID string) EncryptionServiceConf
MaxSkip: 1000, MaxSkip: 1000,
MaxKeep: 3000, MaxKeep: 3000,
MaxMessageKeysPerSession: 2000, MaxMessageKeysPerSession: 2000,
BundleRefreshInterval: 14 * 24 * 60 * 60 * 1000, BundleRefreshInterval: 6 * 60 * 60 * 1000,
InstallationID: installationID, 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 // We should not be sending a signal if it's coming from us, as we receive our own messages
if msg == nil { if msg == nil && *theirIdentityKey != myIdentityKey.PublicKey {
return nil, ErrSessionNotFound return nil, ErrDeviceNotFound
} }
payload := msg.GetPayload() payload := msg.GetPayload()

View File

@ -770,6 +770,39 @@ func (s *EncryptionServiceTestSuite) TestBundleNotExisting() {
s.Equal(ErrSessionNotFound, err) 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 // A new bundle has been received
func (s *EncryptionServiceTestSuite) TestRefreshedBundle() { func (s *EncryptionServiceTestSuite) TestRefreshedBundle() {

View File

@ -11,19 +11,16 @@ import (
type ProtocolService struct { type ProtocolService struct {
log log.Logger log log.Logger
encryption *EncryptionService encryption *EncryptionService
addedBundlesHandler func([]IdentityAndIDPair)
Enabled bool Enabled bool
} }
type HandleMessageResponse struct {
AddedBundles []IdentityAndIDPair
Message []byte
}
// NewProtocolService creates a new ProtocolService instance // NewProtocolService creates a new ProtocolService instance
func NewProtocolService(encryption *EncryptionService) *ProtocolService { func NewProtocolService(encryption *EncryptionService, addedBundlesHandler func([]IdentityAndIDPair)) *ProtocolService {
return &ProtocolService{ return &ProtocolService{
log: log.New("package", "status-go/services/sshext.chat"), log: log.New("package", "status-go/services/sshext.chat"),
encryption: encryption, 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. // 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 { if p.encryption == nil {
return nil, errors.New("encryption service not initialized") return nil, errors.New("encryption service not initialized")
} }
response := &HandleMessageResponse{}
// Unmarshal message // Unmarshal message
protocolMessage := &ProtocolMessage{} protocolMessage := &ProtocolMessage{}
@ -147,14 +142,14 @@ func (p *ProtocolService) HandleMessage(myIdentityKey *ecdsa.PrivateKey, theirPu
if err != nil { if err != nil {
return nil, err return nil, err
} }
response.AddedBundles = addedBundles
p.addedBundlesHandler(addedBundles)
} }
// Check if it's a public message // Check if it's a public message
if publicMessage := protocolMessage.GetPublicMessage(); publicMessage != nil { if publicMessage := protocolMessage.GetPublicMessage(); publicMessage != nil {
response.Message = publicMessage
// Nothing to do, as already in cleartext // Nothing to do, as already in cleartext
return response, nil return publicMessage, nil
} }
// Decrypt message // Decrypt message
@ -163,9 +158,8 @@ func (p *ProtocolService) HandleMessage(myIdentityKey *ecdsa.PrivateKey, theirPu
if err != nil { if err != nil {
return nil, err return nil, err
} }
response.Message = message
return response, nil return message, nil
} }
// Return error // Return error

View File

@ -38,8 +38,10 @@ func (s *ProtocolServiceTestSuite) SetupTest() {
panic(err) panic(err)
} }
s.alice = NewProtocolService(NewEncryptionService(alicePersistence, DefaultEncryptionServiceConfig("1"))) addedBundlesHandler := func(addedBundles []IdentityAndIDPair) {}
s.bob = NewProtocolService(NewEncryptionService(bobPersistence, DefaultEncryptionServiceConfig("2")))
s.alice = NewProtocolService(NewEncryptionService(alicePersistence, DefaultEncryptionServiceConfig("1")), addedBundlesHandler)
s.bob = NewProtocolService(NewEncryptionService(bobPersistence, DefaultEncryptionServiceConfig("2")), addedBundlesHandler)
} }
func (s *ProtocolServiceTestSuite) TestBuildDirectMessage() { func (s *ProtocolServiceTestSuite) TestBuildDirectMessage() {
@ -102,9 +104,8 @@ func (s *ProtocolServiceTestSuite) TestBuildAndReadDirectMessage() {
s.NoError(err) s.NoError(err)
// Bob is able to decrypt the message // 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) s.NoError(err)
unmarshaledMsg := response.Message
s.NotNil(unmarshaledMsg) s.NotNil(unmarshaledMsg)

View File

@ -118,7 +118,15 @@ func (s *Service) InitProtocol(address string, password string) error {
if err != nil { if err != nil {
return err 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 return nil
} }