예제 #1
0
        public void TestBadMessageBundle()
        {
            ISignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
            SessionBuilder       aliceSessionBuilder = new SessionBuilder(aliceStore, BobAddress);

            ISignalProtocolStore bobStore = new TestInMemorySignalProtocolStore();

            EcKeyPair bobPreKeyPair       = Curve.GenerateKeyPair();
            EcKeyPair bobSignedPreKeyPair = Curve.GenerateKeyPair();

            byte[] bobSignedPreKeySignature = Curve.CalculateSignature(bobStore.GetIdentityKeyPair().GetPrivateKey(),
                                                                       bobSignedPreKeyPair.GetPublicKey().Serialize());

            PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(), 1,
                                                      31337, bobPreKeyPair.GetPublicKey(),
                                                      22, bobSignedPreKeyPair.GetPublicKey(), bobSignedPreKeySignature,
                                                      bobStore.GetIdentityKeyPair().GetPublicKey());

            bobStore.StorePreKey(31337, new PreKeyRecord(bobPreKey.GetPreKeyId(), bobPreKeyPair));
            bobStore.StoreSignedPreKey(22, new SignedPreKeyRecord(22, DateUtil.CurrentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));

            aliceSessionBuilder.Process(bobPreKey);

            String            originalMessage    = "L'homme est condamné à être libre";
            SessionCipher     aliceSessionCipher = new SessionCipher(aliceStore, BobAddress);
            CiphertextMessage outgoingMessageOne = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes(originalMessage));

            Assert.AreEqual(CiphertextMessage.PrekeyType, outgoingMessageOne.GetMessageType());

            byte[] goodMessage = outgoingMessageOne.Serialize();
            byte[] badMessage  = new byte[goodMessage.Length];
            Array.Copy(goodMessage, 0, badMessage, 0, badMessage.Length);

            badMessage[badMessage.Length - 10] ^= 0x01;

            PreKeySignalMessage incomingMessage  = new PreKeySignalMessage(badMessage);
            SessionCipher       bobSessionCipher = new SessionCipher(bobStore, AliceAddress);

            byte[] plaintext = new byte[0];

            try
            {
                plaintext = bobSessionCipher.Decrypt(incomingMessage);
                throw new Exception("Decrypt should have failed!");
            }
            catch (InvalidMessageException)
            {
                // good.
            }

            Assert.IsTrue(bobStore.ContainsPreKey(31337));

            plaintext = bobSessionCipher.Decrypt(new PreKeySignalMessage(goodMessage));

            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext));
            Assert.IsFalse(bobStore.ContainsPreKey(31337));
        }
예제 #2
0
        public void TestRepeatBundleMessageV3()
        {
            ISignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
            SessionBuilder       aliceSessionBuilder = new SessionBuilder(aliceStore, BobAddress);

            ISignalProtocolStore bobStore = new TestInMemorySignalProtocolStore();

            EcKeyPair bobPreKeyPair       = Curve.GenerateKeyPair();
            EcKeyPair bobSignedPreKeyPair = Curve.GenerateKeyPair();

            byte[] bobSignedPreKeySignature = Curve.CalculateSignature(bobStore.GetIdentityKeyPair().GetPrivateKey(),
                                                                       bobSignedPreKeyPair.GetPublicKey().Serialize());

            PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(), 1,
                                                      31337, bobPreKeyPair.GetPublicKey(),
                                                      22, bobSignedPreKeyPair.GetPublicKey(), bobSignedPreKeySignature,
                                                      bobStore.GetIdentityKeyPair().GetPublicKey());

            bobStore.StorePreKey(31337, new PreKeyRecord(bobPreKey.GetPreKeyId(), bobPreKeyPair));
            bobStore.StoreSignedPreKey(22, new SignedPreKeyRecord(22, DateUtil.CurrentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));

            aliceSessionBuilder.Process(bobPreKey);

            String            originalMessage    = "L'homme est condamné à être libre";
            SessionCipher     aliceSessionCipher = new SessionCipher(aliceStore, BobAddress);
            CiphertextMessage outgoingMessageOne = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes(originalMessage));
            CiphertextMessage outgoingMessageTwo = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes(originalMessage));

            Assert.AreEqual(CiphertextMessage.PrekeyType, outgoingMessageOne.GetMessageType());
            Assert.AreEqual(CiphertextMessage.PrekeyType, outgoingMessageTwo.GetMessageType());

            PreKeySignalMessage incomingMessage = new PreKeySignalMessage(outgoingMessageOne.Serialize());

            SessionCipher bobSessionCipher = new SessionCipher(bobStore, AliceAddress);

            byte[] plaintext = bobSessionCipher.Decrypt(incomingMessage);
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext));

            CiphertextMessage bobOutgoingMessage = bobSessionCipher.Encrypt(Encoding.UTF8.GetBytes(originalMessage));

            byte[] alicePlaintext = aliceSessionCipher.Decrypt(new SignalMessage(bobOutgoingMessage.Serialize()));
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(alicePlaintext));

            // The test

            PreKeySignalMessage incomingMessageTwo = new PreKeySignalMessage(outgoingMessageTwo.Serialize());

            plaintext = bobSessionCipher.Decrypt(new PreKeySignalMessage(incomingMessageTwo.Serialize()));
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext));

            bobOutgoingMessage = bobSessionCipher.Encrypt(Encoding.UTF8.GetBytes(originalMessage));
            alicePlaintext     = aliceSessionCipher.Decrypt(new SignalMessage(bobOutgoingMessage.Serialize()));
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(alicePlaintext));
        }
