Exemplo n.º 1
0
        private KeyExchangeMessage ProcessInitiate(KeyExchangeMessage message)
        {
            UInt32           flags         = KeyExchangeMessage.RESPONSE_FLAG;
            SessionRecord sessionRecord = _sessionStore.LoadSession(_remoteAddress);

            if (message.Version >= 3 &&
                !Curve.VerifySignature(message.IdentityKey.PublicKey,
                                   message.BaseKey.Serialize(),
                                   message.BaseKeySignature))
            {
                throw new InvalidKeyException("Bad signature!");
            }

            var builder = SymmetricAxolotlParameters.NewBuilder();

            if (!sessionRecord.SessionState.HasPendingKeyExchange) {
                builder.SetOurIdentityKey(_identityKeyStore.GetIdentityKeyPair())
                            .SetOurBaseKey(Curve.GenerateKeyPair())
                            .SetOurRatchetKey(Curve.GenerateKeyPair());
            } else {
                builder.SetOurIdentityKey(sessionRecord.SessionState.PendingKeyExchangeIdentityKey)
                            .SetOurBaseKey(sessionRecord.SessionState.PendingKeyExchangeBaseKey)
                            .SetOurRatchetKey(sessionRecord.SessionState.PendingKeyExchangeRatchetKey);
                flags |= KeyExchangeMessage.SIMULTAENOUS_INITIATE_FLAG;
            }

            builder.SetTheirBaseKey(message.BaseKey)
                        .SetTheirRatchetKey(message.RatchetKey)
                        .SetTheirIdentityKey(message.IdentityKey);

            var parameters = builder.Create();

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

            RatchetingSession.InitializeSession(sessionRecord.SessionState,
                                                (UInt32)Math.Min(message.MaxVersion, CiphertextMessage.CURRENT_VERSION),
                                                parameters);

            _sessionStore.StoreSession(_remoteAddress, sessionRecord);
            _identityKeyStore.SaveIdentity(_remoteAddress.Name, message.IdentityKey);

            byte[] baseKeySignature = Curve.CalculateSignature(parameters.OurIdentityKey.PrivateKey,
                                                               parameters.OurBaseKey.PublicKey.Serialize());

            return new KeyExchangeMessage(sessionRecord.SessionState.GetSessionVersion(),
                                          message.Sequence, flags,
                                          parameters.OurBaseKey.PublicKey,
                                          baseKeySignature, parameters.OurRatchetKey.PublicKey,
                                          parameters.OurIdentityKey.PublicKey);
        }
Exemplo n.º 2
0
        private void ProcessResponse(KeyExchangeMessage message)
        {
            var sessionRecord                  = _sessionStore.LoadSession(_remoteAddress);
            var sessionState                   = sessionRecord.SessionState;
            var hasPendingKeyExchange          = sessionState.HasPendingKeyExchange;
            var isSimultaneousInitiateResponse = message.IsResponseForSimultaneousInitiate;

            if (!hasPendingKeyExchange || sessionState.PendingKeyExchangeSequence != message.Sequence) {
                Console.WriteLine("TAG : " + "No matching sequence for response. Is simultaneous initiate response: " + isSimultaneousInitiateResponse);
                if (!isSimultaneousInitiateResponse) throw new StaleKeyExchangeException();
                else                                 return;
            }

            var parameters = SymmetricAxolotlParameters.NewBuilder();

            parameters.SetOurBaseKey(sessionRecord.SessionState.PendingKeyExchangeBaseKey)
                    .SetOurRatchetKey(sessionRecord.SessionState.PendingKeyExchangeRatchetKey)
                    .SetOurIdentityKey(sessionRecord.SessionState.PendingKeyExchangeIdentityKey)
                    .SetTheirBaseKey(message.BaseKey)
                    .SetTheirRatchetKey(message.RatchetKey)
                    .SetTheirIdentityKey(message.IdentityKey);

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

            RatchetingSession.InitializeSession(sessionRecord.SessionState,
                                                (UInt32)Math.Min(message.MaxVersion, CiphertextMessage.CURRENT_VERSION),
                                                parameters.Create());

            if (sessionRecord.SessionState.GetSessionVersion() >= 3 &&
                !Curve.VerifySignature(message.IdentityKey.PublicKey,
                                   message.BaseKey.Serialize(),
                                   message.BaseKeySignature))
            {
                throw new InvalidKeyException("Base key signature doesn't match!");
            }

            _sessionStore.StoreSession(_remoteAddress, sessionRecord);
            _identityKeyStore.SaveIdentity(_remoteAddress.Name, message.IdentityKey);
        }
Exemplo n.º 3
0
        public KeyExchangeMessage Process(KeyExchangeMessage message)
        {
            lock (SessionCipher.SESSION_LOCK) {
                if (!_identityKeyStore.IsTrustedIdentity(_remoteAddress.Name, message.IdentityKey)) {
                    throw new UntrustedIdentityException();
                }

                KeyExchangeMessage responseMessage = null;

                if (message.IsInitiate)   responseMessage = ProcessInitiate(message);
                else                      ProcessResponse(message);

                return responseMessage;
            }
        }