Пример #1
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);
            }
        }
Пример #2
0
        private ChainKey GetOrCreateChainKey(SessionState sessionState, IEcPublicKey theirEphemeral)

        {
            try
            {
                if (sessionState.HasReceiverChain(theirEphemeral))
                {
                    return(sessionState.GetReceiverChainKey(theirEphemeral));
                }
                else
                {
                    RootKey   rootKey      = sessionState.GetRootKey();
                    EcKeyPair ourEphemeral = sessionState.GetSenderRatchetKeyPair();
                    Pair <RootKey, ChainKey> receiverChain = rootKey.CreateChain(theirEphemeral, ourEphemeral);
                    EcKeyPair ourNewEphemeral            = Curve.GenerateKeyPair();
                    Pair <RootKey, ChainKey> senderChain = receiverChain.First().CreateChain(theirEphemeral, ourNewEphemeral);

                    sessionState.SetRootKey(senderChain.First());
                    sessionState.AddReceiverChain(theirEphemeral, receiverChain.Second());
                    sessionState.SetPreviousCounter(Math.Max(sessionState.GetSenderChainKey().GetIndex() - 1, 0));
                    sessionState.SetSenderChain(ourNewEphemeral, senderChain.Second());

                    return(receiverChain.Second());
                }
            }
            catch (InvalidKeyException e)
            {
                throw new InvalidMessageException(e);
            }
        }
Пример #3
0
        private MessageKeys GetOrCreateMessageKeys(SessionState sessionState,
                                                   IEcPublicKey theirEphemeral,
                                                   ChainKey chainKey, uint counter)

        {
            if (chainKey.GetIndex() > counter)
            {
                if (sessionState.HasMessageKeys(theirEphemeral, counter))
                {
                    return(sessionState.RemoveMessageKeys(theirEphemeral, counter));
                }
                else
                {
                    throw new DuplicateMessageException($"Received message with old counter: {chainKey.GetIndex()}  , {counter}");
                }
            }

            //Avoiding a uint overflow
            uint chainKeyIndex = chainKey.GetIndex();

            if ((counter > chainKeyIndex) && (counter - chainKeyIndex > 2000))
            {
                throw new InvalidMessageException("Over 2000 messages into the future!");
            }

            while (chainKey.GetIndex() < counter)
            {
                MessageKeys messageKeys = chainKey.GetMessageKeys();
                sessionState.SetMessageKeys(theirEphemeral, messageKeys);
                chainKey = chainKey.GetNextChainKey();
            }

            sessionState.SetReceiverChainKey(theirEphemeral, chainKey.GetNextChainKey());
            return(chainKey.GetMessageKeys());
        }
Пример #4
0
        private Pair <StorageProtos.SessionStructure.Types.Chain, uint> GetReceiverChain(IEcPublicKey senderEphemeral)
        {
            IList <StorageProtos.SessionStructure.Types.Chain> receiverChains = _sessionStructure.ReceiverChainsList;
            uint index = 0;

            foreach (StorageProtos.SessionStructure.Types.Chain receiverChain in receiverChains)
            {
                try
                {
                    IEcPublicKey chainSenderRatchetKey = Curve.DecodePoint(receiverChain.SenderRatchetKey.ToByteArray(), 0);

                    if (chainSenderRatchetKey.Equals(senderEphemeral))
                    {
                        return(new Pair <StorageProtos.SessionStructure.Types.Chain, uint>(receiverChain, index));
                    }
                }
                catch (InvalidKeyException e)
                {
                    Debug.WriteLine(e.ToString(), "SessionRecordV2");
                }

                index++;
            }

            return(null);
        }
Пример #5
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);
        }