예제 #3
0
        public void TestBasicSimultaneousInitiate()
        {
            ISignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
            ISignalProtocolStore bobStore   = new TestInMemorySignalProtocolStore();

            PreKeyBundle alicePreKeyBundle = CreateAlicePreKeyBundle(aliceStore);
            PreKeyBundle bobPreKeyBundle   = CreateBobPreKeyBundle(bobStore);

            SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BobAddress);
            SessionBuilder bobSessionBuilder   = new SessionBuilder(bobStore, AliceAddress);

            SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BobAddress);
            SessionCipher bobSessionCipher   = new SessionCipher(bobStore, AliceAddress);

            aliceSessionBuilder.Process(bobPreKeyBundle);
            bobSessionBuilder.Process(alicePreKeyBundle);

            CiphertextMessage messageForBob   = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes("hey there"));
            CiphertextMessage messageForAlice = bobSessionCipher.Encrypt(Encoding.UTF8.GetBytes("sample message"));

            Assert.AreEqual(CiphertextMessage.PrekeyType, messageForBob.GetMessageType());
            Assert.AreEqual(CiphertextMessage.PrekeyType, messageForAlice.GetMessageType());

            Assert.IsFalse(IsSessionIdEqual(aliceStore, bobStore));

            byte[] alicePlaintext = aliceSessionCipher.Decrypt(new PreKeySignalMessage(messageForAlice.Serialize()));
            byte[] bobPlaintext   = bobSessionCipher.Decrypt(new PreKeySignalMessage(messageForBob.Serialize()));

            Assert.AreEqual("sample message", Encoding.UTF8.GetString(alicePlaintext));
            Assert.AreEqual("hey there", Encoding.UTF8.GetString(bobPlaintext));

            Assert.AreEqual((uint)3, aliceStore.LoadSession(BobAddress).GetSessionState().GetSessionVersion());
            Assert.AreEqual((uint)3, bobStore.LoadSession(AliceAddress).GetSessionState().GetSessionVersion());

            Assert.IsFalse(IsSessionIdEqual(aliceStore, bobStore));

            CiphertextMessage aliceResponse = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes("second message"));

            Assert.AreEqual(CiphertextMessage.WhisperType, aliceResponse.GetMessageType());

            byte[] responsePlaintext = bobSessionCipher.Decrypt(new SignalMessage(aliceResponse.Serialize()));

            Assert.AreEqual("second message", Encoding.UTF8.GetString(responsePlaintext));
            Assert.IsTrue(IsSessionIdEqual(aliceStore, bobStore));

            CiphertextMessage finalMessage = bobSessionCipher.Encrypt(Encoding.UTF8.GetBytes("third message"));

            Assert.AreEqual(CiphertextMessage.WhisperType, finalMessage.GetMessageType());

            byte[] finalPlaintext = aliceSessionCipher.Decrypt(new SignalMessage(finalMessage.Serialize()));

            Assert.AreEqual("third message", Encoding.UTF8.GetString(finalPlaintext));
            Assert.IsTrue(IsSessionIdEqual(aliceStore, bobStore));
        }
