Ejemplo n.º 1
0
        private Message Challenge(Session session, Message msg)
        {
            var protocol = session.Protocol;

            if (protocol.State != MessageProtocolState.WaitChallenge)
            {
                throw new DistortedHandshakeException();
            }

            var remoteChallenge = new byte[sizeof(ulong)].AsSpan();

            msg.Read(remoteChallenge);

            var expected = HandshakeHelpers.GetKey(this._localPublic, this._remotePublic).AsSpan();

            HandshakeHelpers.KeyTransformValue(expected, this._commonSecret, (byte)(this._localPublic & 7));
            protocol.Blowfish.Encrypt(expected);

            if (!remoteChallenge.SequenceEqual(expected))
            {
                throw new InvalidHandshakeException();
            }

            HandshakeHelpers.KeyTransformValue(this._key.AsSpan(), this._commonSecret, 3);
            protocol.Blowfish = new Blowfish(this._key.AsSpan());

            protocol.State = MessageProtocolState.Completed;
            return(new Message(MessageID.HANDSHAKE_ACCEPT));
        }
Ejemplo n.º 2
0
        public Task Handshake(Session session, Message msg)
        {
            var protocol = session.Protocol;

            if (protocol.State != MessageProtocolState.WaitChallenge)
            {
                throw new DistortedHandshakeException();
            }

            var remotePublic    = msg.Read <uint>();
            var remoteChallenge = new byte[sizeof(ulong)].AsSpan();

            msg.Read(remoteChallenge);

            var commonSecret = HandshakeHelpers.PowMod(remotePublic, this._localPrivate, this._prime);

            var key = HandshakeHelpers.GetKey(this._localPublic, remotePublic);

            HandshakeHelpers.KeyTransformValue(key.AsSpan(), commonSecret, (byte)(commonSecret & 3));
            protocol.Blowfish = new Blowfish(key.AsSpan());

            protocol.Blowfish.Decrypt(remoteChallenge);

            var expected = HandshakeHelpers.GetKey(remotePublic, this._localPublic).AsSpan();

            HandshakeHelpers.KeyTransformValue(expected, commonSecret, (byte)(remotePublic & 7));

            if (!remoteChallenge.SequenceEqual(expected))
            {
                throw new InvalidHandshakeException();
            }

            var challenge = HandshakeHelpers.GetKey(this._localPublic, remotePublic).AsSpan();

            HandshakeHelpers.KeyTransformValue(challenge, commonSecret, (byte)(this._localPublic & 7));
            protocol.Blowfish.Encrypt(challenge);

            HandshakeHelpers.KeyTransformValue(this._key.AsSpan(), commonSecret, 3);
            protocol.Blowfish = new Blowfish(this._key.AsSpan());

            var res = new Message(MessageID.HANDSHAKE, 9);

            res.Write(MessageProtocolOption.KeyChallenge);
            res.Write <byte>(challenge);
            protocol.State = MessageProtocolState.WaitAccept;

            return(session.SendAsync(res));
        }
Ejemplo n.º 3
0
        private Message Setup(Session session, Message msg)
        {
            var protocol = session.Protocol;

            if (protocol.State != MessageProtocolState.WaitSetup)
            {
                throw new DistortedHandshakeException();
            }

            msg.Read(this._key.AsSpan());
            var generator = msg.Read <uint>();
            var prime     = msg.Read <uint>();

            this._localPublic = msg.Read <uint>();

            var localPrivate = (uint)RandomNumberGenerator.GetInt32(1, int.MaxValue) & int.MaxValue;

            this._remotePublic = HandshakeHelpers.PowMod(generator, localPrivate, prime);
            this._commonSecret = HandshakeHelpers.PowMod(this._localPublic, localPrivate, prime);

            var key = HandshakeHelpers.GetKey(this._localPublic, this._remotePublic).AsSpan();

            HandshakeHelpers.KeyTransformValue(key, this._commonSecret, (byte)(this._commonSecret & 3));
            protocol.Blowfish = new Blowfish(key);

            var localChallenge = HandshakeHelpers.GetKey(this._remotePublic, this._localPublic).AsSpan();

            HandshakeHelpers.KeyTransformValue(localChallenge, this._commonSecret, (byte)(this._remotePublic & 7));
            protocol.Blowfish.Encrypt(localChallenge);

            var res = new Message(MessageID.HANDSHAKE, sizeof(uint) + sizeof(ulong));

            res.Write(this._remotePublic);
            res.Write <byte>(localChallenge);

            protocol.State = MessageProtocolState.WaitChallenge;
            return(res);
        }