Пример #6
0
        public PreKeySignalMessage(uint messageVersion, uint registrationId, May <uint> preKeyId,
                                   uint signedPreKeyId, IEcPublicKey baseKey, IdentityKey identityKey,
                                   SignalMessage message)
        {
            _version        = messageVersion;
            _registrationId = registrationId;
            _preKeyId       = preKeyId;
            _signedPreKeyId = signedPreKeyId;
            _baseKey        = baseKey;
            _identityKey    = identityKey;
            _message        = message;

            PreKeySignalMessage preKeySignalMessage = new PreKeySignalMessage
            {
                SignedPreKeyId = signedPreKeyId,
                BaseKey        = ByteString.CopyFrom(baseKey.Serialize()),
                IdentityKey    = ByteString.CopyFrom(identityKey.Serialize()),
                Message        = ByteString.CopyFrom(message.Serialize()),
                RegistrationId = registrationId
            };

            if (preKeyId.HasValue)                                       // .isPresent()
            {
                preKeySignalMessage.PreKeyId = preKeyId.ForceGetValue(); // get()
            }

            byte[] versionBytes = { ByteUtil.IntsToByteHighAndLow((int)_version, (int)CurrentVersion) };
            byte[] messageBytes = preKeySignalMessage.ToByteArray();

            _serialized = ByteUtil.Combine(versionBytes, messageBytes);
        }
Пример #7
0
        private SenderKeyState(uint id, uint iteration, byte[] chainKey,
                               IEcPublicKey signatureKeyPublic,
                               May <IEcPrivateKey> signatureKeyPrivate)
        {
            StorageProtos.SenderKeyStateStructure.Types.SenderChainKey senderChainKeyStructure =
                StorageProtos.SenderKeyStateStructure.Types.SenderChainKey.CreateBuilder()
                .SetIteration(iteration)
                .SetSeed(ByteString.CopyFrom(chainKey))
                .Build();

            StorageProtos.SenderKeyStateStructure.Types.SenderSigningKey.Builder signingKeyStructure =
                StorageProtos.SenderKeyStateStructure.Types.SenderSigningKey.CreateBuilder()
                .SetPublic(ByteString.CopyFrom(signatureKeyPublic.Serialize()));

            if (signatureKeyPrivate.HasValue)
            {
                signingKeyStructure.SetPrivate(ByteString.CopyFrom(signatureKeyPrivate.ForceGetValue().Serialize()));
            }

            _senderKeyStateStructure = StorageProtos.SenderKeyStateStructure.CreateBuilder()
                                       .SetSenderKeyId(id)
                                       .SetSenderChainKey(senderChainKeyStructure)
                                       .SetSenderSigningKey(signingKeyStructure)
                                       .Build();
        }
        public SignalMessage(uint messageVersion, byte[] macKey, IEcPublicKey senderRatchetKey,
                             uint counter, uint previousCounter, byte[] ciphertext,
                             IdentityKey senderIdentityKey,
                             IdentityKey receiverIdentityKey)
        {
            byte[] version = { ByteUtil.IntsToByteHighAndLow((int)messageVersion, (int)CurrentVersion) };
            byte[] message = new SignalMessage
            {
                ratchedKeyOneofCase_ = RatchedKeyOneofOneofCase.RatchetKey,
                RatchetKey           = ByteString.CopyFrom(senderRatchetKey.Serialize()), //TODO serialize ok?
                counterOneofCase_    = CounterOneofOneofCase.Counter,
                Counter = counter,
                previousCounterOneofCase_ = PreviousCounterOneofOneofCase.PreviousCounter,
                PreviousCounter           = previousCounter,
                ciphertextOneofCase_      = CiphertextOneofOneofCase.Ciphertext,
                Ciphertext = ByteString.CopyFrom(ciphertext),
            }.ToByteArray();

            byte[] mac = GetMac(senderIdentityKey, receiverIdentityKey, macKey, ByteUtil.Combine(version, message));

            _serialized       = ByteUtil.Combine(version, message, mac);
            _senderRatchetKey = senderRatchetKey;
            _counter          = counter;
            _previousCounter  = previousCounter;
            _ciphertext       = ciphertext;
            _messageVersion   = messageVersion;
        }
        private SenderKeyState(uint id, uint iteration, byte[] chainKey,
                               IEcPublicKey signatureKeyPublic,
                               May <IEcPrivateKey> signatureKeyPrivate)
        {
            SenderKeyStateStructure.Types.SenderChainKey senderChainKeyStructure = new SenderKeyStateStructure.Types.SenderChainKey
            {
                Iteration = iteration,
                Seed      = ByteString.CopyFrom(chainKey)
            };

            SenderKeyStateStructure.Types.SenderSigningKey signingKeyStructure = new SenderKeyStateStructure.Types.SenderSigningKey
            {
                Public = ByteString.CopyFrom(signatureKeyPublic.Serialize())
            };

            if (signatureKeyPrivate.HasValue)
            {
                signingKeyStructure.Private = ByteString.CopyFrom(signatureKeyPrivate.ForceGetValue().Serialize());
            }

            _senderKeyStateStructure = new SenderKeyStateStructure
            {
                SenderKeyId      = id,
                SenderChainKey   = senderChainKeyStructure,
                SenderSigningKey = signingKeyStructure
            };
        }
