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)); }
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)); }
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); }