예제 #4
0
        public void TestOptionalOneTimePreKey()
        {
            ISignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
            SessionBuilder       aliceSessionBuilder = new SessionBuilder(aliceStore, BobAddress);

            ISignalProtocolStore bobStore = new TestInMemorySignalProtocolStore();

            EcKeyPair bobPreKeyPair       = Curve.GenerateKeyPair();
            EcKeyPair bobSignedPreKeyPair = Curve.GenerateKeyPair();

            byte[] bobSignedPreKeySignature = Curve.CalculateSignature(bobStore.GetIdentityKeyPair().GetPrivateKey(),
                                                                       bobSignedPreKeyPair.GetPublicKey().Serialize());

            PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(), 1,
                                                      0, null,
                                                      22, bobSignedPreKeyPair.GetPublicKey(),
                                                      bobSignedPreKeySignature,
                                                      bobStore.GetIdentityKeyPair().GetPublicKey());

            aliceSessionBuilder.Process(bobPreKey);

            Assert.IsTrue(aliceStore.ContainsSession(BobAddress));
            Assert.AreEqual((uint)3, aliceStore.LoadSession(BobAddress).GetSessionState().GetSessionVersion());

            String            originalMessage    = "L'homme est condamné à être libre";
            SessionCipher     aliceSessionCipher = new SessionCipher(aliceStore, BobAddress);
            CiphertextMessage outgoingMessage    = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes(originalMessage));

            Assert.AreEqual(outgoingMessage.GetMessageType(), CiphertextMessage.PrekeyType);

            PreKeySignalMessage incomingMessage = new PreKeySignalMessage(outgoingMessage.Serialize());

            Assert.IsFalse(incomingMessage.GetPreKeyId().HasValue);

            bobStore.StorePreKey(31337, new PreKeyRecord(bobPreKey.GetPreKeyId(), bobPreKeyPair));
            bobStore.StoreSignedPreKey(22, new SignedPreKeyRecord(22, DateUtil.CurrentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));

            SessionCipher bobSessionCipher = new SessionCipher(bobStore, AliceAddress);

            byte[] plaintext = bobSessionCipher.Decrypt(incomingMessage);

            Assert.IsTrue(bobStore.ContainsSession(AliceAddress));
            Assert.AreEqual((uint)3, bobStore.LoadSession(AliceAddress).GetSessionState().GetSessionVersion());
            Assert.IsNotNull(bobStore.LoadSession(AliceAddress).GetSessionState().GetAliceBaseKey());
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext));
        }