Пример #10
0
        public PreKeySignalMessage(uint messageVersion, uint registrationId, May <uint> preKeyId,
                                   uint signedPreKeyId, IEcPublicKey baseKey, IdentityKey identityKey,
                                   SignalMessage message)
        {
            _version        = messageVersion;
            _registrationId = registrationId;
            _preKeyId       = preKeyId;
            _signedPreKeyId = signedPreKeyId;
            _baseKey        = baseKey;
            _identityKey    = identityKey;
            _message        = message;

            WhisperProtos.PreKeySignalMessage.Builder builder =
                WhisperProtos.PreKeySignalMessage.CreateBuilder()
                .SetSignedPreKeyId(signedPreKeyId)
                .SetBaseKey(ByteString.CopyFrom(baseKey.Serialize()))
                .SetIdentityKey(ByteString.CopyFrom(identityKey.Serialize()))
                .SetMessage(ByteString.CopyFrom(message.Serialize()))
                .SetRegistrationId(registrationId);

            if (preKeyId.HasValue)                             // .isPresent()
            {
                builder.SetPreKeyId(preKeyId.ForceGetValue()); // get()
            }

            byte[] versionBytes = { ByteUtil.IntsToByteHighAndLow((int)_version, (int)CurrentVersion) };
            byte[] messageBytes = builder.Build().ToByteArray();

            _serialized = ByteUtil.Combine(versionBytes, messageBytes);
        }
Пример #11
0
 public UnacknowledgedPreKeyMessageItems(May <uint> preKeyId,
                                         uint signedPreKeyId,
                                         IEcPublicKey baseKey)
 {
     _preKeyId       = preKeyId;
     _signedPreKeyId = signedPreKeyId;
     _baseKey        = baseKey;
 }
        public void AddSenderKeyState(uint id, uint iteration, byte[] chainKey, IEcPublicKey signatureKey)
        {
            _senderKeyStates.AddFirst(new SenderKeyState(id, iteration, chainKey, signatureKey));

            if (_senderKeyStates.Count > MaxStates)
            {
                _senderKeyStates.RemoveLast();
            }
        }
