Exemple #1
0
        public void Test_OmemoBundleInformation_2()
        {
            IdentityKeyPair      aliceIdentKey     = CryptoUtils.generateOmemoIdentityKeyPair();
            IList <PreKeyRecord> alicePreKeys      = CryptoUtils.generateOmemoPreKeys();
            SignedPreKeyRecord   aliceSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(aliceIdentKey);
            string bundleInfo = getBundleInfoMsg(aliceIdentKey, aliceSignedPreKey, alicePreKeys);

            MessageParser2         parser   = new MessageParser2();
            List <AbstractMessage> messages = parser.parseMessages(ref bundleInfo);

            // Check if message parsed successfully:
            Assert.IsTrue(messages.Count == 1);
            Assert.IsInstanceOfType(messages[0], typeof(OmemoBundleInformationResultMessage));

            OmemoBundleInformationResultMessage bundleInfoMsg = messages[0] as OmemoBundleInformationResultMessage;

            // Check if keys match:
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_IDENTITY_KEY.serialize().SequenceEqual(aliceIdentKey.getPublicKey().serialize()));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_SIGNED_PRE_KEY.serialize().SequenceEqual(aliceSignedPreKey.getKeyPair().getPublicKey().serialize()));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.SIGNED_PRE_KEY_ID == aliceSignedPreKey.getId());
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.SIGNED_PRE_KEY_SIGNATURE.SequenceEqual(aliceSignedPreKey.getSignature()));

            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_PRE_KEYS.Count == alicePreKeys.Count);
            foreach (PreKeyRecord key in alicePreKeys)
            {
                IEnumerable <Tuple <uint, ECPublicKey> > matches = bundleInfoMsg.BUNDLE_INFO.PUBLIC_PRE_KEYS.Where(x => x.Item1 == key.getId());
                Assert.IsTrue(matches.Count() == 1);
                byte[] a = matches.First().Item2.serialize();
                byte[] b = key.getKeyPair().getPublicKey().serialize();
                Assert.IsTrue(a.SequenceEqual(b));
            }
        }
Exemple #2
0
        public void Test_OmemoBundleInformation()
        {
            IdentityKeyPairModel bobIdentKey     = KeyHelper.GenerateIdentityKeyPair();
            List <PreKeyModel>   bobPreKeys      = KeyHelper.GeneratePreKeys(0, 100);
            SignedPreKeyModel    bobSignedPreKey = KeyHelper.GenerateSignedPreKey(0, bobIdentKey.privKey);
            Bundle bobBundle = new Bundle()
            {
                identityKey     = bobIdentKey.pubKey,
                preKeys         = bobPreKeys.Select(key => new PreKeyModel(null, key.pubKey, key.keyId)).ToList(),
                preKeySignature = bobSignedPreKey.signature,
                signedPreKey    = bobSignedPreKey.preKey.pubKey,
                signedPreKeyId  = bobSignedPreKey.preKey.keyId
            };
            string bundleInfo = GetBobsBundleInfoMsg(bobBundle);

            MessageParser2         parser   = new MessageParser2();
            List <AbstractMessage> messages = parser.parseMessages(ref bundleInfo);

            // Check if message parsed successfully:
            Assert.IsTrue(messages.Count == 1);
            Assert.IsInstanceOfType(messages[0], typeof(OmemoBundleInformationResultMessage));

            OmemoBundleInformationResultMessage bundleInfoMsg = messages[0] as OmemoBundleInformationResultMessage;

            // Check if keys match:
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.bundle.identityKey.Equals(bobIdentKey.pubKey));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.bundle.preKeys.SequenceEqual(bobPreKeys.Select(key => new PreKeyModel(null, key.pubKey, key.keyId)).ToList()));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.bundle.preKeySignature.SequenceEqual(bobSignedPreKey.signature));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.bundle.signedPreKey.Equals(bobSignedPreKey.preKey.pubKey));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.bundle.signedPreKeyId == bobSignedPreKey.preKey.keyId);
        }
        public void Test_MessageParser2_1()
        {
            string                 msg      = "<iq xml:lang='en' to='[email protected]/FABIAN-TOWER-PC' from='*****@*****.**' type='error' id='134077900-349929748-1523671119-224987985-1457976454'><pubsub xmlns='http://jabber.org/protocol/pubsub'><items node='eu.siacs.conversations.axolotl.devicelist'/></pubsub><error code='405' type='cancel'><closed-node xmlns='http://jabber.org/protocol/pubsub#errors'/><not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>";
            MessageParser2         parser   = new MessageParser2();
            List <AbstractMessage> messages = parser.parseMessages(ref msg);

            Assert.IsTrue(messages.Any((x) => x is IQErrorMessage));
        }
Exemple #4
0
        public void TestScramSHA1SASLMechanism_3()
        {
            ScramSHA1SASLMechanism     mechanism = new ScramSHA1SASLMechanism("user", "pencil", "fyko+d2lbbFgONRv9qkxdawL");
            SelectSASLMechanismMessage msg       = mechanism.getSelectSASLMechanismMessage();
            MessageParser2             parser    = new MessageParser2();
            List <AbstractMessage>     msgs      = parser.parseMessages("<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0wzcmZjTkhZSlkxWlZ2V1ZzN2oscz1RU1hDUitRNnNlazhiZjkyLGk9NDA5Ng==</challenge>");

            Assert.IsTrue(msgs[0] is ScramSHA1ChallengeMessage);
        }
