Example #1
0
        private static async Task Server()
        {
            // Create the named pipe and wait for the client to connect to it.
            using (var server = new NamedPipeServerStream(PipeName, PipeDirection.InOut))
            {
                await server.WaitForConnectionAsync();

                // Initialize the NoiseSocket.
                using (var noise = new NoiseSocket(server))
                {
                    // Receive the negotiation data from the client. In the real world the
                    // negotiation data would contain the initial protocol, supported protocols
                    // for the switch and retry cases, and maybe some other negotiation options.
                    await noise.ReadNegotiationDataAsync();

                    // Read the handshake message from the client, but without decrypting it.
                    await noise.IgnoreHandshakeMessageAsync();

                    // New protocol requires static key, so we generate it here.
                    using (var keyPair = KeyPair.Generate())
                    {
                        // The server decides to retry with a new protocol.
                        // It again plays the role of the responder.
                        var config = new ProtocolConfig(initiator: false, s: keyPair.PrivateKey);
                        noise.Retry(protocol, config);

                        // Request a retry from the client. In the real world the negotiation data
                        // would encode the details about the server's desicion to make a retry request.
                        await noise.WriteEmptyHandshakeMessageAsync(negotiationData : null);

                        // Receive the negotiation data from the client. The client will
                        // usually just confirm the server's choice of the retry protocol.
                        await noise.ReadNegotiationDataAsync();

                        // Finish the handshake using the new protocol.
                        await noise.ReadHandshakeMessageAsync();

                        await noise.WriteHandshakeMessageAsync();

                        await noise.ReadNegotiationDataAsync();

                        await noise.ReadHandshakeMessageAsync();

                        // Receive the transport message from the client.
                        var request = await noise.ReadMessageAsync();

                        // Echo the message back to the client.
                        await noise.WriteMessageAsync(request);
                    }
                }
            }
        }
Example #2
0
        public async Task WriteEmptyHandshakeMessageAsync(NoiseSocket socket, byte[] negotiationData)
        {
            await socket.WriteEmptyHandshakeMessageAsync(negotiationData);

            var message = new Message
            {
                NegotiationData = negotiationData,
                Value           = Utilities.ReadMessage(stream)
            };

            stream.Position = 0;
            Messages.Add(message);
        }