Пример #13
0
        public EcKeyPair GetSenderRatchetKeyPair()
        {
            IEcPublicKey  publicKey  = GetSenderRatchetKey();
            IEcPrivateKey privateKey = Curve.DecodePrivatePoint(_sessionStructure.SenderChain
                                                                .SenderRatchetKeyPrivate
                                                                .ToByteArray());

            return(new EcKeyPair(publicKey, privateKey));
        }
        /// <summary>
        /// Build a new session from a {@link org.whispersystems.libsignal.state.PreKeyBundle} retrieved from
        /// a server.
        /// </summary>
        /// @param preKey A PreKey for the destination recipient, retrieved from a server.
        /// @throws InvalidKeyException when the {@link org.whispersystems.libsignal.state.PreKeyBundle} is
        ///                             badly formatted.
        /// @throws org.whispersystems.libsignal.UntrustedIdentityException when the sender's
        ///                                                                  {@link IdentityKey} is not
        ///                                                                  trusted.
        ///
        public void Process(PreKeyBundle preKey)
        {
            lock (SessionCipher.SessionLock)
            {
                if (!_identityKeyStore.IsTrustedIdentity(_remoteAddress, preKey.GetIdentityKey(), Direction.Sending))
                {
                    throw new UntrustedIdentityException(_remoteAddress.Name, preKey.GetIdentityKey());
                }

                if (preKey.GetSignedPreKey() != null &&
                    !Curve.VerifySignature(preKey.GetIdentityKey().GetPublicKey(),
                                           preKey.GetSignedPreKey().Serialize(),
                                           preKey.GetSignedPreKeySignature()))
                {
                    throw new InvalidKeyException("Invalid signature on device key!");
                }

                if (preKey.GetSignedPreKey() == null)
                {
                    throw new InvalidKeyException("No signed prekey!");
                }

                SessionRecord      sessionRecord     = _sessionStore.LoadSession(_remoteAddress);
                EcKeyPair          ourBaseKey        = Curve.GenerateKeyPair();
                IEcPublicKey       theirSignedPreKey = preKey.GetSignedPreKey();
                IEcPublicKey       test = preKey.GetPreKey();
                May <IEcPublicKey> theirOneTimePreKey   = (test == null) ? May <IEcPublicKey> .NoValue : new May <IEcPublicKey>(test);
                May <uint>         theirOneTimePreKeyId = theirOneTimePreKey.HasValue ? new May <uint>(preKey.GetPreKeyId()) :
                                                          May <uint> .NoValue;

                AliceSignalProtocolParameters.Builder parameters = AliceSignalProtocolParameters.NewBuilder();

                parameters.SetOurBaseKey(ourBaseKey)
                .SetOurIdentityKey(_identityKeyStore.GetIdentityKeyPair())
                .SetTheirIdentityKey(preKey.GetIdentityKey())
                .SetTheirSignedPreKey(theirSignedPreKey)
                .SetTheirRatchetKey(theirSignedPreKey)
                .SetTheirOneTimePreKey(theirOneTimePreKey);

                if (!sessionRecord.IsFresh())
                {
                    sessionRecord.ArchiveCurrentState();
                }

                RatchetingSession.InitializeSession(sessionRecord.GetSessionState(), parameters.Create());

                sessionRecord.GetSessionState().SetUnacknowledgedPreKeyMessage(theirOneTimePreKeyId, preKey.GetSignedPreKeyId(), ourBaseKey.GetPublicKey());
                sessionRecord.GetSessionState().SetLocalRegistrationId(_identityKeyStore.GetLocalRegistrationId());
                sessionRecord.GetSessionState().SetRemoteRegistrationId(preKey.GetRegistrationId());
                sessionRecord.GetSessionState().SetAliceBaseKey(ourBaseKey.GetPublicKey().Serialize());

                _identityKeyStore.SaveIdentity(_remoteAddress, preKey.GetIdentityKey());

                _sessionStore.StoreSession(_remoteAddress, sessionRecord);
            }
        }
Пример #15
0
        public EcKeyPair GetPendingKeyExchangeRatchetKey()
        {
            IEcPublicKey publicKey = Curve.DecodePoint(_sessionStructure.PendingKeyExchange
                                                       .LocalRatchetKey.ToByteArray(), 0);

            IEcPrivateKey privateKey = Curve.DecodePrivatePoint(_sessionStructure.PendingKeyExchange
                                                                .LocalRatchetKeyPrivate
                                                                .ToByteArray());

            return(new EcKeyPair(publicKey, privateKey));
        }
Пример #16
0
        public Pair <RootKey, ChainKey> CreateChain(IEcPublicKey theirRatchetKey, EcKeyPair ourRatchetKey)
        {
            byte[]             sharedSecret       = Curve.CalculateAgreement(theirRatchetKey, ourRatchetKey.GetPrivateKey());
            byte[]             derivedSecretBytes = _kdf.DeriveSecrets(sharedSecret, _key, Encoding.UTF8.GetBytes("WhisperRatchet"), DerivedRootSecrets.Size);
            DerivedRootSecrets derivedSecrets     = new DerivedRootSecrets(derivedSecretBytes);

            RootKey  newRootKey  = new RootKey(_kdf, derivedSecrets.GetRootKey());
            ChainKey newChainKey = new ChainKey(_kdf, derivedSecrets.GetChainKey(), 0);

            return(new Pair <RootKey, ChainKey>(newRootKey, newChainKey));
        }