Exemple #5
0
        public void Test_ScramSHA256SASLMechanism_3()
        {
            ScramSHA256SASLMechanism mechanism = new ScramSHA256SASLMechanism("user", "pencil", "rOprNGfwEbeRWgbNEkqO", null);

            mechanism.getSelectSASLMechanismMessage();
            MessageParser2         parser = new MessageParser2();
            string                 s      = "<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1yT3ByTkdmd0ViZVJXZ2JORWtxTyVodllEcFdVYTJSYVRDQWZ1eEZJbGopaE5sRiRrMCxzPVcyMlphSjBTTlk3c29Fc1VFamI2Z1E9PSxpPTQwOTY=</challenge>";
            List <AbstractMessage> msgs   = parser.parseMessages(ref s);

            Assert.IsTrue(msgs[0] is ScramSHAChallengeMessage);
        }
Exemple #6
0
        public void TestScramSHA1SASLMechanism_5()
        {
            ScramSHA1SASLMechanism            mechanism = new ScramSHA1SASLMechanism("user", "pencil", "fyko+d2lbbFgONRv9qkxdawL");
            SelectSASLMechanismMessage        msg       = mechanism.getSelectSASLMechanismMessage();
            MessageParser2                    parser    = new MessageParser2();
            List <AbstractMessage>            msgs      = parser.parseMessages("<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0wzcmZjTkhZSlkxWlZ2V1ZzN2oscz1RU1hDUitRNnNlazhiZjkyLGk9NDA5Ng==</challenge>");
            ScramSHA1ChallengeMessage         challenge = (ScramSHA1ChallengeMessage)msgs[0];
            AbstractMessage                   resp      = mechanism.generateResponse(challenge);
            ScramSha1ChallengeSolutionMessage respMsg   = (ScramSha1ChallengeSolutionMessage)resp;

            Assert.IsTrue(string.Equals("Yz1iaXdzLHI9ZnlrbytkMmxiYkZnT05Sdjlxa3hkYXdMM3JmY05IWUpZMVpWdldWczdqLHA9djBYOHYzQnoyVDBDSkdiSlF5RjBYK0hJNFRzPQ==".ToLower(), respMsg.SOLUTION.ToLower()));
        }
        public void Test_ScramSHA1SASLMechanism_4()
        {
            ScramSHA1SASLMechanism mechanism = new ScramSHA1SASLMechanism("user", "pencil", "fyko+d2lbbFgONRv9qkxdawL", null);

            mechanism.getSelectSASLMechanismMessage();
            MessageParser2            parser    = new MessageParser2();
            string                    s         = "<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1meWtvK2QybGJiRmdPTlJ2OXFreGRhd0wzcmZjTkhZSlkxWlZ2V1ZzN2oscz1RU1hDUitRNnNlazhiZjkyLGk9NDA5Ng==</challenge>";
            List <AbstractMessage>    msgs      = parser.parseMessages(ref s);
            ScramSHA1ChallengeMessage challenge = (ScramSHA1ChallengeMessage)msgs[0];
            AbstractMessage           resp      = mechanism.generateResponse(challenge);

            Assert.IsTrue(resp is ScramSha1ChallengeSolutionMessage);
        }
Exemple #8
0
        public void Test_ScramSHA256SASLMechanism_5()
        {
            ScramSHA256SASLMechanism mechanism = new ScramSHA256SASLMechanism("user", "pencil", "rOprNGfwEbeRWgbNEkqO", null);

            mechanism.getSelectSASLMechanismMessage();
            MessageParser2                   parser    = new MessageParser2();
            string                           s         = "<challenge xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>cj1yT3ByTkdmd0ViZVJXZ2JORWtxTyVodllEcFdVYTJSYVRDQWZ1eEZJbGopaE5sRiRrMCxzPVcyMlphSjBTTlk3c29Fc1VFamI2Z1E9PSxpPTQwOTY=</challenge>";
            List <AbstractMessage>           msgs      = parser.parseMessages(ref s);
            ScramSHAChallengeMessage         challenge = (ScramSHAChallengeMessage)msgs[0];
            AbstractMessage                  resp      = mechanism.generateResponse(challenge);
            ScramSHAChallengeSolutionMessage respMsg   = (ScramSHAChallengeSolutionMessage)resp;

            Assert.IsTrue(string.Equals("Yz1iaXdzLHI9ck9wck5HZndFYmVSV2diTkVrcU8laHZZRHBXVWEyUmFUQ0FmdXhGSWxqKWhObEYkazAscD1kSHpiWmFwV0lrNGpVaE4rVXRlOXl0YWc5empmTUhnc3FtbWl6N0FuZFZRPQ==".ToLower(), respMsg.SOLUTION.ToLower()));
        }
