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 }