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)); }
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)); }
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 } }
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)); }