Exemple #9
0
        //--------------------------------------------------------Constructor:----------------------------------------------------------------\\
        #region --Constructors--
        /// <summary>
        /// Basic Constructor
        /// </summary>
        /// <history>
        /// 05/05/2018 Created [Fabian Sauter]
        /// </history>
        public XMPPConnection2(XMPPAccount account) : base(account)
        {
            this.holdConnection       = false;
            this.connectionErrorCount = 0;
            this.lastConnectionError  = null;
            this.TCP_CONNECTION       = new TCPConnection2(account);
            this.TCP_CONNECTION.ConnectionStateChanged += TCPConnection_ConnectionStateChanged;
            this.TCP_CONNECTION.NewDataReceived        += TCPConnection_NewDataReceived;

            this.PARSER             = new MessageParser2();
            this.MESSAGE_PROCESSORS = new AbstractMessageProcessor[4];
            this.streamId           = null;
            this.messageIdCache     = new TSTimedList <string>();

            this.connectionTimer    = null;
            this.reconnectRequested = false;
            this.timeout            = TimeSpan.FromMilliseconds(CONNECTION_TIMEOUT);

            this.GENERAL_COMMAND_HELPER = new GeneralCommandHelper(this);
            this.MUC_COMMAND_HELPER     = new MUCCommandHelper(this);
            this.PUB_SUB_COMMAND_HELPER = new PubSubCommandHelper(this);
            this.OMEMO_COMMAND_HELPER   = new OmemoCommandHelper(this);

            // The order in which new messages should get processed (TLS -- SASL -- Stream Management -- Resource binding -- ...).
            // https://xmpp.org/extensions/xep-0170.html
            //-------------------------------------------------------------
            // TLS:
            this.MESSAGE_PROCESSORS[0] = new TLSConnection(TCP_CONNECTION, this);

            // SASL:
            this.MESSAGE_PROCESSORS[1] = new SASLConnection(TCP_CONNECTION, this);

            // XEP-0198 (Stream Management):
            this.MESSAGE_PROCESSORS[2] = new SMConnection(TCP_CONNECTION, this);

            // Resource binding:
            RecourceBindingConnection recourceBindingConnection = new RecourceBindingConnection(TCP_CONNECTION, this);

            recourceBindingConnection.ResourceBound += RecourceBindingConnection_ResourceBound;
            this.MESSAGE_PROCESSORS[3] = recourceBindingConnection;
            //-------------------------------------------------------------

            NetworkHelper.Instance.NetworkChanged += Instance_NetworkChanged;

            this.omemoHelper          = null;
            this.DISCO_FEATURE_HELPER = new DiscoFeatureHelper(this);
        }
        public void Test_Parsing_MUCPresenceErrorMessage_2()
        {
            string                 msg      = "<presence xmlns:stream='http://etherx.jabber.org/streams' to='*****@*****.**' from='shakespeare.lit' type='error'> <error code='404' type='cancel'> <remote-server-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' /> </error> </presence>";
            MessageParser2         parser   = new MessageParser2();
            List <AbstractMessage> messages = parser.parseMessages(ref msg);

            Assert.IsTrue(messages.Count == 1);
            Assert.IsTrue(messages[0] is MUCPresenceErrorMessage);
            MUCPresenceErrorMessage errorMsg = messages[0] as MUCPresenceErrorMessage;

            Assert.AreEqual(errorMsg.getTo(), "*****@*****.**");
            Assert.AreEqual(errorMsg.getFrom(), "shakespeare.lit");
            Assert.AreEqual(errorMsg.TYPE, "error");
            Assert.IsNotNull(errorMsg.ERROR);
            Assert.IsTrue(string.IsNullOrEmpty(errorMsg.ERROR.BY));
            Assert.IsTrue(string.IsNullOrEmpty(errorMsg.ERROR.ERROR_MESSAGE));
            Assert.AreEqual(errorMsg.ERROR.ERROR_NAME, ErrorName.REMOTE_SERVER_NOT_FOUND);
            Assert.AreEqual(errorMsg.ERROR.ERROR_TYPE, ErrorType.CANCEL);
        }
        public void Test_Parsing_MUCPresenceErrorMessage_1()
        {
            string                 msg      = "<presence from='*****@*****.**' id='273hs51g' to='[email protected]/pda' type='error'> <error by='*****@*****.**' type='modify'> <jid-malformed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/> </error> </presence>";
            MessageParser2         parser   = new MessageParser2();
            List <AbstractMessage> messages = parser.parseMessages(ref msg);

            Assert.IsTrue(messages.Count == 1);
            Assert.IsTrue(messages[0] is MUCPresenceErrorMessage);
            MUCPresenceErrorMessage errorMsg = messages[0] as MUCPresenceErrorMessage;

            Assert.AreEqual(errorMsg.getTo(), "[email protected]/pda");
            Assert.AreEqual(errorMsg.getFrom(), "*****@*****.**");
            Assert.AreEqual(errorMsg.TYPE, "error");
            Assert.IsNotNull(errorMsg.ERROR);
            Assert.AreEqual(errorMsg.ERROR.BY, "*****@*****.**");
            Assert.IsTrue(string.IsNullOrEmpty(errorMsg.ERROR.ERROR_MESSAGE));
            Assert.AreEqual(errorMsg.ERROR.ERROR_NAME, ErrorName.JID_MALFORMED);
            Assert.AreEqual(errorMsg.ERROR.ERROR_TYPE, ErrorType.MODIFY);
        }
