Ejemplo n.º 1
0
        private KeyExchangeMessage ProcessInitiate(KeyExchangeMessage message)
        {
            uint          flags         = KeyExchangeMessage.RESPONSE_FLAG;
            SessionRecord sessionRecord = sessionStore.LoadSession(remoteAddress);

            if (message.GetVersion() >= 3 &&
                !Curve.VerifySignature(message.GetIdentityKey().GetPublicKey(),
                                       message.GetBaseKey().Serialize(),
                                       message.GetBaseKeySignature()))
            {
                throw new InvalidKeyException("Bad signature!");
            }

            SymmetricAxolotlParameters.Builder builder = SymmetricAxolotlParameters.NewBuilder();

            if (!sessionRecord.GetSessionState().HasPendingKeyExchange())
            {
                builder.SetOurIdentityKey(identityKeyStore.GetIdentityKeyPair())
                .SetOurBaseKey(Curve.GenerateKeyPair())
                .SetOurRatchetKey(Curve.GenerateKeyPair());
            }
            else
            {
                builder.SetOurIdentityKey(sessionRecord.GetSessionState().GetPendingKeyExchangeIdentityKey())
                .SetOurBaseKey(sessionRecord.GetSessionState().GetPendingKeyExchangeBaseKey())
                .SetOurRatchetKey(sessionRecord.GetSessionState().GetPendingKeyExchangeRatchetKey());
                flags |= KeyExchangeMessage.SIMULTAENOUS_INITIATE_FLAG;
            }

            builder.SetTheirBaseKey(message.GetBaseKey())
            .SetTheirRatchetKey(message.GetRatchetKey())
            .SetTheirIdentityKey(message.GetIdentityKey());

            SymmetricAxolotlParameters parameters = builder.Create();

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

            RatchetingSession.InitializeSession(sessionRecord.GetSessionState(),
                                                Math.Min(message.GetMaxVersion(), CipherTextMessage.CURRENT_VERSION),
                                                parameters);

            sessionStore.StoreSession(remoteAddress, sessionRecord);
            identityKeyStore.SaveIdentity(remoteAddress.GetName(), message.GetIdentityKey());

            byte[] baseKeySignature = Curve.CalculateSignature(parameters.GetOurIdentityKey().GetPrivateKey(),
                                                               parameters.GetOurBaseKey().GetPublicKey().Serialize());

            return(new KeyExchangeMessage(sessionRecord.GetSessionState().GetSessionVersion(),
                                          message.GetSequence(), flags,
                                          parameters.GetOurBaseKey().GetPublicKey(),
                                          baseKeySignature, parameters.GetOurRatchetKey().GetPublicKey(),
                                          parameters.GetOurIdentityKey().GetPublicKey()));
        }
Ejemplo n.º 2
0
        private void ProcessResponse(KeyExchangeMessage message)
        {
            SessionRecord sessionRecord                  = sessionStore.LoadSession(remoteAddress);
            SessionState  sessionState                   = sessionRecord.GetSessionState();
            bool          hasPendingKeyExchange          = sessionState.HasPendingKeyExchange();
            bool          isSimultaneousInitiateResponse = message.IsResponseForSimultaneousInitiate();

            if (!hasPendingKeyExchange || sessionState.GetPendingKeyExchangeSequence() != message.GetSequence())
            {
                //Log.w(TAG, "No matching sequence for response. Is simultaneous initiate response: " + isSimultaneousInitiateResponse);
                if (!isSimultaneousInitiateResponse)
                {
                    throw new StaleKeyExchangeException();
                }
                else
                {
                    return;
                }
            }

            SymmetricAxolotlParameters.Builder parameters = SymmetricAxolotlParameters.NewBuilder();

            parameters.SetOurBaseKey(sessionRecord.GetSessionState().GetPendingKeyExchangeBaseKey())
            .SetOurRatchetKey(sessionRecord.GetSessionState().GetPendingKeyExchangeRatchetKey())
            .SetOurIdentityKey(sessionRecord.GetSessionState().GetPendingKeyExchangeIdentityKey())
            .SetTheirBaseKey(message.GetBaseKey())
            .SetTheirRatchetKey(message.GetRatchetKey())
            .SetTheirIdentityKey(message.GetIdentityKey());

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

            RatchetingSession.InitializeSession(sessionRecord.GetSessionState(),
                                                Math.Min(message.GetMaxVersion(), CipherTextMessage.CURRENT_VERSION),
                                                parameters.Create());

            if (sessionRecord.GetSessionState().GetSessionVersion() >= 3 &&
                !Curve.VerifySignature(message.GetIdentityKey().GetPublicKey(),
                                       message.GetBaseKey().Serialize(),
                                       message.GetBaseKeySignature()))
            {
                throw new InvalidKeyException("Base key signature doesn't match!");
            }

            sessionStore.StoreSession(remoteAddress, sessionRecord);
            identityKeyStore.SaveIdentity(remoteAddress.GetName(), message.GetIdentityKey());
        }