Пример #17
0
 public static bool VerifySignature(IEcPublicKey signingKey, byte[] message, byte[] signature)
 {
     if (signingKey.GetKeyType() == DjbType)
     {
         return(Curve25519.GetInstance(Curve25519ProviderType.Best)
                .VerifySignature(((DjbEcPublicKey)signingKey).GetPublicKey(), message, signature));
     }
     else
     {
         throw new InvalidKeyException("Unknown type: " + signingKey.GetKeyType());
     }
 }
 public PreKeyBundle(uint registrationId, uint deviceId, uint preKeyId, IEcPublicKey preKeyPublic,
                     uint signedPreKeyId, IEcPublicKey signedPreKeyPublic, byte[] signedPreKeySignature,
                     IdentityKey identityKey)
 {
     _registrationId        = registrationId;
     _deviceId              = deviceId;
     _preKeyId              = preKeyId;
     _preKeyPublic          = preKeyPublic;
     _signedPreKeyId        = signedPreKeyId;
     _signedPreKeyPublic    = signedPreKeyPublic;
     _signedPreKeySignature = signedPreKeySignature;
     _identityKey           = identityKey;
 }
        public EcKeyPair GetKeyPair()
        {
            try
            {
                IEcPublicKey  publicKey  = Curve.DecodePoint(_structure.PublicKey.ToByteArray(), 0);
                IEcPrivateKey privateKey = Curve.DecodePrivatePoint(_structure.PrivateKey.ToByteArray());

                return(new EcKeyPair(publicKey, privateKey));
            }
            catch (InvalidKeyException e)
            {
                throw new Exception(e.Message);
            }
        }
        public SenderKeyDistributionMessage(uint id, uint iteration, byte[] chainKey, IEcPublicKey signatureKey)
        {
            byte[] version  = { ByteUtil.IntsToByteHighAndLow((int)CurrentVersion, (int)CurrentVersion) };
            byte[] protobuf = WhisperProtos.SenderKeyDistributionMessage.CreateBuilder()
                              .SetId(id)
                              .SetIteration(iteration)
                              .SetChainKey(ByteString.CopyFrom(chainKey))
                              .SetSigningKey(ByteString.CopyFrom(signatureKey.Serialize()))
                              .Build().ToByteArray();

            _id           = id;
            _iteration    = iteration;
            _chainKey     = chainKey;
            _signatureKey = signatureKey;
            _serialized   = ByteUtil.Combine(version, protobuf);
        }
        public void SetReceiverChainKey(IEcPublicKey senderEphemeral, ChainKey chainKey)
        {
            Pair <SessionStructure.Types.Chain, uint> chainAndIndex = GetReceiverChain(senderEphemeral);

            SessionStructure.Types.Chain chain = chainAndIndex.First();

            SessionStructure.Types.Chain.Types.ChainKey chainKeyStructure = new SessionStructure.Types.Chain.Types.ChainKey
            {
                Key   = ByteString.CopyFrom(chainKey.GetKey()),
                Index = chainKey.GetIndex()
            };

            chain.ChainKey = chainKeyStructure;

            _sessionStructure.ReceiverChains[(int)chainAndIndex.Second()] = chain;
        }
        public void VerifySignature(IEcPublicKey signatureKey)
        {
            try
            {
                byte[][] parts = ByteUtil.Split(_serialized, _serialized.Length - SignatureLength, SignatureLength);

                if (!Curve.VerifySignature(signatureKey, parts[0], parts[1]))
                {
                    throw new InvalidMessageException("Invalid signature!");
                }
            }
            catch (InvalidKeyException e)
            {
                throw new InvalidMessageException(e);
            }
        }
        BobSignalProtocolParameters(IdentityKeyPair ourIdentityKey, EcKeyPair ourSignedPreKey,
                                    EcKeyPair ourRatchetKey, May <EcKeyPair> ourOneTimePreKey,
                                    IdentityKey theirIdentityKey, IEcPublicKey theirBaseKey)
        {
            _ourIdentityKey   = ourIdentityKey;
            _ourSignedPreKey  = ourSignedPreKey;
            _ourRatchetKey    = ourRatchetKey;
            _ourOneTimePreKey = ourOneTimePreKey;
            _theirIdentityKey = theirIdentityKey;
            _theirBaseKey     = theirBaseKey;

            if (ourIdentityKey == null || ourSignedPreKey == null || ourRatchetKey == null ||
                ourOneTimePreKey == null || theirIdentityKey == null || theirBaseKey == null)
            {
                throw new Exception("Null value!");
            }
        }
