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