예제 #5
0
        public void TestBadSignedPreKeySignature()
        {
            ISignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
            SessionBuilder       aliceSessionBuilder = new SessionBuilder(aliceStore, BobAddress);

            IDentityKeyStore bobIdentityKeyStore = new TestInMemoryIdentityKeyStore();

            EcKeyPair bobPreKeyPair       = Curve.GenerateKeyPair();
            EcKeyPair bobSignedPreKeyPair = Curve.GenerateKeyPair();

            byte[] bobSignedPreKeySignature = Curve.CalculateSignature(bobIdentityKeyStore.GetIdentityKeyPair().GetPrivateKey(),
                                                                       bobSignedPreKeyPair.GetPublicKey().Serialize());


            for (int i = 0; i < bobSignedPreKeySignature.Length * 8; i++)
            {
                byte[] modifiedSignature = new byte[bobSignedPreKeySignature.Length];
                Array.Copy(bobSignedPreKeySignature, 0, modifiedSignature, 0, modifiedSignature.Length);

                modifiedSignature[i / 8] ^= (byte)(0x01 << (i % 8));

                PreKeyBundle bobPreKey = new PreKeyBundle(bobIdentityKeyStore.GetLocalRegistrationId(), 1,
                                                          31337, bobPreKeyPair.GetPublicKey(),
                                                          22, bobSignedPreKeyPair.GetPublicKey(), modifiedSignature,
                                                          bobIdentityKeyStore.GetIdentityKeyPair().GetPublicKey());

                try
                {
                    aliceSessionBuilder.Process(bobPreKey);
                    throw new Exception("Accepted modified device key signature!");
                }
                catch (InvalidKeyException)
                {
                    // good
                }
            }

            PreKeyBundle bobPreKey2 = new PreKeyBundle(bobIdentityKeyStore.GetLocalRegistrationId(), 1,
                                                       31337, bobPreKeyPair.GetPublicKey(),
                                                       22, bobSignedPreKeyPair.GetPublicKey(), bobSignedPreKeySignature,
                                                       bobIdentityKeyStore.GetIdentityKeyPair().GetPublicKey());

            aliceSessionBuilder.Process(bobPreKey2);
        }
        public void TestMessageKeyLimits()
        {
            SessionRecord aliceSessionRecord = new SessionRecord();
            SessionRecord bobSessionRecord   = new SessionRecord();

            InitializeSessionsV3(aliceSessionRecord.GetSessionState(), bobSessionRecord.GetSessionState());

            ISignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
            ISignalProtocolStore bobStore   = new TestInMemorySignalProtocolStore();

            aliceStore.StoreSession(new SignalProtocolAddress("+14159999999", 1), aliceSessionRecord);
            bobStore.StoreSession(new SignalProtocolAddress("+14158888888", 1), bobSessionRecord);

            SessionCipher aliceCipher = new SessionCipher(aliceStore, new SignalProtocolAddress("+14159999999", 1));
            SessionCipher bobCipher   = new SessionCipher(bobStore, new SignalProtocolAddress("+14158888888", 1));

            List <CiphertextMessage> inflight = new List <CiphertextMessage>();

            for (int i = 0; i < 2010; i++)
            {
                inflight.Add(aliceCipher.Encrypt(Encoding.UTF8.GetBytes("you've never been so hungry, you've never been so cold")));
            }

            bobCipher.Decrypt(new SignalMessage(inflight[1000].Serialize()));
            bobCipher.Decrypt(new SignalMessage(inflight[inflight.Count - 1].Serialize()));

            try
            {
                bobCipher.Decrypt(new SignalMessage(inflight[0].Serialize()));
                throw new Exception("Should have failed!");
            }
            catch (DuplicateMessageException)
            {
                // good
            }
        }
        private void RunInteraction(SessionRecord aliceSessionRecord, SessionRecord bobSessionRecord)
        {
            ISignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
            ISignalProtocolStore bobStore   = new TestInMemorySignalProtocolStore();

            aliceStore.StoreSession(new SignalProtocolAddress("+14159999999", 1), aliceSessionRecord);
            bobStore.StoreSession(new SignalProtocolAddress("+14158888888", 1), bobSessionRecord);

            SessionCipher aliceCipher = new SessionCipher(aliceStore, new SignalProtocolAddress("+14159999999", 1));
            SessionCipher bobCipher   = new SessionCipher(bobStore, new SignalProtocolAddress("+14158888888", 1));

            byte[]            alicePlaintext = Encoding.UTF8.GetBytes("This is a plaintext message.");
            CiphertextMessage message        = aliceCipher.Encrypt(alicePlaintext);

            byte[] bobPlaintext = bobCipher.Decrypt(new SignalMessage(message.Serialize()));

            CollectionAssert.AreEqual(alicePlaintext, bobPlaintext);

            byte[]            bobReply = Encoding.UTF8.GetBytes("This is a message from Bob.");
            CiphertextMessage reply    = bobCipher.Encrypt(bobReply);

            byte[] receivedReply = aliceCipher.Decrypt(new SignalMessage(reply.Serialize()));

            CollectionAssert.AreEqual(bobReply, receivedReply);

            List <CiphertextMessage> aliceCiphertextMessages = new List <CiphertextMessage>();
            List <byte[]>            alicePlaintextMessages  = new List <byte[]>();

            for (int i = 0; i < 50; i++)
            {
                alicePlaintextMessages.Add(Encoding.UTF8.GetBytes("смерть за смерть " + i));
                aliceCiphertextMessages.Add(aliceCipher.Encrypt(Encoding.UTF8.GetBytes("смерть за смерть " + i)));
            }

            ulong seed = DateUtil.CurrentTimeMillis();

            HelperMethods.Shuffle(aliceCiphertextMessages, new Random((int)seed));
            HelperMethods.Shuffle(alicePlaintextMessages, new Random((int)seed));

            for (int i = 0; i < aliceCiphertextMessages.Count / 2; i++)
            {
                byte[] receivedPlaintext = bobCipher.Decrypt(new SignalMessage(aliceCiphertextMessages[i].Serialize()));
                Assert.IsTrue(ByteUtil.IsEqual(receivedPlaintext, alicePlaintextMessages[i]));
            }

            List <CiphertextMessage> bobCiphertextMessages = new List <CiphertextMessage>();
            List <byte[]>            bobPlaintextMessages  = new List <byte[]>();

            for (int i = 0; i < 20; i++)
            {
                bobPlaintextMessages.Add(Encoding.UTF8.GetBytes("смерть за смерть " + i));
                bobCiphertextMessages.Add(bobCipher.Encrypt(Encoding.UTF8.GetBytes("смерть за смерть " + i)));
            }

            seed = DateUtil.CurrentTimeMillis();

            HelperMethods.Shuffle(bobCiphertextMessages, new Random((int)seed));
            HelperMethods.Shuffle(bobPlaintextMessages, new Random((int)seed));

            for (int i = 0; i < bobCiphertextMessages.Count / 2; i++)
            {
                byte[] receivedPlaintext = aliceCipher.Decrypt(new SignalMessage(bobCiphertextMessages[i].Serialize()));
                CollectionAssert.AreEqual(receivedPlaintext, bobPlaintextMessages[i]);
            }

            for (int i = aliceCiphertextMessages.Count / 2; i < aliceCiphertextMessages.Count; i++)
            {
                byte[] receivedPlaintext = bobCipher.Decrypt(new SignalMessage(aliceCiphertextMessages[i].Serialize()));
                CollectionAssert.AreEqual(receivedPlaintext, alicePlaintextMessages[i]);
            }

            for (int i = bobCiphertextMessages.Count / 2; i < bobCiphertextMessages.Count; i++)
            {
                byte[] receivedPlaintext = aliceCipher.Decrypt(new SignalMessage(bobCiphertextMessages[i].Serialize()));
                CollectionAssert.AreEqual(receivedPlaintext, bobPlaintextMessages[i]);
            }
        }
예제 #8
0
        public void TestBasicPreKeyV3()
        {
            ISignalProtocolStore aliceStore          = new TestInMemorySignalProtocolStore();
            SessionBuilder       aliceSessionBuilder = new SessionBuilder(aliceStore, BobAddress);

            ISignalProtocolStore bobStore            = new TestInMemorySignalProtocolStore();
            EcKeyPair            bobPreKeyPair       = Curve.GenerateKeyPair();
            EcKeyPair            bobSignedPreKeyPair = Curve.GenerateKeyPair();

            byte[] bobSignedPreKeySignature = Curve.CalculateSignature(bobStore.GetIdentityKeyPair().GetPrivateKey(),
                                                                       bobSignedPreKeyPair.GetPublicKey().Serialize());

            PreKeyBundle bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(), 1,
                                                      31337, bobPreKeyPair.GetPublicKey(),
                                                      22, bobSignedPreKeyPair.GetPublicKey(),
                                                      bobSignedPreKeySignature,
                                                      bobStore.GetIdentityKeyPair().GetPublicKey());

            aliceSessionBuilder.Process(bobPreKey);

            Assert.IsTrue(aliceStore.ContainsSession(BobAddress));
            Assert.AreEqual((uint)3, aliceStore.LoadSession(BobAddress).GetSessionState().GetSessionVersion());

            String            originalMessage    = "L'homme est condamné à être libre";
            SessionCipher     aliceSessionCipher = new SessionCipher(aliceStore, BobAddress);
            CiphertextMessage outgoingMessage    = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes(originalMessage));

            Assert.AreEqual(CiphertextMessage.PrekeyType, outgoingMessage.GetMessageType());

            PreKeySignalMessage incomingMessage = new PreKeySignalMessage(outgoingMessage.Serialize());

            bobStore.StorePreKey(31337, new PreKeyRecord(bobPreKey.GetPreKeyId(), bobPreKeyPair));
            bobStore.StoreSignedPreKey(22, new SignedPreKeyRecord(22, DateUtil.CurrentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));

            SessionCipher bobSessionCipher = new SessionCipher(bobStore, AliceAddress);

            byte[] plaintext = bobSessionCipher.Decrypt(incomingMessage, new BobDecryptionCallback(bobStore, originalMessage));

            Assert.IsTrue(bobStore.ContainsSession(AliceAddress));
            Assert.AreEqual((uint)3, bobStore.LoadSession(AliceAddress).GetSessionState().GetSessionVersion());
            Assert.IsNotNull(bobStore.LoadSession(AliceAddress).GetSessionState().GetAliceBaseKey());
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext));

            CiphertextMessage bobOutgoingMessage = bobSessionCipher.Encrypt(Encoding.UTF8.GetBytes(originalMessage));

            Assert.AreEqual(CiphertextMessage.WhisperType, bobOutgoingMessage.GetMessageType());

            byte[] alicePlaintext = aliceSessionCipher.Decrypt(new SignalMessage(bobOutgoingMessage.Serialize()));
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(alicePlaintext));

            RunInteraction(aliceStore, bobStore);

            aliceStore          = new TestInMemorySignalProtocolStore();
            aliceSessionBuilder = new SessionBuilder(aliceStore, BobAddress);
            aliceSessionCipher  = new SessionCipher(aliceStore, BobAddress);

            bobPreKeyPair            = Curve.GenerateKeyPair();
            bobSignedPreKeyPair      = Curve.GenerateKeyPair();
            bobSignedPreKeySignature = Curve.CalculateSignature(bobStore.GetIdentityKeyPair().GetPrivateKey(), bobSignedPreKeyPair.GetPublicKey().Serialize());
            bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(),
                                         1, 31338, bobPreKeyPair.GetPublicKey(),
                                         23, bobSignedPreKeyPair.GetPublicKey(), bobSignedPreKeySignature,
                                         bobStore.GetIdentityKeyPair().GetPublicKey());

            bobStore.StorePreKey(31338, new PreKeyRecord(bobPreKey.GetPreKeyId(), bobPreKeyPair));
            bobStore.StoreSignedPreKey(23, new SignedPreKeyRecord(23, DateUtil.CurrentTimeMillis(), bobSignedPreKeyPair, bobSignedPreKeySignature));
            aliceSessionBuilder.Process(bobPreKey);

            outgoingMessage = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes(originalMessage));

            try
            {
                plaintext = bobSessionCipher.Decrypt(new PreKeySignalMessage(outgoingMessage.Serialize()));
                throw new Exception("shouldn't be trusted!");
            }
            catch (UntrustedIdentityException)
            {
                bobStore.SaveIdentity(AliceAddress, new PreKeySignalMessage(outgoingMessage.Serialize()).GetIdentityKey());
            }

            plaintext = bobSessionCipher.Decrypt(new PreKeySignalMessage(outgoingMessage.Serialize()));
            Assert.AreEqual(originalMessage, Encoding.UTF8.GetString(plaintext));

            bobPreKey = new PreKeyBundle(bobStore.GetLocalRegistrationId(), 1,
                                         31337, Curve.GenerateKeyPair().GetPublicKey(),
                                         23, bobSignedPreKeyPair.GetPublicKey(), bobSignedPreKeySignature,
                                         aliceStore.GetIdentityKeyPair().GetPublicKey());

            try
            {
                aliceSessionBuilder.Process(bobPreKey);
                throw new Exception("shoulnd't be trusted!");
            }
            catch (UntrustedIdentityException)
            {
                // good
            }
        }