Пример #24
0
        public SenderKeyDistributionMessage(uint id, uint iteration, byte[] chainKey, IEcPublicKey signatureKey)
        {
            byte[] version  = { ByteUtil.IntsToByteHighAndLow((int)CurrentVersion, (int)CurrentVersion) };
            byte[] protobuf = new SenderKeyDistributionMessage
            {
                Id         = id,
                Iteration  = iteration,
                ChainKey   = ByteString.CopyFrom(chainKey),
                SigningKey = ByteString.CopyFrom(signatureKey.Serialize())
            }.ToByteArray();

            _id           = id;
            _iteration    = iteration;
            _chainKey     = chainKey;
            _signatureKey = signatureKey;
            _serialized   = ByteUtil.Combine(version, protobuf);
        }
Пример #25
0
        public void SetReceiverChainKey(IEcPublicKey senderEphemeral, ChainKey chainKey)
        {
            Pair <StorageProtos.SessionStructure.Types.Chain, uint> chainAndIndex = GetReceiverChain(senderEphemeral);

            StorageProtos.SessionStructure.Types.Chain chain = chainAndIndex.First();

            StorageProtos.SessionStructure.Types.Chain.Types.ChainKey chainKeyStructure = StorageProtos.SessionStructure.Types.Chain.Types.ChainKey.CreateBuilder()
                                                                                          .SetKey(ByteString.CopyFrom(chainKey.GetKey()))
                                                                                          .SetIndex(chainKey.GetIndex())
                                                                                          .Build();

            StorageProtos.SessionStructure.Types.Chain updatedChain = chain.ToBuilder().SetChainKey(chainKeyStructure).Build();

            _sessionStructure = _sessionStructure.ToBuilder()
                                .SetReceiverChains((int)chainAndIndex.Second(), updatedChain)                                                                                  // TODO: conv
                                .Build();
        }
Пример #26
0
        public ChainKey GetReceiverChainKey(IEcPublicKey senderEphemeral)
        {
            Pair <StorageProtos.SessionStructure.Types.Chain, uint> receiverChainAndIndex = GetReceiverChain(senderEphemeral);

            StorageProtos.SessionStructure.Types.Chain receiverChain = receiverChainAndIndex.First();

            if (receiverChain == null)
            {
                return(null);
            }
            else
            {
                return(new ChainKey(Hkdf.CreateFor(GetSessionVersion()),
                                    receiverChain.ChainKey.Key.ToByteArray(),
                                    receiverChain.ChainKey.Index));
            }
        }
Пример #27
0
        SymmetricSignalProtocolParameters(EcKeyPair ourBaseKey, EcKeyPair ourRatchetKey,
                                          IdentityKeyPair ourIdentityKey, IEcPublicKey theirBaseKey,
                                          IEcPublicKey theirRatchetKey, IdentityKey theirIdentityKey)
        {
            _ourBaseKey       = ourBaseKey;
            _ourRatchetKey    = ourRatchetKey;
            _ourIdentityKey   = ourIdentityKey;
            _theirBaseKey     = theirBaseKey;
            _theirRatchetKey  = theirRatchetKey;
            _theirIdentityKey = theirIdentityKey;

            if (ourBaseKey == null || ourRatchetKey == null || ourIdentityKey == null ||
                theirBaseKey == null || theirRatchetKey == null || theirIdentityKey == null)
            {
                throw new Exception("Null values!");
            }
        }
