예제 #1
0
        public void Test_OmemoKeyExchangeMessage()
        {
            Random rand = new Random();

            byte[] hmac = new byte[16];
            rand.NextBytes(hmac);
            byte[] sessionKey = new byte[32];
            rand.NextBytes(sessionKey);

            IdentityKeyPairModel identityKey     = KeyHelper.GenerateIdentityKeyPair();
            SignedPreKeyModel    signedPreKey    = KeyHelper.GenerateSignedPreKey(0, identityKey.privKey);
            OmemoSessionModel    refOmemoSession = new OmemoSessionModel(new Bundle()
            {
                identityKey     = identityKey.pubKey,
                preKeys         = KeyHelper.GeneratePreKeys(0, 10),
                preKeySignature = signedPreKey.signature,
                signedPreKey    = signedPreKey.preKey.pubKey,
                signedPreKeyId  = signedPreKey.preKey.keyId
            }, 0, KeyHelper.GenerateIdentityKeyPair())
            {
                ek = KeyHelper.GenerateKeyPair().pubKey
            };
            OmemoMessage refOmemoMessage = new OmemoMessage(refOmemoSession);
            OmemoAuthenticatedMessage refOmemoAuthenticatedMessage = new OmemoAuthenticatedMessage(new byte[16], refOmemoMessage.ToByteArray());
            OmemoKeyExchangeMessage   refOmemoKeyExchangeMessage   = new OmemoKeyExchangeMessage((uint)rand.Next(), (uint)rand.Next(), KeyHelper.GenerateKeyPair().pubKey, KeyHelper.GenerateKeyPair().pubKey, refOmemoAuthenticatedMessage);

            byte[] data = refOmemoKeyExchangeMessage.ToByteArray();
            Assert.IsTrue(data.Length > 0);

            OmemoKeyExchangeMessage omemoKeyExchangeMessage = new OmemoKeyExchangeMessage(data);

            Assert.IsTrue(omemoKeyExchangeMessage.Equals(refOmemoKeyExchangeMessage));
        }
예제 #2
0
        /// <summary>
        /// Encrypts the given <paramref name="keyHmac"/> combination for all given devices and returns the resulting messages.
        /// Uses the given <see cref="OmemoSessionModel"/> for encrypting.
        /// </summary>
        /// <param name="keyHmac">The key HMAC combination, that should be encrypted.</param>
        /// <param name="devices">A collection of devices, we should encrypt the message for.</param>
        /// <returns>A collection of encrypted messages for each device grouped by their bare JID (List[Tuple[bareJid, List[Tuple[deviceId, IOmemoMessage]]]]).</returns>
        public List <Tuple <string, List <Tuple <uint, IOmemoMessage> > > > EncryptKeyHmacForDevices(byte[] keyHmac, List <OmemoDeviceGroup> devices)
        {
            List <Tuple <string, List <Tuple <uint, IOmemoMessage> > > > msgs = new List <Tuple <string, List <Tuple <uint, IOmemoMessage> > > >();

            foreach (OmemoDeviceGroup group in devices)
            {
                List <Tuple <uint, IOmemoMessage> > groupMsgs = new List <Tuple <uint, IOmemoMessage> >();
                foreach (KeyValuePair <uint, OmemoSessionModel> device in group.SESSIONS)
                {
                    try
                    {
                        OmemoSessionModel         session = device.Value;
                        OmemoAuthenticatedMessage authMsg = EncryptKeyHmacForDevices(keyHmac, device.Value, session.assData);

                        // To account for lost and out-of-order messages during the key exchange, OmemoKeyExchange structures are sent until a response by the recipient confirms that the key exchange was successfully completed.
                        if (session.nS == 0 || session.nR == 0)
                        {
                            OmemoKeyExchangeMessage kexMsg = new OmemoKeyExchangeMessage(session.preKeyId, session.signedPreKeyId, OWN_IDENTITY_KEY.pubKey, session.ek, authMsg);
                            groupMsgs.Add(new Tuple <uint, IOmemoMessage>(device.Key, kexMsg));
                        }
                        else
                        {
                            groupMsgs.Add(new Tuple <uint, IOmemoMessage>(device.Key, authMsg));
                        }
                    }
                    catch (OmemoException e)
                    {
                        Logger.Error("Failed to encrypt message for device " + group.ToString() + " with: " + e.ToString());
                    }
                }
                msgs.Add(new Tuple <string, List <Tuple <uint, IOmemoMessage> > >(group.BARE_JID, groupMsgs));
            }
            return(msgs);
        }