示例#1
0
        internal void PerformTcpHandshake()
        {
            if (Client.SymetricKey == Guid.Empty)
            {
                Client.SymetricKey = Guid.NewGuid();
            }

            using (var client = new TcpClient())
            {
                client.Connect(EndPoint);
                using (var stream = client.GetStream())
                {
                    var rdr = new BinaryReader(stream);
                    var wrt = new BinaryWriter(stream);
                    wrt.Write((byte)PeerCommand.Identify);

                    wrt.Write(Client.PublicKey.Length);
                    wrt.Write(Client.PublicKey);

                    var sigGuid = rdr.ReadBytes(16);
                    using (var rsa = OpenSslKey.DecodeRsaPrivateKey(Client.PrivateKey))
                    {
                        var sig = rsa.SignData(sigGuid, new SHA256CryptoServiceProvider());
                        wrt.Write(sig.Length);
                        wrt.Write(sig);
                    }

                    using (var rsa = OpenSslKey.DecodeX509PublicKey(PublicKey))
                    {
                        var encSym = rsa.Encrypt(Client.SymetricKey.ToByteArray(), false);
                        wrt.Write(encSym.Length);
                        wrt.Write(encSym);
                    }

                    wrt.Write(Client.DisplayName != null);
                    if (Client.DisplayName != null)
                    {
                        wrt.Write(Client.DisplayName);
                    }
                    wrt.Write(Client.ProfilePicture != null);
                    if (Client.ProfilePicture != null)
                    {
                        wrt.Write(Client.ProfilePicture.Length);
                        wrt.Write(Client.ProfilePicture);
                    }

                    DisplayName = rdr.ReadBoolean() ? rdr.ReadString() : null;
                    if (rdr.ReadBoolean())
                    {
                        rdr.ReadBytes(rdr.ReadInt32());
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Attempts to verify the public key on the other end of the stream.
        /// </summary>
        /// <param name="stream">The stream to handshake on.</param>
        /// <param name="publicKey">The public key claimed by the other side.</param>
        /// <returns>True if the identity was verified.</returns>
        public static bool VerifyIdentity(Stream stream, out byte[] publicKey)
        {
            var rdr = new BinaryReader(stream);

            var sigGuid = Guid.NewGuid();

            //Length is fixed - 16 bytes
            stream.Write(sigGuid.ToByteArray(), 0, 16);

            publicKey = rdr.ReadBytes(rdr.ReadInt32());
            var sig = rdr.ReadBytes(rdr.ReadInt32());

            using (var rsa = OpenSslKey.DecodeX509PublicKey(publicKey))
                return(rsa.VerifyData(sigGuid.ToByteArray(), new SHA256CryptoServiceProvider(), sig));
        }
示例#3
0
        /// <summary>
        /// Shakes hands with the client to prove that you own a private key for your claimed public key.
        /// </summary>
        /// <param name="stream">The stream to handshake on.</param>
        /// <param name="publicKey">The public key to transmit and verify.</param>
        /// <param name="privateKey">The private key to use for signing.</param>
        public static void ProveIdentity(Stream stream, byte[] publicKey, byte[] privateKey)
        {
            var rdr = new BinaryReader(stream);
            var wrt = new BinaryWriter(stream);

            wrt.Write(publicKey.Length);
            wrt.Write(publicKey);

            var sigGuid = rdr.ReadBytes(16);

            using (var rsa = OpenSslKey.DecodeRsaPrivateKey(privateKey))
            {
                var sig = rsa.SignData(sigGuid, new SHA256CryptoServiceProvider());
                wrt.Write(sig.Length);
                wrt.Write(sig);
            }
        }
示例#4
0
        private void TcpAcceptLoop(IAsyncResult result)
        {
            try
            {
                _tcpListener.BeginAcceptSocket(TcpAcceptLoop, null);
            }
            catch
            {
                //Called when disposed
                return;
            }

            using (var socket = _tcpListener.EndAcceptSocket(result))
                using (var stream = new NetworkStream(socket))
                {
                    if (!(socket.RemoteEndPoint is IPEndPoint))
                    {
                        return;
                    }

                    var rdr = new BinaryReader(stream);
                    var wrt = new BinaryWriter(stream);
                    switch ((PeerCommand)rdr.ReadByte())
                    {
                    case PeerCommand.Identify:
                    {
                        byte[] pub;
                        if (!GlobalHelpers.VerifyIdentity(stream, out pub))
                        {
                            return;
                        }

                        var symGuid = rdr.ReadBytes(rdr.ReadInt32());
                        using (var rsa = OpenSslKey.DecodeRsaPrivateKey(PrivateKey))
                            SymetricKey = new Guid(rsa.Decrypt(symGuid, false));

                        var peer = new PhonemePeer(this, pub, new IPEndPoint(((IPEndPoint)socket.RemoteEndPoint).Address, NetworkPort));
                        if (!_knownPeersSet.Contains(peer))
                        {
                            _knownPeersSet.Add(peer);
                            //TODO: Remove this dependency
                            Application.Current.Dispatcher.Invoke(() => KnownPeers.Add(peer));
                            PeerJoin?.Invoke(peer);
                        }
                        else
                        {
                            peer = _knownPeersSet.First(x => x.Equals(peer));
                        }

                        peer.DisplayName = rdr.ReadBoolean() ? rdr.ReadString() : null;
                        if (rdr.ReadBoolean())
                        {
                            rdr.ReadBytes(rdr.ReadInt32());
                        }

                        wrt.Write(DisplayName != null);
                        if (DisplayName != null)
                        {
                            wrt.Write(DisplayName);
                        }
                        wrt.Write(ProfilePicture != null);
                        if (ProfilePicture != null)
                        {
                            wrt.Write(ProfilePicture.Length);
                            wrt.Write(ProfilePicture);
                        }


                        break;
                    }

                    case PeerCommand.BinaryBlob:
                    {
                        byte[] pub;
                        if (!GlobalHelpers.VerifyIdentity(stream, out pub))
                        {
                            return;
                        }

                        var peer = new PhonemePeer(this, pub, new IPEndPoint(((IPEndPoint)socket.RemoteEndPoint).Address, NetworkPort));
                        if (!_knownPeersSet.Contains(peer))
                        {
                            return;
                        }
                        peer = _knownPeersSet.First(x => x.Equals(peer));

                        var blob = rdr.ReadBytes(rdr.ReadInt32());
                        GlobalHelpers.OneTimePad(blob, SymetricKey);

                        peer.OnMessageRecieved(blob);

                        break;
                    }

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
        }