Exemple #12
0
        public void Test_OmemoDevices()
        {
            string msg = GetBobsDeviceListMsg();

            MessageParser2         parser   = new MessageParser2();
            List <AbstractMessage> messages = parser.parseMessages(ref msg);

            // Check if message parsed successfully:
            Assert.IsTrue(messages.Count == 1);
            Assert.IsInstanceOfType(messages[0], typeof(OmemoDeviceListResultMessage));

            OmemoDeviceListResultMessage devicesMsg = messages[0] as OmemoDeviceListResultMessage;

            // Check if keys match:
            Assert.IsTrue(devicesMsg.DEVICES.DEVICES.Count == 1);
            Assert.IsTrue(devicesMsg.DEVICES.DEVICES.First().IS_VALID);
            Assert.IsTrue(devicesMsg.DEVICES.DEVICES.First().ID == BOB_ADDRESS.DEVICE_ID);
            Assert.IsTrue(devicesMsg.DEVICES.DEVICES.First().label.Equals("Gajim on Ubuntu Linux"));
        }
        public void Test_MessageParser2_Performance_1()
        {
            string         msg    = "<iq xml:lang='en' to='[email protected]/FABIAN-TOWER-PC' from='*****@*****.**' type='error' id='134077900-349929748-1523671119-224987985-1457976454'><pubsub xmlns='http://jabber.org/protocol/pubsub'><items node='eu.siacs.conversations.axolotl.devicelist'/></pubsub><error code='405' type='cancel'><closed-node xmlns='http://jabber.org/protocol/pubsub#errors'/><not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>";
            MessageParser2 parser = new MessageParser2();
            Stopwatch      watch  = new Stopwatch();
            long           sum    = 0;

            for (int e = 0; e < 100; e++)
            {
                watch.Start();
                for (int i = 0; i < 1000; i++)
                {
                    parser.parseMessages(ref msg);
                }
                watch.Stop();
                sum += watch.ElapsedTicks;
            }
            sum /= 100;
            Logging.Logger.Info("[UNIT_TEST] Message Parser average parse time: " + sum);
        }
Exemple #14
0
        public void Test_OmemoBundleInformation_1()
        {
            IdentityKeyPair      aliceIdentKey     = CryptoUtils.generateOmemoIdentityKeyPair();
            IList <PreKeyRecord> alicePreKeys      = KeyHelper.generatePreKeys(0, 1);
            SignedPreKeyRecord   aliceSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(aliceIdentKey);
            string bundleInfo = getBundleInfoMsg(aliceIdentKey, aliceSignedPreKey, alicePreKeys);

            MessageParser2         parser   = new MessageParser2();
            List <AbstractMessage> messages = parser.parseMessages(ref bundleInfo);

            // Check if message parsed successfully:
            Assert.IsTrue(messages.Count == 1);
            Assert.IsInstanceOfType(messages[0], typeof(OmemoBundleInformationResultMessage));

            OmemoBundleInformationResultMessage bundleInfoMsg = messages[0] as OmemoBundleInformationResultMessage;

            // Check if keys match:
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_IDENTITY_KEY.serialize().SequenceEqual(aliceIdentKey.getPublicKey().serialize()));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_SIGNED_PRE_KEY.serialize().SequenceEqual(aliceSignedPreKey.getKeyPair().getPublicKey().serialize()));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.SIGNED_PRE_KEY_ID == aliceSignedPreKey.getId());
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.SIGNED_PRE_KEY_SIGNATURE.SequenceEqual(aliceSignedPreKey.getSignature()));
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_PRE_KEYS.Count == 1);
            Assert.IsTrue(bundleInfoMsg.BUNDLE_INFO.PUBLIC_PRE_KEYS[0].Item2.serialize().SequenceEqual(alicePreKeys[0].getKeyPair().getPublicKey().serialize()));
        }
