github.com/status-im/status-go@v1.1.0/protocol/encryption/encryption_test.go (about)

     1  package encryption
     2  
     3  import (
     4  	"crypto/ecdsa"
     5  	"errors"
     6  	"fmt"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/golang/protobuf/proto"
    11  
    12  	"github.com/status-im/status-go/appdatabase"
    13  	"github.com/status-im/status-go/protocol/sqlite"
    14  	"github.com/status-im/status-go/t/helpers"
    15  
    16  	"github.com/stretchr/testify/suite"
    17  	"go.uber.org/zap"
    18  
    19  	"github.com/status-im/status-go/eth-node/crypto"
    20  )
    21  
    22  var cleartext = []byte("hello")
    23  var aliceInstallationID = "1"
    24  var bobInstallationID = "2"
    25  var defaultMessageID = []byte("default")
    26  
    27  func TestEncryptionServiceTestSuite(t *testing.T) {
    28  	suite.Run(t, new(EncryptionServiceTestSuite))
    29  }
    30  
    31  type EncryptionServiceTestSuite struct {
    32  	suite.Suite
    33  	logger *zap.Logger
    34  	alice  *Protocol
    35  	bob    *Protocol
    36  }
    37  
    38  func (s *EncryptionServiceTestSuite) initDatabases(config encryptorConfig) {
    39  	var err error
    40  
    41  	db, err := helpers.SetupTestMemorySQLDB(appdatabase.DbInitializer{})
    42  	s.Require().NoError(err)
    43  	err = sqlite.Migrate(db)
    44  	s.Require().NoError(err)
    45  	config.InstallationID = aliceInstallationID
    46  	s.alice = NewWithEncryptorConfig(
    47  		db,
    48  		aliceInstallationID,
    49  		config,
    50  		s.logger.With(zap.String("user", "alice")),
    51  	)
    52  
    53  	db, err = helpers.SetupTestMemorySQLDB(appdatabase.DbInitializer{})
    54  	s.Require().NoError(err)
    55  	err = sqlite.Migrate(db)
    56  	s.Require().NoError(err)
    57  	config.InstallationID = bobInstallationID
    58  	s.bob = NewWithEncryptorConfig(
    59  		db,
    60  		bobInstallationID,
    61  		config,
    62  		s.logger.With(zap.String("user", "bob")),
    63  	)
    64  }
    65  
    66  func (s *EncryptionServiceTestSuite) SetupTest() {
    67  	s.logger, _ = zap.NewProduction()
    68  	s.initDatabases(defaultEncryptorConfig("none", s.logger))
    69  }
    70  
    71  func (s *EncryptionServiceTestSuite) TearDownTest() {
    72  	_ = s.logger.Sync()
    73  }
    74  
    75  func (s *EncryptionServiceTestSuite) TestGetBundle() {
    76  	aliceKey, err := crypto.GenerateKey()
    77  	s.Require().NoError(err)
    78  	aliceBundle1, err := s.alice.GetBundle(aliceKey)
    79  	s.Require().NoError(err)
    80  	s.NotNil(aliceBundle1, "It creates a bundle")
    81  
    82  	aliceBundle2, err := s.alice.GetBundle(aliceKey)
    83  	s.Require().NoError(err)
    84  	s.Equal(aliceBundle1.GetSignedPreKeys(), aliceBundle2.GetSignedPreKeys(), "It returns the same signed pre keys")
    85  	s.NotEqual(aliceBundle1.Timestamp, aliceBundle2.Timestamp, "It refreshes the timestamp")
    86  }
    87  
    88  func (s *EncryptionServiceTestSuite) TestHashRatchetSend() {
    89  	aliceKey, err := crypto.GenerateKey()
    90  	s.Require().NoError(err)
    91  
    92  	bobKey, err := crypto.GenerateKey()
    93  	s.Require().NoError(err)
    94  
    95  	groupID := []byte("test_community_id")
    96  	s.Require().NotNil(aliceKey)
    97  	s.Require().NotNil(bobKey)
    98  
    99  	s.logger.Info("Hash ratchet key exchange 1")
   100  	keyID1, err := s.alice.encryptor.GenerateHashRatchetKey(groupID)
   101  	s.Require().NoError(err)
   102  
   103  	hashRatchetKeyExMsg1, err := s.alice.BuildHashRatchetKeyExchangeMessage(aliceKey, &bobKey.PublicKey, groupID, []*HashRatchetKeyCompatibility{keyID1})
   104  	s.Require().NoError(err)
   105  
   106  	s.logger.Info("Hash ratchet key exchange 1", zap.Any("msg", hashRatchetKeyExMsg1.Message))
   107  	s.Require().NotNil(hashRatchetKeyExMsg1)
   108  
   109  	s.logger.Info("Handle hash ratchet key msg 1")
   110  	decryptedResponse1, err := s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, hashRatchetKeyExMsg1.Message, defaultMessageID)
   111  	s.Require().NoError(err)
   112  	s.Require().NotNil(decryptedResponse1)
   113  
   114  	decryptedHashRatchetKeyBytes1 := decryptedResponse1.DecryptedMessage
   115  	decryptedHashRatchetKeyID1, err := s.bob.encryptor.persistence.GetCurrentKeyForGroup(groupID)
   116  	s.logger.Info("Current hash ratchet key in DB 1", zap.Any("keyId", decryptedHashRatchetKeyID1))
   117  	s.Require().NoError(err)
   118  	s.Require().NotNil(decryptedHashRatchetKeyID1)
   119  	s.Require().NotNil(decryptedHashRatchetKeyID1.Key)
   120  
   121  	keyID, err := decryptedHashRatchetKeyID1.GetKeyID()
   122  	s.Require().NoError(err)
   123  	s.Require().NotNil(keyID)
   124  
   125  	s.Require().NotNil(decryptedHashRatchetKeyID1.GroupID)
   126  	s.Require().NotEmpty(decryptedHashRatchetKeyID1.Timestamp)
   127  	s.Require().NotNil(decryptedHashRatchetKeyBytes1)
   128  	//s.Equal(decryptedHashRatchetKey1, decryptedHashRatchetKeyBytes1)
   129  
   130  	payload1 := []byte("community msg 1")
   131  	hashRatchetMsg1, err := s.bob.BuildHashRatchetMessage(groupID, payload1)
   132  
   133  	s.Require().NoError(err)
   134  	s.Require().NotNil(hashRatchetMsg1)
   135  	s.Require().NotNil(hashRatchetMsg1.Message)
   136  
   137  	decryptedResponse2, err := s.alice.HandleMessage(aliceKey, nil, hashRatchetMsg1.Message, defaultMessageID)
   138  
   139  	s.Require().NoError(err)
   140  	s.Require().NotNil(decryptedResponse2)
   141  	s.Equal(payload1, decryptedResponse2.DecryptedMessage)
   142  
   143  	payload2 := []byte("community msg 2")
   144  	hashRatchetMsg2, err := s.alice.BuildHashRatchetMessage(groupID, payload2)
   145  
   146  	s.Require().NoError(err)
   147  	s.Require().NotNil(hashRatchetMsg2)
   148  	s.Require().NotNil(hashRatchetMsg2.Message)
   149  
   150  	decryptedResponse3, err := s.bob.HandleMessage(bobKey, nil, hashRatchetMsg2.Message, defaultMessageID)
   151  
   152  	s.Require().NoError(err)
   153  	s.Require().NotNil(decryptedResponse3)
   154  	s.Equal(payload2, decryptedResponse3.DecryptedMessage)
   155  
   156  	// Re-generate hash ratchet key. Bob generates a new key and sends it to Alice
   157  
   158  	keyID2, err := s.bob.encryptor.GenerateHashRatchetKey(groupID)
   159  	s.Require().NoError(err)
   160  
   161  	hashRatchetKeyExMsg2, err := s.bob.BuildHashRatchetKeyExchangeMessage(bobKey, &aliceKey.PublicKey, groupID, []*HashRatchetKeyCompatibility{keyID2})
   162  	s.Require().NoError(err)
   163  
   164  	s.logger.Info("Hash ratchet key exchange 2", zap.Any("msg", hashRatchetKeyExMsg2.Message))
   165  	s.Require().NotNil(hashRatchetKeyExMsg2)
   166  
   167  	s.logger.Info("Handle hash ratchet key msg 2")
   168  	decryptedResponse4, err := s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, hashRatchetKeyExMsg2.Message, defaultMessageID)
   169  	s.Require().NoError(err)
   170  	decryptedHashRatchetKeyBytes2 := decryptedResponse4.DecryptedMessage
   171  	decryptedHashRatchetKeyID2, err := s.alice.encryptor.persistence.GetCurrentKeyForGroup(groupID)
   172  	s.Require().NoError(err)
   173  	s.logger.Info("Current hash ratchet key in DB 2", zap.Any("keyId", decryptedHashRatchetKeyID2))
   174  	s.Require().NotNil(decryptedHashRatchetKeyID2)
   175  	s.Require().NotNil(decryptedHashRatchetKeyBytes2)
   176  
   177  	payload3 := []byte("community msg 3")
   178  	hashRatchetMsg3, err := s.alice.BuildHashRatchetMessage(groupID, payload3)
   179  
   180  	s.logger.Info("BuildHashRatchetMessage err", zap.Any("err", err))
   181  	s.Require().NotNil(hashRatchetMsg3)
   182  	s.Require().NotNil(hashRatchetMsg3.Message)
   183  
   184  	//directMsg1 := hashRatchetMsg.Message.GetEncryptedMessage()
   185  
   186  	decryptedResponse5, err := s.bob.HandleMessage(bobKey, nil, hashRatchetMsg3.Message, defaultMessageID)
   187  
   188  	s.logger.Info("HandleHashRatchetMessage err", zap.Any("err", err))
   189  	s.Require().NotNil(decryptedResponse5)
   190  	s.Equal(payload3, decryptedResponse5.DecryptedMessage)
   191  
   192  	payload4 := []byte("community msg 4")
   193  	payload5 := []byte("community msg 5")
   194  	payload6 := []byte("community msg 6")
   195  	hashRatchetMsg4, err := s.alice.BuildHashRatchetMessage(groupID, payload4) // seqNo=2
   196  	s.Require().NoError(err)
   197  	hashRatchetMsg5, err := s.alice.BuildHashRatchetMessage(groupID, payload5) // seqNo=3
   198  	s.Require().NoError(err)
   199  	hashRatchetMsg6, err := s.alice.BuildHashRatchetMessage(groupID, payload6) // seqNo=3
   200  	s.Require().NoError(err)
   201  
   202  	// Handle them out of order plus an older one we've received earlier with seqNo=1
   203  
   204  	decryptedResponse6, err := s.bob.HandleMessage(bobKey, nil, hashRatchetMsg6.Message, defaultMessageID)
   205  	s.Require().NoError(err)
   206  	decryptedResponse7, err := s.bob.HandleMessage(bobKey, nil, hashRatchetMsg5.Message, defaultMessageID)
   207  	s.Require().NoError(err)
   208  	decryptedResponse8, err := s.bob.HandleMessage(bobKey, nil, hashRatchetMsg4.Message, defaultMessageID)
   209  	s.Require().NoError(err)
   210  	decryptedResponse9, err := s.bob.HandleMessage(bobKey, nil, hashRatchetMsg3.Message, defaultMessageID)
   211  	s.Require().NoError(err)
   212  
   213  	s.logger.Info("HandleHashRatchetMessage err", zap.Any("err", err))
   214  	s.Require().NotNil(decryptedResponse6)
   215  	s.Equal(payload6, decryptedResponse6.DecryptedMessage)
   216  	s.Require().NotNil(decryptedResponse7)
   217  	s.Equal(payload5, decryptedResponse7.DecryptedMessage)
   218  	s.Require().NotNil(decryptedResponse8)
   219  	s.Equal(payload4, decryptedResponse8.DecryptedMessage)
   220  	s.Require().NotNil(decryptedResponse9)
   221  	s.Equal(payload3, decryptedResponse9.DecryptedMessage)
   222  
   223  	// Handle message with previous key
   224  	decryptedResponse10, err := s.bob.HandleMessage(bobKey, nil, hashRatchetMsg2.Message, defaultMessageID)
   225  	s.Require().NoError(err)
   226  	s.Require().NotNil(decryptedResponse10)
   227  	s.Equal(payload2, decryptedResponse10.DecryptedMessage)
   228  }
   229  
   230  // Alice sends Bob an encrypted message with DH using an ephemeral key
   231  // and Bob's identity key.
   232  // Bob is able to decrypt it.
   233  // Alice does not re-use the symmetric key
   234  func (s *EncryptionServiceTestSuite) TestEncryptPayloadNoBundle() {
   235  	bobKey, err := crypto.GenerateKey()
   236  	s.Require().NoError(err)
   237  
   238  	aliceKey, err := crypto.GenerateKey()
   239  	s.Require().NoError(err)
   240  
   241  	response1, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, cleartext)
   242  	s.Require().NoError(err)
   243  
   244  	encryptionResponse1 := response1.Message.GetEncryptedMessage()
   245  
   246  	installationResponse1 := encryptionResponse1["none"]
   247  	// That's for any device
   248  	s.Require().NotNil(installationResponse1)
   249  
   250  	cyphertext1 := installationResponse1.Payload
   251  	ephemeralKey1 := installationResponse1.GetDHHeader().GetKey()
   252  	s.NotNil(ephemeralKey1, "It generates an ephemeral key for DH exchange")
   253  	s.NotNil(cyphertext1, "It generates an encrypted payload")
   254  	s.NotEqual(cyphertext1, cleartext, "It encrypts the payload correctly")
   255  
   256  	// On the receiver side, we should be able to decrypt using our private key and the ephemeral just sent
   257  	decryptedPayload1, err := s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, response1.Message, defaultMessageID)
   258  	s.Require().NoError(err)
   259  	s.Equal(cleartext, decryptedPayload1.DecryptedMessage, "It correctly decrypts the payload using DH")
   260  
   261  	// The next message will not be re-using the same key
   262  	response2, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, cleartext)
   263  	s.Require().NoError(err)
   264  
   265  	encryptionResponse2 := response2.Message.GetEncryptedMessage()
   266  
   267  	installationResponse2 := encryptionResponse2[aliceInstallationID]
   268  
   269  	cyphertext2 := installationResponse2.GetPayload()
   270  	ephemeralKey2 := installationResponse2.GetDHHeader().GetKey()
   271  	s.NotEqual(cyphertext1, cyphertext2, "It does not re-use the symmetric key")
   272  	s.NotEqual(ephemeralKey1, ephemeralKey2, "It does not re-use the ephemeral key")
   273  
   274  	decryptedPayload2, err := s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, response2.Message, defaultMessageID)
   275  	s.Require().NoError(err)
   276  	s.Equal(cleartext, decryptedPayload2.DecryptedMessage, "It correctly decrypts the payload using DH")
   277  }
   278  
   279  // Alice has Bob's bundle
   280  // Alice sends Bob an encrypted message with X3DH and DR using an ephemeral key
   281  // and Bob's bundle.
   282  func (s *EncryptionServiceTestSuite) TestEncryptPayloadBundle() {
   283  	bobKey, err := crypto.GenerateKey()
   284  	s.Require().NoError(err)
   285  
   286  	aliceKey, err := crypto.GenerateKey()
   287  	s.Require().NoError(err)
   288  
   289  	// Create a bundle
   290  	bobBundle, err := s.bob.GetBundle(bobKey)
   291  	s.Require().NoError(err)
   292  
   293  	// We add bob bundle
   294  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle)
   295  	s.Require().NoError(err)
   296  
   297  	// We send a message using the bundle
   298  	response1, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, cleartext)
   299  	s.Require().NoError(err)
   300  
   301  	encryptionResponse1 := response1.Message.GetEncryptedMessage()
   302  
   303  	installationResponse1 := encryptionResponse1[bobInstallationID]
   304  	s.Require().NotNil(installationResponse1)
   305  
   306  	cyphertext1 := installationResponse1.GetPayload()
   307  	x3dhHeader := installationResponse1.GetX3DHHeader()
   308  	drHeader := installationResponse1.GetDRHeader()
   309  
   310  	s.NotNil(cyphertext1, "It generates an encrypted payload")
   311  	s.NotEqual(cyphertext1, cleartext, "It encrypts the payload correctly")
   312  
   313  	// Check X3DH Header
   314  	bundleID := bobBundle.GetSignedPreKeys()[bobInstallationID].GetSignedPreKey()
   315  
   316  	s.NotNil(x3dhHeader, "It adds an x3dh header")
   317  	s.NotNil(x3dhHeader.GetKey(), "It adds an ephemeral key")
   318  	s.Equal(x3dhHeader.GetId(), bundleID, "It sets the bundle id")
   319  
   320  	// Check DR Header
   321  	s.NotNil(drHeader, "It adds a DR header")
   322  	s.NotNil(drHeader.GetKey(), "It adds a key to the DR header")
   323  	s.Equal(bundleID, drHeader.GetId(), "It adds the bundle id")
   324  	s.Equal(uint32(0), drHeader.GetN(), "It adds the correct message number")
   325  	s.Equal(uint32(0), drHeader.GetPn(), "It adds the correct length of the message chain")
   326  
   327  	// Bob is able to decrypt it using the bundle
   328  	decryptedPayload1, err := s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, response1.Message, defaultMessageID)
   329  	s.Require().NoError(err)
   330  	s.Equal(cleartext, decryptedPayload1.DecryptedMessage, "It correctly decrypts the payload using X3DH")
   331  }
   332  
   333  // Alice has Bob's bundle
   334  // Alice sends Bob 2 encrypted messages with X3DH and DR using an ephemeral key
   335  // and Bob's bundle.
   336  // Alice sends another message. This message should be using a DR
   337  // and should include the initial x3dh message
   338  // Bob receives only the last one, he should be able to decrypt it
   339  // nolint: megacheck
   340  func (s *EncryptionServiceTestSuite) TestConsequentMessagesBundle() {
   341  	cleartext1 := []byte("message 1")
   342  	cleartext2 := []byte("message 2")
   343  
   344  	bobKey, err := crypto.GenerateKey()
   345  	s.Require().NoError(err)
   346  
   347  	aliceKey, err := crypto.GenerateKey()
   348  	s.Require().NoError(err)
   349  
   350  	// Create a bundle
   351  	bobBundle, err := s.bob.GetBundle(bobKey)
   352  	s.Require().NoError(err)
   353  
   354  	// We add bob bundle
   355  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle)
   356  	s.Require().NoError(err)
   357  
   358  	// We send a message using the bundle
   359  	_, err = s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, cleartext1)
   360  	s.Require().NoError(err)
   361  
   362  	// We send another message using the bundle
   363  	response, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, cleartext2)
   364  	s.Require().NoError(err)
   365  	encryptionResponse := response.Message.GetEncryptedMessage()
   366  
   367  	installationResponse := encryptionResponse[bobInstallationID]
   368  	s.Require().NotNil(installationResponse)
   369  
   370  	cyphertext1 := installationResponse.GetPayload()
   371  	x3dhHeader := installationResponse.GetX3DHHeader()
   372  	drHeader := installationResponse.GetDRHeader()
   373  
   374  	s.NotNil(cyphertext1, "It generates an encrypted payload")
   375  	s.NotEqual(cyphertext1, cleartext2, "It encrypts the payload correctly")
   376  
   377  	// Check X3DH Header
   378  	bundleID := bobBundle.GetSignedPreKeys()[bobInstallationID].GetSignedPreKey()
   379  
   380  	s.NotNil(x3dhHeader, "It adds an x3dh header")
   381  	s.NotNil(x3dhHeader.GetKey(), "It adds an ephemeral key")
   382  	s.Equal(x3dhHeader.GetId(), bundleID, "It sets the bundle id")
   383  
   384  	// Check DR Header
   385  	s.NotNil(drHeader, "It adds a DR header")
   386  	s.NotNil(drHeader.GetKey(), "It adds a key to the DR header")
   387  	s.Equal(bundleID, drHeader.GetId(), "It adds the bundle id")
   388  
   389  	s.Equal(uint32(1), drHeader.GetN(), "It adds the correct message number")
   390  	s.Equal(uint32(0), drHeader.GetPn(), "It adds the correct length of the message chain")
   391  
   392  	// Bob is able to decrypt it using the bundle
   393  	decryptedPayload1, err := s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, response.Message, defaultMessageID)
   394  	s.Require().NoError(err)
   395  
   396  	s.Equal(cleartext2, decryptedPayload1.DecryptedMessage, "It correctly decrypts the payload using X3DH")
   397  }
   398  
   399  // Alice has Bob's bundle
   400  // Alice sends Bob an encrypted message with X3DH using an ephemeral key
   401  // and Bob's bundle.
   402  // Bob's receives the message
   403  // Bob replies to the message
   404  // Alice replies to the message
   405  
   406  func (s *EncryptionServiceTestSuite) TestConversation() {
   407  	cleartext1 := []byte("message 1")
   408  	cleartext2 := []byte("message 2")
   409  
   410  	bobKey, err := crypto.GenerateKey()
   411  	s.Require().NoError(err)
   412  
   413  	aliceKey, err := crypto.GenerateKey()
   414  	s.Require().NoError(err)
   415  
   416  	// Create a bundle
   417  	bobBundle, err := s.bob.GetBundle(bobKey)
   418  	s.Require().NoError(err)
   419  
   420  	// Create a bundle
   421  	aliceBundle, err := s.alice.GetBundle(aliceKey)
   422  	s.Require().NoError(err)
   423  
   424  	// We add bob bundle
   425  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle)
   426  	s.Require().NoError(err)
   427  
   428  	// We add alice bundle
   429  	_, err = s.bob.ProcessPublicBundle(bobKey, aliceBundle)
   430  	s.Require().NoError(err)
   431  
   432  	// Alice sends a message
   433  	response, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, cleartext1)
   434  	s.Require().NoError(err)
   435  
   436  	// Bob receives the message
   437  	_, err = s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, response.Message, defaultMessageID)
   438  	s.Require().NoError(err)
   439  
   440  	// Bob replies to the message
   441  	response, err = s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, cleartext1)
   442  	s.Require().NoError(err)
   443  
   444  	// Alice receives the message
   445  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, response.Message, defaultMessageID)
   446  	s.Require().NoError(err)
   447  
   448  	// We send another message using the bundle
   449  	response, err = s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, cleartext2)
   450  	s.Require().NoError(err)
   451  	encryptionResponse := response.Message.GetEncryptedMessage()
   452  
   453  	installationResponse := encryptionResponse[bobInstallationID]
   454  	s.Require().NotNil(installationResponse)
   455  
   456  	cyphertext1 := installationResponse.GetPayload()
   457  	x3dhHeader := installationResponse.GetX3DHHeader()
   458  	drHeader := installationResponse.GetDRHeader()
   459  
   460  	s.NotNil(cyphertext1, "It generates an encrypted payload")
   461  	s.NotEqual(cyphertext1, cleartext2, "It encrypts the payload correctly")
   462  
   463  	// It does not send the x3dh bundle
   464  	s.Nil(x3dhHeader, "It does not add an x3dh header")
   465  
   466  	// Check DR Header
   467  	bundleID := bobBundle.GetSignedPreKeys()[bobInstallationID].GetSignedPreKey()
   468  
   469  	s.NotNil(drHeader, "It adds a DR header")
   470  	s.NotNil(drHeader.GetKey(), "It adds a key to the DR header")
   471  	s.Equal(bundleID, drHeader.GetId(), "It adds the bundle id")
   472  
   473  	s.Equal(uint32(0), drHeader.GetN(), "It adds the correct message number")
   474  	s.Equal(uint32(1), drHeader.GetPn(), "It adds the correct length of the message chain")
   475  
   476  	// Bob is able to decrypt it using the bundle
   477  	decryptedPayload1, err := s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, response.Message, defaultMessageID)
   478  	s.Require().NoError(err)
   479  
   480  	s.Equal(cleartext2, decryptedPayload1.DecryptedMessage, "It correctly decrypts the payload using X3DH")
   481  }
   482  
   483  // Previous implementation allowed max maxSkip keys in the same receiving chain
   484  // leading to a problem whereby dropped messages would accumulate and eventually
   485  // we would not be able to decrypt any new message anymore.
   486  // Here we are testing that maxSkip only applies to *consecutive* messages, not
   487  // overall.
   488  func (s *EncryptionServiceTestSuite) TestMaxSkipKeys() {
   489  	bobText := []byte("text")
   490  
   491  	bobKey, err := crypto.GenerateKey()
   492  	s.Require().NoError(err)
   493  
   494  	aliceKey, err := crypto.GenerateKey()
   495  	s.Require().NoError(err)
   496  
   497  	// Create a bundle
   498  	bobBundle, err := s.bob.GetBundle(bobKey)
   499  	s.Require().NoError(err)
   500  
   501  	// We add bob bundle
   502  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle)
   503  	s.Require().NoError(err)
   504  
   505  	// Create a bundle
   506  	aliceBundle, err := s.alice.GetBundle(aliceKey)
   507  	s.Require().NoError(err)
   508  
   509  	// We add alice bundle
   510  	_, err = s.bob.ProcessPublicBundle(bobKey, aliceBundle)
   511  	s.Require().NoError(err)
   512  
   513  	// Bob sends a message
   514  
   515  	for i := 0; i < s.alice.encryptor.config.MaxSkip; i++ {
   516  		_, err = s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText)
   517  		s.Require().NoError(err)
   518  	}
   519  
   520  	// Bob sends a message
   521  	bobMessage1, err := s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText)
   522  	s.Require().NoError(err)
   523  
   524  	// Alice receives the message
   525  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage1.Message, defaultMessageID)
   526  	s.Require().NoError(err)
   527  
   528  	// Bob sends a message
   529  	_, err = s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText)
   530  	s.Require().NoError(err)
   531  
   532  	// Bob sends a message
   533  	bobMessage2, err := s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText)
   534  	s.Require().NoError(err)
   535  
   536  	// Alice receives the message, we should have maxSkip + 1 keys in the db, but
   537  	// we should not throw an error
   538  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage2.Message, defaultMessageID)
   539  	s.Require().NoError(err)
   540  }
   541  
   542  // Test that an error is thrown if max skip is reached
   543  func (s *EncryptionServiceTestSuite) TestMaxSkipKeysError() {
   544  	bobText := []byte("text")
   545  
   546  	bobKey, err := crypto.GenerateKey()
   547  	s.Require().NoError(err)
   548  
   549  	aliceKey, err := crypto.GenerateKey()
   550  	s.Require().NoError(err)
   551  
   552  	// Create a bundle
   553  	bobBundle, err := s.bob.GetBundle(bobKey)
   554  	s.Require().NoError(err)
   555  
   556  	// We add bob bundle
   557  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle)
   558  	s.Require().NoError(err)
   559  
   560  	// Create a bundle
   561  	aliceBundle, err := s.alice.GetBundle(aliceKey)
   562  	s.Require().NoError(err)
   563  
   564  	// We add alice bundle
   565  	_, err = s.bob.ProcessPublicBundle(bobKey, aliceBundle)
   566  	s.Require().NoError(err)
   567  
   568  	// Bob sends a message
   569  
   570  	for i := 0; i < s.alice.encryptor.config.MaxSkip+1; i++ {
   571  		_, err = s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText)
   572  		s.Require().NoError(err)
   573  	}
   574  
   575  	// Bob sends a message
   576  	bobMessage1, err := s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText)
   577  	s.Require().NoError(err)
   578  
   579  	// Alice receives the message
   580  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage1.Message, defaultMessageID)
   581  	s.Require().Equal(errors.New("can't skip current chain message keys: too many messages"), err)
   582  }
   583  
   584  func (s *EncryptionServiceTestSuite) TestMaxMessageKeysPerSession() {
   585  	config := defaultEncryptorConfig("none", zap.NewNop())
   586  	// Set MaxKeep and MaxSkip to an high value so it does not interfere
   587  	config.MaxKeep = 100000
   588  	config.MaxSkip = 100000
   589  
   590  	s.initDatabases(config)
   591  
   592  	bobText := []byte("text")
   593  
   594  	bobKey, err := crypto.GenerateKey()
   595  	s.Require().NoError(err)
   596  
   597  	aliceKey, err := crypto.GenerateKey()
   598  	s.Require().NoError(err)
   599  
   600  	// Create a bundle
   601  	bobBundle, err := s.bob.GetBundle(bobKey)
   602  	s.Require().NoError(err)
   603  
   604  	// We add bob bundle
   605  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle)
   606  	s.Require().NoError(err)
   607  
   608  	// Create a bundle
   609  	aliceBundle, err := s.alice.GetBundle(aliceKey)
   610  	s.Require().NoError(err)
   611  
   612  	// We add alice bundle
   613  	_, err = s.bob.ProcessPublicBundle(bobKey, aliceBundle)
   614  	s.Require().NoError(err)
   615  
   616  	// We create just enough messages so that the first key should be deleted
   617  
   618  	nMessages := s.alice.encryptor.config.MaxMessageKeysPerSession
   619  	messages := make([]*ProtocolMessage, nMessages)
   620  	for i := 0; i < nMessages; i++ {
   621  		m, err := s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText)
   622  		s.Require().NoError(err)
   623  
   624  		messages[i] = m.Message
   625  	}
   626  
   627  	// Another message to trigger the deletion
   628  	m, err := s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText)
   629  	s.Require().NoError(err)
   630  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, m.Message, defaultMessageID)
   631  	s.Require().NoError(err)
   632  
   633  	// We decrypt the first message, and it should fail
   634  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, messages[0], defaultMessageID)
   635  	s.Require().Equal(errors.New("can't skip current chain message keys: bad until: probably an out-of-order message that was deleted"), err)
   636  
   637  	// We decrypt the second message, and it should be decrypted
   638  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, messages[1], defaultMessageID)
   639  	s.Require().NoError(err)
   640  }
   641  
   642  func (s *EncryptionServiceTestSuite) TestMaxKeep() {
   643  	config := defaultEncryptorConfig("none", s.logger)
   644  	// Set MaxMessageKeysPerSession to an high value so it does not interfere
   645  	config.MaxMessageKeysPerSession = 100000
   646  	// Set MaxKeep to a small number for testing
   647  	config.MaxKeep = 10
   648  
   649  	s.initDatabases(config)
   650  
   651  	bobText := []byte("text")
   652  
   653  	bobKey, err := crypto.GenerateKey()
   654  	s.Require().NoError(err)
   655  
   656  	aliceKey, err := crypto.GenerateKey()
   657  	s.Require().NoError(err)
   658  
   659  	// Create a bundle
   660  	bobBundle, err := s.bob.GetBundle(bobKey)
   661  	s.Require().NoError(err)
   662  
   663  	// We add bob bundle
   664  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle)
   665  	s.Require().NoError(err)
   666  
   667  	// Create a bundle
   668  	aliceBundle, err := s.alice.GetBundle(aliceKey)
   669  	s.Require().NoError(err)
   670  
   671  	// We add alice bundle
   672  	_, err = s.bob.ProcessPublicBundle(bobKey, aliceBundle)
   673  	s.Require().NoError(err)
   674  
   675  	// We decrypt all messages but 1 & 2
   676  	messages := make([]*ProtocolMessage, s.alice.encryptor.config.MaxKeep)
   677  	for i := 0; i < s.alice.encryptor.config.MaxKeep; i++ {
   678  		m, err := s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText)
   679  		messages[i] = m.Message
   680  		s.Require().NoError(err)
   681  
   682  		if i != 0 && i != 1 {
   683  			messageID := []byte(fmt.Sprintf("%d", i))
   684  			_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, m.Message, messageID)
   685  			s.Require().NoError(err)
   686  			err = s.alice.ConfirmMessageProcessed(messageID)
   687  			s.Require().NoError(err)
   688  		}
   689  
   690  	}
   691  
   692  	// We decrypt the first message, and it should fail, as it should have been removed
   693  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, messages[0], defaultMessageID)
   694  	s.Require().Equal(errors.New("can't skip current chain message keys: bad until: probably an out-of-order message that was deleted"), err)
   695  
   696  	// We decrypt the second message, and it should be decrypted
   697  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, messages[1], defaultMessageID)
   698  	s.Require().NoError(err)
   699  }
   700  
   701  // Alice has Bob's bundle
   702  // Bob has Alice's bundle
   703  // Bob sends a message to alice
   704  // Alice sends a message to Bob
   705  // Bob receives alice message
   706  // Alice receives Bob message
   707  // Bob sends another message to alice and vice-versa.
   708  func (s *EncryptionServiceTestSuite) TestConcurrentBundles() {
   709  	bobText1 := []byte("bob text 1")
   710  	bobText2 := []byte("bob text 2")
   711  	aliceText1 := []byte("alice text 1")
   712  	aliceText2 := []byte("alice text 2")
   713  
   714  	bobKey, err := crypto.GenerateKey()
   715  	s.Require().NoError(err)
   716  
   717  	aliceKey, err := crypto.GenerateKey()
   718  	s.Require().NoError(err)
   719  
   720  	// Create a bundle
   721  	bobBundle, err := s.bob.GetBundle(bobKey)
   722  	s.Require().NoError(err)
   723  
   724  	// We add bob bundle
   725  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle)
   726  	s.Require().NoError(err)
   727  
   728  	// Create a bundle
   729  	aliceBundle, err := s.alice.GetBundle(aliceKey)
   730  	s.Require().NoError(err)
   731  
   732  	// We add alice bundle
   733  	_, err = s.bob.ProcessPublicBundle(bobKey, aliceBundle)
   734  	s.Require().NoError(err)
   735  
   736  	// Alice sends a message
   737  	aliceMessage1, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, aliceText1)
   738  	s.Require().NoError(err)
   739  
   740  	// Bob sends a message
   741  	bobMessage1, err := s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText1)
   742  	s.Require().NoError(err)
   743  
   744  	// Bob receives the message
   745  	_, err = s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, aliceMessage1.Message, defaultMessageID)
   746  	s.Require().NoError(err)
   747  
   748  	// Alice receives the message
   749  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage1.Message, defaultMessageID)
   750  	s.Require().NoError(err)
   751  
   752  	// Bob replies to the message
   753  	bobMessage2, err := s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText2)
   754  	s.Require().NoError(err)
   755  
   756  	// Alice sends a message
   757  	aliceMessage2, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, aliceText2)
   758  	s.Require().NoError(err)
   759  
   760  	// Alice receives the message
   761  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage2.Message, defaultMessageID)
   762  	s.Require().NoError(err)
   763  
   764  	// Bob receives the message
   765  	_, err = s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, aliceMessage2.Message, defaultMessageID)
   766  	s.Require().NoError(err)
   767  }
   768  
   769  // Edge cases
   770  
   771  // The bundle is lost
   772  func (s *EncryptionServiceTestSuite) TestBundleNotExisting() {
   773  	aliceText := []byte("alice text")
   774  
   775  	bobKey, err := crypto.GenerateKey()
   776  	s.Require().NoError(err)
   777  
   778  	aliceKey, err := crypto.GenerateKey()
   779  	s.Require().NoError(err)
   780  
   781  	// Create a bundle without saving it
   782  	bobBundleContainer, err := NewBundleContainer(bobKey, bobInstallationID)
   783  	s.Require().NoError(err)
   784  
   785  	err = SignBundle(bobKey, bobBundleContainer)
   786  	s.Require().NoError(err)
   787  
   788  	bobBundle := bobBundleContainer.GetBundle()
   789  
   790  	// We add bob bundle
   791  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle)
   792  	s.Require().NoError(err)
   793  
   794  	// Alice sends a message
   795  	aliceMessage, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, aliceText)
   796  	s.Require().NoError(err)
   797  
   798  	// Bob receives the message, and returns a bundlenotfound error
   799  	_, err = s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, aliceMessage.Message, defaultMessageID)
   800  	s.Require().Error(err)
   801  	s.Equal(errSessionNotFound, err)
   802  }
   803  
   804  // Device is not included in the bundle
   805  func (s *EncryptionServiceTestSuite) TestDeviceNotIncluded() {
   806  	bobDevice2InstallationID := "bob2"
   807  
   808  	bobKey, err := crypto.GenerateKey()
   809  	s.Require().NoError(err)
   810  
   811  	aliceKey, err := crypto.GenerateKey()
   812  	s.Require().NoError(err)
   813  
   814  	// Create a bundle without saving it
   815  	bobBundleContainer, err := NewBundleContainer(bobKey, bobDevice2InstallationID)
   816  	s.Require().NoError(err)
   817  
   818  	err = SignBundle(bobKey, bobBundleContainer)
   819  	s.Require().NoError(err)
   820  
   821  	bobBundle := bobBundleContainer.GetBundle()
   822  
   823  	// We add bob bundle
   824  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle)
   825  	s.Require().NoError(err)
   826  
   827  	// Alice sends a message
   828  	aliceMessage, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, []byte("does not matter"))
   829  	s.Require().NoError(err)
   830  
   831  	// Bob receives the message, and returns a bundlenotfound error
   832  	_, err = s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, aliceMessage.Message, defaultMessageID)
   833  	s.Require().Error(err)
   834  	s.Equal(ErrDeviceNotFound, err)
   835  }
   836  
   837  // A new bundle has been received
   838  func (s *EncryptionServiceTestSuite) TestRefreshedBundle() {
   839  	config := defaultEncryptorConfig("none", s.logger)
   840  	// Set up refresh interval to "always"
   841  	config.BundleRefreshInterval = 1000
   842  
   843  	s.initDatabases(config)
   844  
   845  	bobKey, err := crypto.GenerateKey()
   846  	s.Require().NoError(err)
   847  
   848  	aliceKey, err := crypto.GenerateKey()
   849  	s.Require().NoError(err)
   850  
   851  	// Create bundles
   852  	bobBundle1, err := s.bob.GetBundle(bobKey)
   853  	s.Require().NoError(err)
   854  	s.Require().Equal(uint32(1), bobBundle1.GetSignedPreKeys()[bobInstallationID].GetVersion())
   855  
   856  	// Sleep the required time so that bundle is refreshed
   857  	time.Sleep(time.Duration(config.BundleRefreshInterval) * time.Millisecond)
   858  
   859  	// Create bundles
   860  	bobBundle2, err := s.bob.GetBundle(bobKey)
   861  	s.Require().NoError(err)
   862  	s.Require().Equal(uint32(2), bobBundle2.GetSignedPreKeys()[bobInstallationID].GetVersion())
   863  
   864  	// We add the first bob bundle
   865  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle1)
   866  	s.Require().NoError(err)
   867  
   868  	// Alice sends a message
   869  	response1, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, []byte("anything"))
   870  	s.Require().NoError(err)
   871  	encryptionResponse1 := response1.Message.GetEncryptedMessage()
   872  
   873  	installationResponse1 := encryptionResponse1[bobInstallationID]
   874  	s.Require().NotNil(installationResponse1)
   875  
   876  	// This message is using bobBundle1
   877  
   878  	x3dhHeader1 := installationResponse1.GetX3DHHeader()
   879  	s.NotNil(x3dhHeader1)
   880  	s.Equal(bobBundle1.GetSignedPreKeys()[bobInstallationID].GetSignedPreKey(), x3dhHeader1.GetId())
   881  
   882  	// Bob decrypts the message
   883  	_, err = s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, response1.Message, defaultMessageID)
   884  	s.Require().NoError(err)
   885  
   886  	// We add the second bob bundle
   887  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle2)
   888  	s.Require().NoError(err)
   889  
   890  	// Alice sends a message
   891  	response2, err := s.alice.BuildEncryptedMessage(aliceKey, &bobKey.PublicKey, []byte("anything"))
   892  	s.Require().NoError(err)
   893  	encryptionResponse2 := response2.Message.GetEncryptedMessage()
   894  
   895  	installationResponse2 := encryptionResponse2[bobInstallationID]
   896  	s.Require().NotNil(installationResponse2)
   897  
   898  	// This message is using bobBundle2
   899  
   900  	x3dhHeader2 := installationResponse2.GetX3DHHeader()
   901  	s.NotNil(x3dhHeader2)
   902  	s.Equal(bobBundle2.GetSignedPreKeys()[bobInstallationID].GetSignedPreKey(), x3dhHeader2.GetId())
   903  
   904  	// Bob decrypts the message
   905  	_, err = s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, response2.Message, defaultMessageID)
   906  	s.Require().NoError(err)
   907  }
   908  
   909  func (s *EncryptionServiceTestSuite) TestMessageConfirmation() {
   910  	bobText1 := []byte("bob text 1")
   911  
   912  	bobKey, err := crypto.GenerateKey()
   913  	s.Require().NoError(err)
   914  
   915  	aliceKey, err := crypto.GenerateKey()
   916  	s.Require().NoError(err)
   917  
   918  	// Create a bundle
   919  	bobBundle, err := s.bob.GetBundle(bobKey)
   920  	s.Require().NoError(err)
   921  
   922  	// We add bob bundle
   923  	_, err = s.alice.ProcessPublicBundle(aliceKey, bobBundle)
   924  	s.Require().NoError(err)
   925  
   926  	// Create a bundle
   927  	aliceBundle, err := s.alice.GetBundle(aliceKey)
   928  	s.Require().NoError(err)
   929  
   930  	// We add alice bundle
   931  	_, err = s.bob.ProcessPublicBundle(bobKey, aliceBundle)
   932  	s.Require().NoError(err)
   933  
   934  	// Bob sends a message
   935  	bobMessage1, err := s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText1)
   936  	s.Require().NoError(err)
   937  	bobMessage1ID := []byte("bob-message-1-id")
   938  
   939  	// Alice receives the message once
   940  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage1.Message, bobMessage1ID)
   941  	s.Require().NoError(err)
   942  
   943  	// Alice receives the message twice
   944  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage1.Message, bobMessage1ID)
   945  	s.Require().NoError(err)
   946  
   947  	// Alice confirms the message
   948  	err = s.alice.ConfirmMessageProcessed(bobMessage1ID)
   949  	s.Require().NoError(err)
   950  
   951  	// Alice decrypts it again, it should fail
   952  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage1.Message, bobMessage1ID)
   953  	s.Require().Equal(errors.New("can't skip current chain message keys: bad until: probably an out-of-order message that was deleted"), err)
   954  
   955  	// Bob sends a message
   956  	bobMessage2, err := s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText1)
   957  	s.Require().NoError(err)
   958  	bobMessage2ID := []byte("bob-message-2-id")
   959  
   960  	// Bob sends a message
   961  	bobMessage3, err := s.bob.BuildEncryptedMessage(bobKey, &aliceKey.PublicKey, bobText1)
   962  	s.Require().NoError(err)
   963  	bobMessage3ID := []byte("bob-message-3-id")
   964  
   965  	// Alice receives message 3 once
   966  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage3.Message, bobMessage3ID)
   967  	s.Require().NoError(err)
   968  
   969  	// Alice receives message 3 twice
   970  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage3.Message, bobMessage3ID)
   971  	s.Require().NoError(err)
   972  
   973  	// Alice receives message 2 once
   974  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage2.Message, bobMessage2ID)
   975  	s.Require().NoError(err)
   976  
   977  	// Alice receives message 2 twice
   978  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage2.Message, bobMessage2ID)
   979  	s.Require().NoError(err)
   980  
   981  	// Alice confirms the messages
   982  	err = s.alice.ConfirmMessageProcessed(bobMessage2ID)
   983  	s.Require().NoError(err)
   984  	err = s.alice.ConfirmMessageProcessed(bobMessage3ID)
   985  	s.Require().NoError(err)
   986  
   987  	// Alice decrypts it again, it should fail
   988  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage3.Message, bobMessage3ID)
   989  	s.Require().Equal(errors.New("can't skip current chain message keys: bad until: probably an out-of-order message that was deleted"), err)
   990  
   991  	// Alice decrypts it again, it should fail
   992  	_, err = s.alice.HandleMessage(aliceKey, &bobKey.PublicKey, bobMessage2.Message, bobMessage2ID)
   993  	s.Require().Equal(errors.New("can't skip current chain message keys: bad until: probably an out-of-order message that was deleted"), err)
   994  }
   995  
   996  // Tests:
   997  
   998  // 1) Client has an old key, it upgrades, receives a message from an old client
   999  // 2) Client has an old key, it upgrades, receives a message from a new client
  1000  
  1001  func (s *EncryptionServiceTestSuite) TestHashRatchetCompatibility() {
  1002  	aliceKey, err := crypto.GenerateKey()
  1003  	s.Require().NoError(err)
  1004  
  1005  	bobKey, err := crypto.GenerateKey()
  1006  	s.Require().NoError(err)
  1007  
  1008  	groupID := []byte("test_community_id")
  1009  	s.Require().NotNil(aliceKey)
  1010  	s.Require().NotNil(bobKey)
  1011  
  1012  	// We create a hash ratchet on bob
  1013  	s.logger.Info("Hash ratchet key exchange 1")
  1014  	keyID1, err := s.bob.encryptor.GenerateHashRatchetKey(groupID)
  1015  	s.Require().NoError(err)
  1016  
  1017  	// We replicate the same error condition
  1018  	timestamp32 := keyID1.DeprecatedKeyID()
  1019  	_, err = s.alice.encryptor.persistence.DB.Exec("INSERT INTO hash_ratchet_encryption(group_id, deprecated_key_id, key, key_id) VALUES(?,?,?,?)", groupID, timestamp32, keyID1.Key, append(groupID, []byte("some-bytes")...))
  1020  	s.Require().NoError(err)
  1021  
  1022  	// We migrate
  1023  	_, err = s.alice.encryptor.persistence.DB.Exec("UPDATE hash_ratchet_encryption SET key_timestamp = deprecated_key_id")
  1024  	s.Require().NoError(err)
  1025  
  1026  	payload1 := []byte("community msg 1")
  1027  	hashRatchetMsg1, err := s.bob.BuildHashRatchetMessage(groupID, payload1)
  1028  
  1029  	s.Require().NoError(err)
  1030  	s.Require().NotNil(hashRatchetMsg1)
  1031  	s.Require().NotNil(hashRatchetMsg1.Message)
  1032  
  1033  	// We remove groupID, as that's whats coming from older clients
  1034  	hashRatchetMsg1.Message.EncryptedMessage["none"].HRHeader.KeyId = nil
  1035  	s.Require().NotEmpty(hashRatchetMsg1.Message.EncryptedMessage["none"].HRHeader.DeprecatedKeyId)
  1036  	s.Require().Equal(timestamp32, hashRatchetMsg1.Message.EncryptedMessage["none"].HRHeader.DeprecatedKeyId)
  1037  
  1038  	decryptedResponse, err := s.alice.HandleMessage(aliceKey, nil, hashRatchetMsg1.Message, defaultMessageID)
  1039  	s.Require().NoError(err)
  1040  	s.Require().NotEmpty(decryptedResponse)
  1041  
  1042  	// New message structure, on old key
  1043  	hashRatchetMsg2, err := s.bob.BuildHashRatchetMessage(groupID, payload1)
  1044  
  1045  	s.Require().NoError(err)
  1046  	s.Require().NotNil(hashRatchetMsg2)
  1047  	s.Require().NotNil(hashRatchetMsg2.Message)
  1048  
  1049  	s.Require().NotEmpty(hashRatchetMsg2.Message.EncryptedMessage["none"].HRHeader.DeprecatedKeyId)
  1050  	s.Require().NotEmpty(hashRatchetMsg2.Message.EncryptedMessage["none"].HRHeader.KeyId)
  1051  	s.Require().Equal(timestamp32, hashRatchetMsg2.Message.EncryptedMessage["none"].HRHeader.DeprecatedKeyId)
  1052  
  1053  	decryptedResponse, err = s.alice.HandleMessage(aliceKey, nil, hashRatchetMsg2.Message, defaultMessageID)
  1054  	s.Require().NoError(err)
  1055  	s.Require().NotEmpty(decryptedResponse)
  1056  }
  1057  
  1058  func (s *EncryptionServiceTestSuite) TestHashRatchetRekey() {
  1059  	privateKey, err := crypto.GenerateKey()
  1060  	s.Require().NoError(err)
  1061  
  1062  	groupID := []byte{0x4}
  1063  	var timestamp uint64 = 10
  1064  	keyID1, err := s.alice.encryptor.GenerateHashRatchetKey(groupID)
  1065  	s.Require().NoError(err)
  1066  
  1067  	keyMaterial := keyID1.Key
  1068  
  1069  	key1String := "e8395a5d2289d14d47f5f5c506001a2b4f039d96ebf576a6a39e5f23c7a9c618"
  1070  
  1071  	key1, err := crypto.HexToECDSA(key1String)
  1072  	s.Require().NoError(err)
  1073  
  1074  	key1KeyBytes := publicKeyMostRelevantBytes(&key1.PublicKey)
  1075  
  1076  	s.Require().Equal(uint32(0x6da634b9), key1KeyBytes)
  1077  
  1078  	key2String := "e8395a5d5b3c4081c0e1f63c5d588c6f2c4ba7c6ec590f5f8e1a96b48f5e6e7e"
  1079  	key2, err := crypto.HexToECDSA(key2String)
  1080  	s.Require().NoError(err)
  1081  
  1082  	key2KeyBytes := publicKeyMostRelevantBytes(&key2.PublicKey)
  1083  	s.Require().Equal(uint32(0x72d6c574), key2KeyBytes)
  1084  
  1085  	message, err := buildGroupRekeyMessage(privateKey, groupID, timestamp, keyMaterial, []*ecdsa.PublicKey{&key1.PublicKey, &key1.PublicKey, &key1.PublicKey, &key2.PublicKey})
  1086  	s.Require().NoError(err)
  1087  
  1088  	_, err = proto.Marshal(message)
  1089  	s.Require().NoError(err)
  1090  
  1091  	s.Require().Equal(timestamp, message.Timestamp)
  1092  
  1093  	s.Require().NotNil(message.Keys)
  1094  
  1095  	s.Require().NotEmpty(message.Keys[key1KeyBytes])
  1096  	s.Require().NotEmpty(message.Keys[key2KeyBytes])
  1097  
  1098  	s.Require().Len(message.Keys[key1KeyBytes], 180)
  1099  	s.Require().Len(message.Keys[key2KeyBytes], 60)
  1100  
  1101  }
  1102  
  1103  // We test that adding a new field and leaving the old blank won't crash the app
  1104  func (s *EncryptionServiceTestSuite) TestHashRatchetRekeyCompatibility() {
  1105  	_, err := s.alice.HandleHashRatchetKeys([]byte{0x1}, nil, nil, nil)
  1106  	s.Require().NoError(err)
  1107  }
  1108  
  1109  // We test that adding a new field and leaving the old blank won't crash the app
  1110  func (s *EncryptionServiceTestSuite) TestHashRatchetRekeyHandleRatchet() {
  1111  	aliceKey, err := crypto.GenerateKey()
  1112  	s.Require().NoError(err)
  1113  
  1114  	bobKey, err := crypto.GenerateKey()
  1115  	s.Require().NoError(err)
  1116  
  1117  	groupID := []byte{0x1}
  1118  	spec, err := s.alice.BuildHashRatchetReKeyGroupMessage(aliceKey, []*ecdsa.PublicKey{&bobKey.PublicKey}, groupID, nil, nil)
  1119  	s.Require().NoError(err)
  1120  	s.Require().NotNil(spec)
  1121  
  1122  	response, err := s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, spec.Message, []byte{0x2})
  1123  	s.Require().NoError(err)
  1124  	s.Require().NotNil(response)
  1125  	s.Require().Len(response.HashRatchetInfo, 1)
  1126  
  1127  }
  1128  
  1129  func (s *EncryptionServiceTestSuite) TestHashRatchetSendOutOfOrder() {
  1130  	aliceKey, err := crypto.GenerateKey()
  1131  	s.Require().NoError(err)
  1132  
  1133  	bobKey, err := crypto.GenerateKey()
  1134  	s.Require().NoError(err)
  1135  
  1136  	groupID := []byte("test_community_id")
  1137  	s.Require().NotNil(aliceKey)
  1138  	s.Require().NotNil(bobKey)
  1139  
  1140  	s.logger.Info("Hash ratchet key exchange 1")
  1141  	keyID1, err := s.alice.encryptor.GenerateHashRatchetKey(groupID)
  1142  	s.Require().NoError(err)
  1143  
  1144  	hashRatchetKeyExMsg1, err := s.alice.BuildHashRatchetKeyExchangeMessage(aliceKey, &bobKey.PublicKey, groupID, []*HashRatchetKeyCompatibility{keyID1})
  1145  	s.Require().NoError(err)
  1146  
  1147  	s.logger.Info("Hash ratchet key exchange 1", zap.Any("msg", hashRatchetKeyExMsg1.Message))
  1148  	s.Require().NotNil(hashRatchetKeyExMsg1)
  1149  
  1150  	payload1 := []byte("community msg 1")
  1151  	hashRatchetMsg1, err := s.alice.BuildHashRatchetMessage(groupID, payload1)
  1152  
  1153  	s.Require().NoError(err)
  1154  	s.Require().NotNil(hashRatchetMsg1)
  1155  	s.Require().NotNil(hashRatchetMsg1.Message)
  1156  
  1157  	_, err = s.bob.HandleMessage(aliceKey, nil, hashRatchetMsg1.Message, defaultMessageID)
  1158  
  1159  	s.Require().Error(err)
  1160  	s.Require().Equal(err, ErrHashRatchetGroupIDNotFound)
  1161  
  1162  	s.logger.Info("Handle hash ratchet key msg 1")
  1163  	decryptedResponse1, err := s.bob.HandleMessage(bobKey, &aliceKey.PublicKey, hashRatchetKeyExMsg1.Message, defaultMessageID)
  1164  	s.Require().NoError(err)
  1165  	s.Require().NotNil(decryptedResponse1)
  1166  
  1167  	decryptedHashRatchetKeyBytes1 := decryptedResponse1.DecryptedMessage
  1168  	decryptedHashRatchetKeyID1, err := s.bob.encryptor.persistence.GetCurrentKeyForGroup(groupID)
  1169  	s.logger.Info("Current hash ratchet key in DB 1", zap.Any("keyId", decryptedHashRatchetKeyID1))
  1170  	s.Require().NoError(err)
  1171  	s.Require().NotNil(decryptedHashRatchetKeyID1)
  1172  	s.Require().NotNil(decryptedHashRatchetKeyID1.Key)
  1173  
  1174  	keyID, err := decryptedHashRatchetKeyID1.GetKeyID()
  1175  	s.Require().NoError(err)
  1176  	s.Require().NotNil(keyID)
  1177  
  1178  	s.Require().NotNil(decryptedHashRatchetKeyID1.GroupID)
  1179  	s.Require().NotEmpty(decryptedHashRatchetKeyID1.Timestamp)
  1180  	s.Require().NotNil(decryptedHashRatchetKeyBytes1)
  1181  
  1182  	decryptedPayload2, err := s.bob.HandleMessage(aliceKey, nil, hashRatchetMsg1.Message, defaultMessageID)
  1183  
  1184  	s.Require().NoError(err)
  1185  	s.Require().Equal(payload1, decryptedPayload2.DecryptedMessage)
  1186  }