private byte[] Decrypt(SessionState sessionState, SignalMessage ciphertextMessage) { if (!sessionState.HasSenderChain()) { throw new InvalidMessageException("Uninitialized session!"); } if (ciphertextMessage.GetMessageVersion() != sessionState.GetSessionVersion()) { throw new InvalidMessageException($"Message version {ciphertextMessage.GetMessageVersion()}, but session version {sessionState.GetSessionVersion()}"); } uint messageVersion = ciphertextMessage.GetMessageVersion(); IEcPublicKey theirEphemeral = ciphertextMessage.GetSenderRatchetKey(); uint counter = ciphertextMessage.GetCounter(); ChainKey chainKey = GetOrCreateChainKey(sessionState, theirEphemeral); MessageKeys messageKeys = GetOrCreateMessageKeys(sessionState, theirEphemeral, chainKey, counter); ciphertextMessage.VerifyMac(messageVersion, sessionState.GetRemoteIdentityKey(), sessionState.GetLocalIdentityKey(), messageKeys.GetMacKey()); byte[] plaintext = GetPlaintext(messageVersion, messageKeys, ciphertextMessage.GetBody()); sessionState.ClearUnacknowledgedPreKeyMessage(); return(plaintext); }
public void SetMessageKeys(IEcPublicKey senderEphemeral, MessageKeys messageKeys) { Pair <SessionStructure.Types.Chain, uint> chainAndIndex = GetReceiverChain(senderEphemeral); SessionStructure.Types.Chain chain = chainAndIndex.First(); SessionStructure.Types.Chain.Types.MessageKey messageKeyStructure = new SessionStructure.Types.Chain.Types.MessageKey { CipherKey = ByteString.CopyFrom(messageKeys.GetCipherKey()), MacKey = ByteString.CopyFrom(messageKeys.GetMacKey()), Index = messageKeys.GetCounter(), Iv = ByteString.CopyFrom(messageKeys.GetIv()) }; chain.MessageKeys.Add(messageKeyStructure); if (chain.MessageKeys.Count > MaxMessageKeys) { chain.MessageKeys.RemoveAt(0); } _sessionStructure.ReceiverChains[(int)chainAndIndex.Second()] = chain; }
public void SetMessageKeys(ECPublicKey senderEphemeral, MessageKeys messageKeys) { Pair <Chain, uint> chainAndIndex = GetReceiverChain(senderEphemeral); Chain chain = chainAndIndex.First(); Chain.Types.MessageKey messageKeyStructure = Chain.Types.MessageKey.CreateBuilder() .SetCipherKey(ByteString.CopyFrom(messageKeys.GetCipherKey() /*.getEncoded()*/)) .SetMacKey(ByteString.CopyFrom(messageKeys.GetMacKey() /*.getEncoded()*/)) .SetIndex(messageKeys.GetCounter()) .SetIv(ByteString.CopyFrom(messageKeys.GetIv() /*.getIV()*/)) .Build(); Chain.Builder updatedChain = chain.ToBuilder().AddMessageKeys(messageKeyStructure); if (updatedChain.MessageKeysList.Count > MAX_MESSAGE_KEYS) { updatedChain.MessageKeysList.RemoveAt(0); } this.sessionStructure = this.sessionStructure.ToBuilder() .SetReceiverChains((int)chainAndIndex.Second(), updatedChain.Build()) // TODO: conv .Build(); }
/** * Encrypt a message. * * @param paddedMessage The plaintext message bytes, optionally padded to a constant multiple. * @return A ciphertext message encrypted to the recipient+device tuple. */ public CiphertextMessage Encrypt(byte[] paddedMessage) { lock (SessionLock) { SessionRecord sessionRecord = _sessionStore.LoadSession(_remoteAddress); SessionState sessionState = sessionRecord.GetSessionState(); ChainKey chainKey = sessionState.GetSenderChainKey(); MessageKeys messageKeys = chainKey.GetMessageKeys(); IEcPublicKey senderEphemeral = sessionState.GetSenderRatchetKey(); uint previousCounter = sessionState.GetPreviousCounter(); uint sessionVersion = sessionState.GetSessionVersion(); byte[] ciphertextBody = GetCiphertext(sessionVersion, messageKeys, paddedMessage); CiphertextMessage ciphertextMessage = new SignalMessage(sessionVersion, messageKeys.GetMacKey(), senderEphemeral, chainKey.GetIndex(), previousCounter, ciphertextBody, sessionState.GetLocalIdentityKey(), sessionState.GetRemoteIdentityKey()); if (sessionState.HasUnacknowledgedPreKeyMessage()) { SessionState.UnacknowledgedPreKeyMessageItems items = sessionState.GetUnacknowledgedPreKeyMessageItems(); uint localRegistrationId = sessionState.GetLocalRegistrationId(); ciphertextMessage = new PreKeySignalMessage(sessionVersion, localRegistrationId, items.GetPreKeyId(), items.GetSignedPreKeyId(), items.GetBaseKey(), sessionState.GetLocalIdentityKey(), (SignalMessage)ciphertextMessage); } sessionState.SetSenderChainKey(chainKey.GetNextChainKey()); _sessionStore.StoreSession(_remoteAddress, sessionRecord); return(ciphertextMessage); } }