Example #3
0
        public async Task TestVectors()
        {
            var s    = File.ReadAllText("Vectors/noisesocket.json");
            var json = JObject.Parse(s);

            using (var stream = new MemoryStream())
            {
                foreach (var vector in json["vectors"])
                {
                    var initialConfig = vector["initial"];
                    var switchConfig  = vector["switch"];
                    var retryConfig   = vector["retry"];

                    var alicePrologue = GetBytes(vector, "alice_prologue");
                    var alicePsks     = GetPsks(vector, "alice_psks");
                    var bobPrologue   = GetBytes(vector, "bob_prologue");
                    var bobPsks       = GetPsks(vector, "bob_psks");
                    var handshakeHash = GetBytes(vector, "handshake_hash");

                    var config      = vector["initial"].ToObject <Config>();
                    var aliceConfig = new ProtocolConfig(true, alicePrologue, config.AliceStatic, config.AliceRemoteStatic, alicePsks);
                    var bobConfig   = new ProtocolConfig(false, bobPrologue, config.BobStatic, config.BobRemoteStatic, bobPsks);

                    var protocol = Protocol.Parse(config.ProtocolName.AsSpan());
                    var queue    = ReadMessages(vector["messages"]);

                    var alice = new NoiseSocket(protocol, aliceConfig, stream, true);
                    var bob   = new NoiseSocket(protocol, bobConfig, stream, true);

                    var aliceEphemeral = config.AliceEphemeral;
                    var bobEphemeral   = config.BobEphemeral;

                    alice.SetInitializer(handshakeState => Utilities.SetDh(handshakeState, aliceEphemeral));
                    bob.SetInitializer(handshakeState => Utilities.SetDh(handshakeState, bobEphemeral));

                    var writer = alice;
                    var reader = bob;

                    if (switchConfig == null && retryConfig == null)
                    {
                        var message = queue.Dequeue();
                        stream.Position = 0;

                        await alice.WriteHandshakeMessageAsync(message.NegotiationData, message.MessageBody, message.PaddedLength);

                        Assert.Equal(message.Value, Utilities.ReadMessage(stream));

                        stream.Position = 0;
                        Assert.Equal(message.NegotiationData, await bob.ReadNegotiationDataAsync());

                        bob.Accept(protocol, bobConfig);
                        Assert.Equal(message.MessageBody, await bob.ReadHandshakeMessageAsync());

                        Utilities.Swap(ref writer, ref reader);
                    }
                    else if (switchConfig != null)
                    {
                        config   = switchConfig.ToObject <Config>();
                        protocol = Protocol.Parse(config.ProtocolName.AsSpan());

                        aliceConfig = new ProtocolConfig(false, alicePrologue, config.AliceStatic, config.AliceRemoteStatic, alicePsks);
                        bobConfig   = new ProtocolConfig(true, bobPrologue, config.BobStatic, config.BobRemoteStatic, bobPsks);

                        var message = queue.Dequeue();
                        stream.Position = 0;

                        await alice.WriteHandshakeMessageAsync(message.NegotiationData, message.MessageBody, message.PaddedLength);

                        Assert.Equal(message.Value, Utilities.ReadMessage(stream));

                        stream.Position = 0;
                        Assert.Equal(message.NegotiationData, await bob.ReadNegotiationDataAsync());

                        if ((protocol.Modifiers & PatternModifiers.Fallback) != 0)
                        {
                            await bob.ReadHandshakeMessageAsync();

                            bob.Switch(protocol, bobConfig);

                            message         = queue.Dequeue();
                            stream.Position = 0;

                            await bob.WriteHandshakeMessageAsync(message.NegotiationData, message.MessageBody, message.PaddedLength);

                            Assert.Equal(message.Value, Utilities.ReadMessage(stream));

                            stream.Position = 0;
                            Assert.Equal(message.NegotiationData, await alice.ReadNegotiationDataAsync());

                            alice.Switch(protocol, aliceConfig);
                            Assert.Equal(message.MessageBody, await alice.ReadHandshakeMessageAsync());
                        }
                        else
                        {
                            bob.Switch(protocol, bobConfig);
                            bob.SetInitializer(handshakeState => Utilities.SetDh(handshakeState, config.BobEphemeral));
                            await bob.IgnoreHandshakeMessageAsync();

                            message         = queue.Dequeue();
                            stream.Position = 0;

                            await bob.WriteHandshakeMessageAsync(message.NegotiationData, message.MessageBody, message.PaddedLength);

                            Assert.Equal(message.Value, Utilities.ReadMessage(stream));

                            stream.Position = 0;
                            Assert.Equal(message.NegotiationData, await alice.ReadNegotiationDataAsync());

                            alice.Switch(protocol, aliceConfig);
                            alice.SetInitializer(handshakeState => Utilities.SetDh(handshakeState, config.AliceEphemeral));
                            Assert.Equal(message.MessageBody, await alice.ReadHandshakeMessageAsync());
                        }
                    }
                    else if (retryConfig != null)
                    {
                        config   = retryConfig.ToObject <Config>();
                        protocol = Protocol.Parse(config.ProtocolName.AsSpan());

                        aliceConfig = new ProtocolConfig(true, alicePrologue, config.AliceStatic, config.AliceRemoteStatic, alicePsks);
                        bobConfig   = new ProtocolConfig(false, bobPrologue, config.BobStatic, config.BobRemoteStatic, bobPsks);

                        var message = queue.Dequeue();
                        stream.Position = 0;

                        await alice.WriteHandshakeMessageAsync(message.NegotiationData, message.MessageBody, message.PaddedLength);

                        Assert.Equal(message.Value, Utilities.ReadMessage(stream));

                        stream.Position = 0;
                        Assert.Equal(message.NegotiationData, await bob.ReadNegotiationDataAsync());

                        bob.Retry(protocol, bobConfig);
                        bob.SetInitializer(handshakeState => Utilities.SetDh(handshakeState, config.BobEphemeral));
                        await bob.IgnoreHandshakeMessageAsync();

                        message         = queue.Dequeue();
                        stream.Position = 0;

                        await bob.WriteEmptyHandshakeMessageAsync(message.NegotiationData);

                        Assert.Equal(message.Value, Utilities.ReadMessage(stream));

                        stream.Position = 0;
                        Assert.Equal(message.NegotiationData, await alice.ReadNegotiationDataAsync());

                        alice.Retry(protocol, aliceConfig);
                        alice.SetInitializer(handshakeState => Utilities.SetDh(handshakeState, config.AliceEphemeral));
                        await alice.IgnoreHandshakeMessageAsync();
                    }

                    while (queue.Count > 0)
                    {
                        var message = queue.Dequeue();

                        if (writer.HandshakeHash.IsEmpty)
                        {
                            stream.Position = 0;
                            await writer.WriteHandshakeMessageAsync(message.NegotiationData, message.MessageBody, message.PaddedLength);

                            Assert.Equal(message.Value, Utilities.ReadMessage(stream));

                            stream.Position = 0;
                            Assert.Empty(await reader.ReadNegotiationDataAsync());
                            Assert.Equal(message.MessageBody, await reader.ReadHandshakeMessageAsync());
                        }
                        else
                        {
                            stream.Position = 0;
                            await writer.WriteMessageAsync(message.MessageBody, message.PaddedLength);

                            Assert.Equal(message.Value, Utilities.ReadMessage(stream));

                            stream.Position = 0;
                            Assert.Equal(message.MessageBody, await reader.ReadMessageAsync());
                        }

                        Utilities.Swap(ref writer, ref reader);
                    }

                    Assert.Equal(handshakeHash, writer.HandshakeHash.ToArray());
                    Assert.Equal(handshakeHash, reader.HandshakeHash.ToArray());

                    alice.Dispose();
                    bob.Dispose();
                }
            }
        }