Exemple #15
0
        public async void Test_Omemo_Enc_Dec_2()
        {
            // Generate Alices keys:
            IdentityKeyPair      aliceIdentKey     = CryptoUtils.generateOmemoIdentityKeyPair();
            IList <PreKeyRecord> alicePreKeys      = CryptoUtils.generateOmemoPreKeys();
            SignedPreKeyRecord   aliceSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(aliceIdentKey);

            // Create Alices stores:
            InMemoryIdentityKeyStore aliceIdentStore  = new InMemoryIdentityKeyStore(aliceIdentKey, ALICE_ADDRESS.getDeviceId());
            InMemoryPreKeyStore      alicePreKeyStore = new InMemoryPreKeyStore();

            foreach (PreKeyRecord key in alicePreKeys)
            {
                alicePreKeyStore.StorePreKey(key.getId(), key);
            }
            InMemorySignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore();

            aliceSignedPreKeyStore.StoreSignedPreKey(aliceSignedPreKey.getId(), aliceSignedPreKey);
            InMemorySessionStore aliceSessionStore = new InMemorySessionStore();

            // Generate Bobs keys:
            IdentityKeyPair      bobIdentKey     = CryptoUtils.generateOmemoIdentityKeyPair();
            IList <PreKeyRecord> bobPreKeys      = CryptoUtils.generateOmemoPreKeys();
            SignedPreKeyRecord   bobSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(bobIdentKey);

            // Create Bobs stores:
            InMemoryIdentityKeyStore bobIdentStore  = new InMemoryIdentityKeyStore(bobIdentKey, BOB_ADDRESS.getDeviceId());
            InMemoryPreKeyStore      bobPreKeyStore = new InMemoryPreKeyStore();

            foreach (PreKeyRecord key in bobPreKeys)
            {
                bobPreKeyStore.StorePreKey(key.getId(), key);
            }
            InMemorySignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore();

            bobSignedPreKeyStore.StoreSignedPreKey(bobSignedPreKey.getId(), bobSignedPreKey);
            InMemorySessionStore bobSessionStore = new InMemorySessionStore();


            //-----------------OMEOMO Session Building:-----------------
            MessageParser2 parser = new MessageParser2();

            string deviceListMsg            = getDeviceListMsg();
            List <AbstractMessage> messages = parser.parseMessages(ref deviceListMsg);

            Assert.IsTrue(messages.Count == 1);
            Assert.IsTrue(messages[0] is OmemoDeviceListResultMessage);
            OmemoDeviceListResultMessage devList = messages[0] as OmemoDeviceListResultMessage;

            uint selectedBobDeviceId = devList.DEVICES.getRandomDeviceId();

            Assert.IsTrue(selectedBobDeviceId == BOB_ADDRESS.getDeviceId());

            // Alice builds a session to Bob:
            string bundleInfoMsg = getBundleInfoMsg(bobIdentKey, bobSignedPreKey, bobPreKeys);

            messages = parser.parseMessages(ref bundleInfoMsg);
            Assert.IsTrue(messages.Count == 1);
            Assert.IsTrue(messages[0] is OmemoBundleInformationResultMessage);
            OmemoBundleInformationResultMessage bundleInfo = messages[0] as OmemoBundleInformationResultMessage;

            Assert.IsTrue(bundleInfo.DEVICE_ID == BOB_ADDRESS.getDeviceId());

            SessionBuilder sessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, aliceSignedPreKeyStore, aliceIdentStore, BOB_ADDRESS);
            PreKeyBundle   bobPreKey      = bundleInfo.BUNDLE_INFO.getRandomPreKey(bundleInfo.DEVICE_ID);

            sessionBuilder.process(bobPreKey);

            // Check if session exists:
            Assert.IsTrue(aliceSessionStore.ContainsSession(BOB_ADDRESS));
            Assert.IsTrue(aliceSessionStore.LoadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3);

            // Alice sends a message:
            string aliceOrigMsg = "$(rm -rvf .)";
            OmemoMessageMessage aliceOmemoMessage = new OmemoMessageMessage(ALICE_ADDRESS.getName() + "/SOME_RESOURCE", BOB_ADDRESS.getName(), aliceOrigMsg, MessageMessage.TYPE_CHAT, true);

            Assert.IsFalse(aliceOmemoMessage.ENCRYPTED);

            OmemoSession  omemoSession       = new OmemoSession(BOB_ADDRESS.getName());
            SessionCipher aliceSessionCipher = new SessionCipher(aliceSessionStore, alicePreKeyStore, aliceSignedPreKeyStore, aliceIdentStore, BOB_ADDRESS);

            omemoSession.DEVICE_SESSIONS_REMOTE.Add(BOB_ADDRESS.getDeviceId(), aliceSessionCipher);

            // Alice encrypts the message:
            aliceOmemoMessage.encrypt(omemoSession, ALICE_ADDRESS.getDeviceId());
            Assert.IsTrue(aliceOmemoMessage.ENCRYPTED);

            string aliceOmemoMsgText = aliceOmemoMessage.toXmlString();

            // Bob receives the message from Alice:
            messages = parser.parseMessages(ref aliceOmemoMsgText);
            Assert.IsTrue(messages.Count == 1);
            Assert.IsTrue(messages[0] is OmemoMessageMessage);
            OmemoMessageMessage bobOmemoMessage = messages[0] as OmemoMessageMessage;

            Assert.IsTrue(bobOmemoMessage.ENCRYPTED);
            Assert.AreEqual(bobOmemoMessage.SOURCE_DEVICE_ID, aliceOmemoMessage.SOURCE_DEVICE_ID);
            Assert.AreEqual(bobOmemoMessage.BASE_64_IV, aliceOmemoMessage.BASE_64_IV);
            Assert.AreEqual(bobOmemoMessage.BASE_64_PAYLOAD, aliceOmemoMessage.BASE_64_PAYLOAD);

            // Bob decrypts the message:
            SignalProtocolAddress aliceAddress     = new SignalProtocolAddress(Utils.getBareJidFromFullJid(bobOmemoMessage.getFrom()), bobOmemoMessage.SOURCE_DEVICE_ID);
            SessionCipher         bobSessionCipher = new SessionCipher(bobSessionStore, bobPreKeyStore, bobSignedPreKeyStore, bobIdentStore, aliceAddress);
            await bobOmemoMessage.decryptAsync(bobSessionCipher, aliceAddress, BOB_ADDRESS.getDeviceId(), null);

            Assert.IsFalse(bobOmemoMessage.ENCRYPTED);
            Assert.AreEqual(aliceOrigMsg, bobOmemoMessage.MESSAGE);
        }