예제 #9
0
        public void TestRepeatedSimultaneousInitiateLostMessageRepeatedMessages()
        {
            ISignalProtocolStore aliceStore = new TestInMemorySignalProtocolStore();
            ISignalProtocolStore bobStore   = new TestInMemorySignalProtocolStore();


            SessionBuilder aliceSessionBuilder = new SessionBuilder(aliceStore, BobAddress);
            SessionBuilder bobSessionBuilder   = new SessionBuilder(bobStore, AliceAddress);

            SessionCipher aliceSessionCipher = new SessionCipher(aliceStore, BobAddress);
            SessionCipher bobSessionCipher   = new SessionCipher(bobStore, AliceAddress);

            //    PreKeyBundle aliceLostPreKeyBundle = createAlicePreKeyBundle(aliceStore);
            PreKeyBundle bobLostPreKeyBundle = CreateBobPreKeyBundle(bobStore);

            aliceSessionBuilder.Process(bobLostPreKeyBundle);
            //    bobSessionBuilder.process(aliceLostPreKeyBundle);

            CiphertextMessage lostMessageForBob = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes("hey there"));

            //    CiphertextMessage lostMessageForAlice = bobSessionCipher.encrypt("sample message".getBytes());

            for (int i = 0; i < 15; i++)
            {
                PreKeyBundle alicePreKeyBundle = CreateAlicePreKeyBundle(aliceStore);
                PreKeyBundle bobPreKeyBundle   = CreateBobPreKeyBundle(bobStore);

                aliceSessionBuilder.Process(bobPreKeyBundle);
                bobSessionBuilder.Process(alicePreKeyBundle);

                CiphertextMessage messageForBob   = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes("hey there"));
                CiphertextMessage messageForAlice = bobSessionCipher.Encrypt(Encoding.UTF8.GetBytes("sample message"));

                Assert.AreEqual <uint>(messageForBob.GetMessageType(), CiphertextMessage.PrekeyType);
                Assert.AreEqual <uint>(messageForAlice.GetMessageType(), CiphertextMessage.PrekeyType);

                Assert.IsFalse(IsSessionIdEqual(aliceStore, bobStore));

                byte[] alicePlaintext = aliceSessionCipher.Decrypt(new PreKeySignalMessage(messageForAlice.Serialize()));
                byte[] bobPlaintext   = bobSessionCipher.Decrypt(new PreKeySignalMessage(messageForBob.Serialize()));

                Assert.IsTrue(Encoding.UTF8.GetString(alicePlaintext).Equals("sample message"));
                Assert.IsTrue(Encoding.UTF8.GetString(bobPlaintext).Equals("hey there"));

                Assert.IsTrue(aliceStore.LoadSession(BobAddress).GetSessionState().GetSessionVersion() == 3);
                Assert.IsTrue(bobStore.LoadSession(AliceAddress).GetSessionState().GetSessionVersion() == 3);

                Assert.IsFalse(IsSessionIdEqual(aliceStore, bobStore));
            }

            for (int i = 0; i < 50; i++)
            {
                CiphertextMessage messageForBobRepeat   = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes("hey there"));
                CiphertextMessage messageForAliceRepeat = bobSessionCipher.Encrypt(Encoding.UTF8.GetBytes("sample message"));

                Assert.AreEqual <uint>(messageForBobRepeat.GetMessageType(), CiphertextMessage.WhisperType);
                Assert.AreEqual <uint>(messageForAliceRepeat.GetMessageType(), CiphertextMessage.WhisperType);

                Assert.IsFalse(IsSessionIdEqual(aliceStore, bobStore));

                byte[] alicePlaintextRepeat = aliceSessionCipher.Decrypt(new SignalMessage(messageForAliceRepeat.Serialize()));
                byte[] bobPlaintextRepeat   = bobSessionCipher.Decrypt(new SignalMessage(messageForBobRepeat.Serialize()));

                Assert.IsTrue(Encoding.UTF8.GetString(alicePlaintextRepeat).Equals("sample message"));
                Assert.IsTrue(Encoding.UTF8.GetString(bobPlaintextRepeat).Equals("hey there"));

                Assert.IsFalse(IsSessionIdEqual(aliceStore, bobStore));
            }

            CiphertextMessage aliceResponse = aliceSessionCipher.Encrypt(Encoding.UTF8.GetBytes("second message"));

            Assert.AreEqual <uint>(aliceResponse.GetMessageType(), CiphertextMessage.WhisperType);

            byte[] responsePlaintext = bobSessionCipher.Decrypt(new SignalMessage(aliceResponse.Serialize()));

            Assert.IsTrue(Encoding.UTF8.GetString(responsePlaintext).Equals("second message"));
            Assert.IsTrue(IsSessionIdEqual(aliceStore, bobStore));

            CiphertextMessage finalMessage = bobSessionCipher.Encrypt(Encoding.UTF8.GetBytes("third message"));

            Assert.AreEqual <uint>(finalMessage.GetMessageType(), CiphertextMessage.WhisperType);

            byte[] finalPlaintext = aliceSessionCipher.Decrypt(new SignalMessage(finalMessage.Serialize()));

            Assert.IsTrue(Encoding.UTF8.GetString(finalPlaintext).Equals("third message"));
            Assert.IsTrue(IsSessionIdEqual(aliceStore, bobStore));

            byte[] lostMessagePlaintext = bobSessionCipher.Decrypt(new PreKeySignalMessage(lostMessageForBob.Serialize()));
            Assert.IsTrue(Encoding.UTF8.GetString(lostMessagePlaintext).Equals("hey there"));

            Assert.IsFalse(IsSessionIdEqual(aliceStore, bobStore));

            CiphertextMessage blastFromThePast = bobSessionCipher.Encrypt(Encoding.UTF8.GetBytes("unexpected!"));

            byte[] blastFromThePastPlaintext = aliceSessionCipher.Decrypt(new SignalMessage(blastFromThePast.Serialize()));

            Assert.IsTrue(Encoding.UTF8.GetString(blastFromThePastPlaintext).Equals("unexpected!"));
            Assert.IsTrue(IsSessionIdEqual(aliceStore, bobStore));
        }