Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 3
0
        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();
        }
Ejemplo n.º 4
0
        /**
         * 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);
            }
        }