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