Exemple #16
0
        public void Test_Omemo_Send_Receive_Send()
        {
            // Generate Alices keys:
            IdentityKeyPairModel aliceIdentKey     = KeyHelper.GenerateIdentityKeyPair();
            List <PreKeyModel>   alicePreKeys      = KeyHelper.GeneratePreKeys(0, 1);
            SignedPreKeyModel    aliceSignedPreKey = KeyHelper.GenerateSignedPreKey(0, aliceIdentKey.privKey);
            Bundle aliceBundle = new Bundle()
            {
                identityKey     = aliceIdentKey.pubKey,
                preKeys         = alicePreKeys.Select(key => new PreKeyModel(null, key.pubKey, key.keyId)).ToList(),
                preKeySignature = aliceSignedPreKey.signature,
                signedPreKey    = aliceSignedPreKey.preKey.pubKey,
                signedPreKeyId  = aliceSignedPreKey.preKey.keyId
            };
            InMemmoryOmemoStorage aliceStorage = new InMemmoryOmemoStorage();
            DoubleRachet          aliceRachet  = new DoubleRachet(aliceIdentKey);

            // Generate Bobs keys:
            IdentityKeyPairModel bobIdentKey     = KeyHelper.GenerateIdentityKeyPair();
            List <PreKeyModel>   bobPreKeys      = KeyHelper.GeneratePreKeys(0, 1);
            SignedPreKeyModel    bobSignedPreKey = KeyHelper.GenerateSignedPreKey(0, bobIdentKey.privKey);
            Bundle bobBundle = new Bundle()
            {
                identityKey     = bobIdentKey.pubKey,
                preKeys         = bobPreKeys.Select(key => new PreKeyModel(null, key.pubKey, key.keyId)).ToList(),
                preKeySignature = bobSignedPreKey.signature,
                signedPreKey    = bobSignedPreKey.preKey.pubKey,
                signedPreKeyId  = bobSignedPreKey.preKey.keyId
            };
            InMemmoryOmemoStorage bobStorage = new InMemmoryOmemoStorage();
            DoubleRachet          bobRachet  = new DoubleRachet(bobIdentKey);

            //-----------------OMEOMO Session Building:-----------------
            MessageParser2 parser = new MessageParser2();

            string deviceListMsg            = GetBobsDeviceListMsg();
            List <AbstractMessage> messages = parser.parseMessages(ref deviceListMsg);

            Assert.IsTrue(messages.Count == 1);
            Assert.IsTrue(messages[0] is OmemoDeviceListResultMessage);
            OmemoDeviceListResultMessage devList = messages[0] as OmemoDeviceListResultMessage;

            uint selectedBobDeviceId = devList.DEVICES.getRandomDeviceId();

            Assert.IsTrue(selectedBobDeviceId == BOB_ADDRESS.DEVICE_ID);

            // Alice builds a session to Bob:
            string bundleInfoMsg = GetBobsBundleInfoMsg(bobBundle);

            messages = parser.parseMessages(ref bundleInfoMsg);
            Assert.IsTrue(messages.Count == 1);
            Assert.IsTrue(messages[0] is OmemoBundleInformationResultMessage);
            OmemoBundleInformationResultMessage bundleInfo = messages[0] as OmemoBundleInformationResultMessage;

            Assert.IsTrue(bundleInfo.BUNDLE_INFO.deviceId == BOB_ADDRESS.DEVICE_ID);
            aliceStorage.StoreFingerprint(new OmemoFingerprint(bobBundle.identityKey, BOB_ADDRESS));

            // Encrypt Message 1:
            string msg1 = "Hello OMEMO";
            OmemoEncryptedMessage   omemoEncryptedMessage = new OmemoEncryptedMessage(ALICE_ADDRESS.BARE_JID, BOB_ADDRESS.BARE_JID, msg1, MessageMessage.TYPE_CHAT, false);
            List <OmemoDeviceGroup> bobDevices            = new List <OmemoDeviceGroup>();
            OmemoDeviceGroup        bobDeviceGroup        = new OmemoDeviceGroup(BOB_ADDRESS.BARE_JID);

            bobDeviceGroup.SESSIONS[BOB_ADDRESS.DEVICE_ID] = new OmemoSessionModel(bobBundle, 0, aliceIdentKey);
            bobDevices.Add(bobDeviceGroup);
            omemoEncryptedMessage.encrypt(ALICE_ADDRESS.DEVICE_ID, aliceIdentKey, aliceStorage, bobDevices);
            Assert.IsTrue(omemoEncryptedMessage.ENCRYPTED);
            Assert.IsNotNull(aliceStorage.LoadFingerprint(BOB_ADDRESS));
            Assert.IsNotNull(aliceStorage.LoadSession(BOB_ADDRESS));

            // Decrypt Message 1:
            // Throws an exception in case something goes wrong:
            OmemoDecryptionContext decryptCtx1 = new OmemoDecryptionContext(BOB_ADDRESS, bobIdentKey, bobSignedPreKey, bobPreKeys, false, bobStorage);

            omemoEncryptedMessage.decrypt(decryptCtx1);
            Assert.AreEqual(msg1, omemoEncryptedMessage.MESSAGE);
            Assert.IsFalse(omemoEncryptedMessage.IS_PURE_KEY_EXCHANGE_MESSAGE);
            Assert.IsFalse(omemoEncryptedMessage.ENCRYPTED);
            Assert.IsNotNull(bobStorage.LoadFingerprint(ALICE_ADDRESS));
            Assert.IsNotNull(bobStorage.LoadSession(ALICE_ADDRESS));

            // Encrypt Message 2:
            string msg2 = "Hello OMEMO 2";
            OmemoEncryptedMessage   omemoEncryptedMessage2 = new OmemoEncryptedMessage(BOB_ADDRESS.BARE_JID, ALICE_ADDRESS.BARE_JID, msg2, MessageMessage.TYPE_CHAT, false);
            List <OmemoDeviceGroup> aliceDevices           = new List <OmemoDeviceGroup>();
            OmemoDeviceGroup        aliceDeviceGroup       = new OmemoDeviceGroup(ALICE_ADDRESS.BARE_JID);

            aliceDeviceGroup.SESSIONS[ALICE_ADDRESS.DEVICE_ID] = bobStorage.LoadSession(ALICE_ADDRESS);
            aliceDevices.Add(aliceDeviceGroup);
            omemoEncryptedMessage2.encrypt(BOB_ADDRESS.DEVICE_ID, bobIdentKey, bobStorage, aliceDevices);
            Assert.IsTrue(omemoEncryptedMessage2.ENCRYPTED);

            // Decrypt Message 2:
            // Throws an exception in case something goes wrong:
            OmemoDecryptionContext decryptCtx2 = new OmemoDecryptionContext(ALICE_ADDRESS, aliceIdentKey, aliceSignedPreKey, alicePreKeys, false, aliceStorage);

            omemoEncryptedMessage2.decrypt(decryptCtx2);
            Assert.AreEqual(msg2, omemoEncryptedMessage2.MESSAGE);
            Assert.IsFalse(omemoEncryptedMessage2.IS_PURE_KEY_EXCHANGE_MESSAGE);
            Assert.IsFalse(omemoEncryptedMessage2.ENCRYPTED);

            // Encrypt Message 3:
            string msg3 = "Hello OMEMO 3";
            OmemoEncryptedMessage omemoEncryptedMessage3 = new OmemoEncryptedMessage(ALICE_ADDRESS.BARE_JID, BOB_ADDRESS.BARE_JID, msg3, MessageMessage.TYPE_CHAT, false);

            bobDeviceGroup.SESSIONS[BOB_ADDRESS.DEVICE_ID] = aliceStorage.LoadSession(BOB_ADDRESS);
            omemoEncryptedMessage3.encrypt(ALICE_ADDRESS.DEVICE_ID, aliceIdentKey, aliceStorage, bobDevices);
            Assert.IsFalse(omemoEncryptedMessage3.IS_PURE_KEY_EXCHANGE_MESSAGE);
            Assert.IsTrue(omemoEncryptedMessage3.ENCRYPTED);
            Assert.IsNotNull(aliceStorage.LoadFingerprint(BOB_ADDRESS));
            Assert.IsNotNull(aliceStorage.LoadSession(BOB_ADDRESS));

            // Decrypt Message 3:
            // Throws an exception in case something goes wrong:
            OmemoDecryptionContext decryptCtx3 = new OmemoDecryptionContext(BOB_ADDRESS, bobIdentKey, bobSignedPreKey, bobPreKeys, false, bobStorage);

            omemoEncryptedMessage3.decrypt(decryptCtx3);
            Assert.AreEqual(msg3, omemoEncryptedMessage3.MESSAGE);
            Assert.IsFalse(omemoEncryptedMessage3.IS_PURE_KEY_EXCHANGE_MESSAGE);
            Assert.IsFalse(omemoEncryptedMessage3.ENCRYPTED);
            Assert.IsNotNull(bobStorage.LoadFingerprint(ALICE_ADDRESS));
            Assert.IsNotNull(bobStorage.LoadSession(ALICE_ADDRESS));
        }
Exemple #17
0
        public void Test_Omemo_Enc_Dec_1()
        {
            // Generate Alices keys:
            IdentityKeyPair      aliceIdentKey     = CryptoUtils.generateOmemoIdentityKeyPair();
            IList <PreKeyRecord> alicePreKeys      = CryptoUtils.generateOmemoPreKeys();
            SignedPreKeyRecord   aliceSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(aliceIdentKey);

            // Create Alices stores:
            InMemoryIdentityKeyStore aliceIdentStore  = new InMemoryIdentityKeyStore(aliceIdentKey, ALICE_ADDRESS.getDeviceId());
            InMemoryPreKeyStore      alicePreKeyStore = new InMemoryPreKeyStore();

            foreach (PreKeyRecord key in alicePreKeys)
            {
                alicePreKeyStore.StorePreKey(key.getId(), key);
            }
            InMemorySignedPreKeyStore aliceSignedPreKeyStore = new InMemorySignedPreKeyStore();

            aliceSignedPreKeyStore.StoreSignedPreKey(aliceSignedPreKey.getId(), aliceSignedPreKey);
            InMemorySessionStore aliceSessionStore = new InMemorySessionStore();

            // Generate Bobs keys:
            IdentityKeyPair      bobIdentKey     = CryptoUtils.generateOmemoIdentityKeyPair();
            IList <PreKeyRecord> bobPreKeys      = CryptoUtils.generateOmemoPreKeys();
            SignedPreKeyRecord   bobSignedPreKey = CryptoUtils.generateOmemoSignedPreKey(bobIdentKey);

            // Create Bobs stores:
            InMemoryIdentityKeyStore bobIdentStore  = new InMemoryIdentityKeyStore(bobIdentKey, BOB_ADDRESS.getDeviceId());
            InMemoryPreKeyStore      bobPreKeyStore = new InMemoryPreKeyStore();

            foreach (PreKeyRecord key in bobPreKeys)
            {
                bobPreKeyStore.StorePreKey(key.getId(), key);
            }
            InMemorySignedPreKeyStore bobSignedPreKeyStore = new InMemorySignedPreKeyStore();

            bobSignedPreKeyStore.StoreSignedPreKey(bobSignedPreKey.getId(), bobSignedPreKey);
            InMemorySessionStore bobSessionStore = new InMemorySessionStore();


            //-----------------OMEOMO Session Building:-----------------
            MessageParser2 parser = new MessageParser2();

            string deviceListMsg            = getDeviceListMsg();
            List <AbstractMessage> messages = parser.parseMessages(ref deviceListMsg);

            Assert.IsTrue(messages.Count == 1);
            Assert.IsTrue(messages[0] is OmemoDeviceListResultMessage);
            OmemoDeviceListResultMessage devList = messages[0] as OmemoDeviceListResultMessage;

            uint selectedBobDeviceId = devList.DEVICES.getRandomDeviceId();

            Assert.IsTrue(selectedBobDeviceId == BOB_ADDRESS.getDeviceId());

            // Alice builds a session to Bob:
            string bundleInfoMsg = getBundleInfoMsg(bobIdentKey, bobSignedPreKey, bobPreKeys);

            messages = parser.parseMessages(ref bundleInfoMsg);
            Assert.IsTrue(messages.Count == 1);
            Assert.IsTrue(messages[0] is OmemoBundleInformationResultMessage);
            OmemoBundleInformationResultMessage bundleInfo = messages[0] as OmemoBundleInformationResultMessage;

            Assert.IsTrue(bundleInfo.DEVICE_ID == BOB_ADDRESS.getDeviceId());

            SessionBuilder sessionBuilder = new SessionBuilder(aliceSessionStore, alicePreKeyStore, aliceSignedPreKeyStore, aliceIdentStore, BOB_ADDRESS);
            PreKeyBundle   bobPreKey      = bundleInfo.BUNDLE_INFO.getRandomPreKey(bundleInfo.DEVICE_ID);

            sessionBuilder.process(bobPreKey);

            // Check if session exists:
            Assert.IsTrue(aliceSessionStore.ContainsSession(BOB_ADDRESS));
            Assert.IsTrue(aliceSessionStore.LoadSession(BOB_ADDRESS).getSessionState().getSessionVersion() == 3);

            // Alice sends a message:
            string aliceOrigMsg = "$(rm -rvf .)";

            // 1. Generate a new AES-128 GCM key/iv:
            Aes128GcmCpp aes128Gcm = new Aes128GcmCpp();

            aes128Gcm.generateKey();
            aes128Gcm.generateIv();

            // 2. Encrypt the message using the Aes128Gcm instance:
            byte[] encryptedData = aes128Gcm.encrypt(Encoding.UTF8.GetBytes(aliceOrigMsg));
            string base64Payload = Convert.ToBase64String(encryptedData);
            string base64IV      = Convert.ToBase64String(aes128Gcm.iv);

            // 3. Concatenate key and authentication tag:
            byte[] keyAuthTag = new byte[aes128Gcm.authTag.Length + aes128Gcm.key.Length];
            Buffer.BlockCopy(aes128Gcm.key, 0, keyAuthTag, 0, aes128Gcm.key.Length);
            Buffer.BlockCopy(aes128Gcm.authTag, 0, keyAuthTag, aes128Gcm.key.Length, aes128Gcm.authTag.Length);

            SessionCipher     aliceSessionCipher = new SessionCipher(aliceSessionStore, alicePreKeyStore, aliceSignedPreKeyStore, aliceIdentStore, BOB_ADDRESS);
            CiphertextMessage ciphertextMessage  = aliceSessionCipher.encrypt(keyAuthTag);
            OmemoKey          omemoKey           = new OmemoKey(BOB_ADDRESS.getDeviceId(), ciphertextMessage is PreKeySignalMessage, Convert.ToBase64String(ciphertextMessage.serialize()));

            Assert.IsTrue(string.Equals(Convert.ToBase64String(ciphertextMessage.serialize()), omemoKey.BASE_64_KEY));

            //-------------------Decrypt Again:-------------------

            // 2. Load the cipher:
            SessionCipher cipher = new SessionCipher(bobSessionStore, bobPreKeyStore, bobSignedPreKeyStore, bobIdentStore, ALICE_ADDRESS);

            byte[] encryptedKeyAuthTag = Convert.FromBase64String(omemoKey.BASE_64_KEY);
            byte[] decryptedKeyAuthTag = null;
            if (omemoKey.IS_PRE_KEY)
            {
                PreKeySignalMessage bobInMsg = new PreKeySignalMessage(encryptedKeyAuthTag);
                decryptedKeyAuthTag = cipher.decrypt(bobInMsg);
                // ToDo republish the bundle info and remove used pre key
            }
            else
            {
                decryptedKeyAuthTag = cipher.decrypt(new SignalMessage(encryptedKeyAuthTag));
            }

            // 3. Check if the cipher got loaded successfully:
            Assert.IsTrue(decryptedKeyAuthTag != null);

            // 4. Decrypt the payload:
            byte[] aesIv      = Convert.FromBase64String(base64IV);
            byte[] aesKey     = new byte[16];
            byte[] aesAuthTag = new byte[decryptedKeyAuthTag.Length - aesKey.Length];
            Buffer.BlockCopy(decryptedKeyAuthTag, 0, aesKey, 0, aesKey.Length);
            Buffer.BlockCopy(decryptedKeyAuthTag, aesKey.Length, aesAuthTag, 0, aesAuthTag.Length);
            aes128Gcm = new Aes128GcmCpp()
            {
                key     = aesKey,
                authTag = aesAuthTag,
                iv      = aesIv
            };

            encryptedData = Convert.FromBase64String(base64Payload);
            byte[] bobData = aes128Gcm.decrypt(encryptedData);

            // 5. Convert decrypted data to Unicode string:
            string bobRecMsg = Encoding.UTF8.GetString(bobData);

            // Check if successfully send:
            Assert.AreEqual(aliceOrigMsg, bobRecMsg);
            Assert.IsTrue(bobSessionStore.ContainsSession(ALICE_ADDRESS));
        }