Пример #28
0
        public static byte[] CalculateAgreement(IEcPublicKey publicKey, IEcPrivateKey privateKey)
        {
            if (publicKey.GetKeyType() != privateKey.GetKeyType())
            {
                throw new InvalidKeyException("Public and private keys must be of the same type!");
            }

            if (publicKey.GetKeyType() == DjbType)
            {
                return(Curve25519.GetInstance(Curve25519ProviderType.Best)
                       .CalculateAgreement(((DjbEcPublicKey)publicKey).GetPublicKey(),
                                           ((DjbEcPrivateKey)privateKey).GetPrivateKey()));
            }
            else
            {
                throw new InvalidKeyException("Unknown type: " + publicKey.GetKeyType());
            }
        }
Пример #29
0
        public void AddReceiverChain(IEcPublicKey senderRatchetKey, ChainKey chainKey)
        {
            StorageProtos.SessionStructure.Types.Chain.Types.ChainKey chainKeyStructure = StorageProtos.SessionStructure.Types.Chain.Types.ChainKey.CreateBuilder()
                                                                                          .SetKey(ByteString.CopyFrom(chainKey.GetKey()))
                                                                                          .SetIndex(chainKey.GetIndex())
                                                                                          .Build();

            StorageProtos.SessionStructure.Types.Chain chain = StorageProtos.SessionStructure.Types.Chain.CreateBuilder()
                                                               .SetChainKey(chainKeyStructure)
                                                               .SetSenderRatchetKey(ByteString.CopyFrom(senderRatchetKey.Serialize()))
                                                               .Build();

            _sessionStructure = _sessionStructure.ToBuilder().AddReceiverChains(chain).Build();

            if (_sessionStructure.ReceiverChainsList.Count > 5)
            {
                _sessionStructure = _sessionStructure.ToBuilder() /*.ClearReceiverChains()*/.Build();                //RemoveReceiverChains(0) TODO: why does it work without
            }
        }
        public SignalMessage(byte[] serialized)
        {
            try
            {
                byte[][] messageParts = ByteUtil.Split(serialized, 1, serialized.Length - 1 - MacLength, MacLength);
                byte     version      = messageParts[0][0];
                byte[]   message      = messageParts[1];
                byte[]   mac          = messageParts[2];

                if (ByteUtil.HighBitsToInt(version) < CurrentVersion)
                {
                    throw new LegacyMessageException("Legacy message: " + ByteUtil.HighBitsToInt(version));
                }

                if (ByteUtil.HighBitsToInt(version) > CurrentVersion)
                {
                    throw new InvalidMessageException("Unknown version: " + ByteUtil.HighBitsToInt(version));
                }

                SignalMessage signalMessage = Parser.ParseFrom(message);



                if (signalMessage.CiphertextOneofCase == CiphertextOneofOneofCase.None ||
                    signalMessage.CounterOneofCase == CounterOneofOneofCase.None ||
                    signalMessage.RatchedKeyOneofCase == RatchedKeyOneofOneofCase.None)
                {
                    throw new InvalidMessageException("Incomplete message.");
                }

                _serialized       = serialized;
                _senderRatchetKey = Curve.DecodePoint(signalMessage.RatchetKey.ToByteArray(), 0);
                _messageVersion   = (uint)ByteUtil.HighBitsToInt(version);
                _counter          = signalMessage.Counter;
                _previousCounter  = signalMessage.PreviousCounter;
                _ciphertext       = signalMessage.Ciphertext.ToByteArray();
            }
            catch (/*InvalidProtocolBufferException | InvalidKeyException | Parse*/ Exception e)
            {
                throw new InvalidMessageException(e);
            }
        }