public void TestCloseConnection()
        {
            SecureTunnel t = new SecureTunnel(tunnelSocket);

            byte[] privateKey, publicKey;
            privateKey = new byte[0];
            publicKey  = new byte[0];
            this.SetupTunnelComms(t, out privateKey, out publicKey);

            tunnelSocket.InterceptOutgoingPacket(p =>
            {
                //we should recieve a close connection packet
                EncryptedPacket packet = (EncryptedPacket)p;
                packet.DecryptPacket(privateKey, publicKey);
                var x = packet.RPCs.First;
                Assert.IsTrue(x.SerializationTag == (byte)RPCType.ClosePipe);
            });

            DuplexPipe connection = new DuplexPipe(t, 100);

            Assert.IsTrue(t.OpenPipe(connection));
            Assert.IsTrue(t.PipeIDs.Contains((uint)100));

            Assert.IsTrue(t.ClosePipe((uint)100));
            Assert.IsFalse(t.PipeIDs.Contains((uint)100));
        }
        public void TestSendEncryptedPacket()
        {
            SecureTunnel t         = new SecureTunnel(this.tunnelSocket);
            bool         triggered = false;

            byte[] server_epk = new byte[0];
            this.tunnelSocket.InterceptOutgoingPacket(p =>
            {
                Assert.IsNotNull(p.EuphemeralPublicKey);
                Assert.IsTrue(p.EuphemeralPublicKey.Length == 32);
                Assert.IsTrue(p.HasEPK);
                triggered  = true;
                server_epk = p.EuphemeralPublicKey;
            });
            String messageText = "The quick brown fox jumps over the lazy dog";
            //create an encryption key
            KeyPair         keyPair = Sodium.PublicKeyBox.GenerateKeyPair();
            EncryptedPacket hello   = new EncryptedPacket(1000, 0);

            hello.EuphemeralPublicKey = keyPair.PublicKey;
            t.HandleHelloPacket(hello);
            Assert.IsTrue(triggered);
            //these are just to ensure that the keys have been exchanged correctly.
            //We may want the response to a hello to be an encrypted rpc just for added protection -- there is no
            //need for the EPK to be transferred in the clear at this point.
            Assert.That(keyPair.PublicKey.SequenceEqual(t.recipentEPK));
            Assert.That(!keyPair.PublicKey.SequenceEqual(server_epk));
            Assert.That(t.mKeyPair.PublicKey.SequenceEqual(server_epk));
            triggered = false;

            this.tunnelSocket.InterceptOutgoingPacket(p =>
            {
                EncryptedPacket packet = (EncryptedPacket)p;
                Assert.IsNotNull(packet.ToBytes());
                if (packet.DecryptPacket(keyPair.PrivateKey, server_epk))
                {
                    String msg = System.Text.ASCIIEncoding.ASCII.GetString(packet.Payload);
                    System.Console.WriteLine(msg);
                    //Assert.IsTrue(msg.Equals (messageText));
                    triggered = true;
                }
                else
                {
                    Assert.Fail("Decryption failed");
                }
            });

            EncryptedPacket sentPacket = new EncryptedPacket(1000, 0);

            sentPacket.SetPayload(messageText);
            t.EncryptAndSendPacket(sentPacket);
            Assert.IsTrue(triggered);
        }
示例#3
0
        public override void HandleIncomingPacket(EncryptedPacket p)
        {
            //decrypt the GenericPacket
            //Sodium.PublicKeyBox.Open (p.CipherText, p.Nonce, this.mKeyPair.PrivateKey, this.p)

            switch (State)
            {
            case TunnelState.WaitingForHelloResponse:
                //this should be the hello response
                Debug.Assert(p.HasEPK, "The first GenericPacket back from a hello response has to have a public key attached to it");
                this.recipentEPK = p.EuphemeralPublicKey;
                this.State       = TunnelState.Connected;
                //there could be a payload attached to this GenericPacket
                this.HandleIncomingPacket(p);

                while (this.bufferedEncryptedPackets.Count > 0)
                {
                    this.EncryptAndSendPacket(this.bufferedEncryptedPackets.Dequeue());
                }
                break;

            case TunnelState.Connected:
                Debug.Assert(recipentEPK != null);
                if (p.CipherText.Length > 0)
                {
                    if (p.DecryptPacket(mKeyPair.PrivateKey, recipentEPK))
                    {
                        if (congestionController.CheckResendAck(p))
                        {
                            Console.WriteLine("Resending ack");
                            this.SendAck(p.Ack);
                        }
                        if (congestionController.CheckPacket(p))
                        {
                            PipeBase connection;
                            UInt32   cid = p.CID;
                            if (p.Ack > 0)
                            {
                                this.SendAck(p.Ack);
                            }
                            //only handle packets that have a payload or RPCs
                            if (p.Payload.Length > 0 || p.RPCs.Count > 0)
                            {
                                if (cid == 0)
                                {
                                    ControlPipe.HandlePacket(p);
                                }
                                else
                                {
                                    if (ActivePipes.Find(ref cid, out connection))
                                    {
                                        connection.HandlePacket(p);
                                    }
                                }
                            }
                        }
                    }
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }