Пример #1
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();
                }
            }
        }
Пример #2
0
        public static async Task <IEnumerable <Vector> > Generate()
        {
            var vectors = new List <Vector>();

            using (var stream = new MemoryStream())
            {
                foreach (var test in GetTests())
                {
                    var aliceConfig = new ProtocolConfig(
                        initiator: true,
                        prologue: PrologueRaw,
                        s: test.InitStaticRequired ? AliceStaticRaw : null,
                        rs: test.InitRemoteStaticRequired ? BobStaticPublicRaw : null,
                        psks: test.PsksRequired ? psksRaw : null
                        );

                    var bobConfig = new ProtocolConfig(
                        initiator: false,
                        prologue: PrologueRaw,
                        s: test.RespStaticRequired ? BobStaticRaw : null,
                        rs: test.RespRemoteStaticRequired ? AliceStaticPublicRaw : null,
                        psks: test.PsksRequired ? psksRaw : null
                        );

                    var alice = new NoiseSocket(test.Protocol, aliceConfig, stream, true);
                    var bob   = new NoiseSocket(test.Protocol, bobConfig, stream, true);

                    alice.SetInitializer(handshakeState => Utilities.SetDh(handshakeState, AliceEphemeralRaw.ToArray()));
                    bob.SetInitializer(handshakeState => Utilities.SetDh(handshakeState, BobEphemeralRaw.ToArray()));

                    var proxy = new SocketProxy(stream, (ushort)test.PaddedLength);
                    var queue = new Queue <byte[]>(payloads);

                    var writer = alice;
                    var reader = bob;

                    if (test.Response == Response.Accept)
                    {
                        await proxy.WriteHandshakeMessageAsync(alice, InitialNegotiationData, queue.Dequeue());

                        await bob.ReadNegotiationDataAsync();

                        bob.Accept(test.Protocol, bobConfig);

                        await bob.ReadHandshakeMessageAsync();

                        stream.Position = 0;

                        Utilities.Swap(ref writer, ref reader);
                    }
                    else if (test.Response == Response.Switch)
                    {
                        await proxy.WriteHandshakeMessageAsync(alice, InitialNegotiationData, queue.Dequeue());

                        await bob.ReadNegotiationDataAsync();

                        if (test.Fallback != null)
                        {
                            await bob.ReadHandshakeMessageAsync();

                            stream.Position = 0;

                            bob.Switch(test.Fallback, new ProtocolConfig(true, PrologueRaw, BobStaticRaw));

                            await proxy.WriteHandshakeMessageAsync(bob, SwitchNegotiationData, queue.Dequeue());

                            await alice.ReadNegotiationDataAsync();

                            alice.Switch(test.Fallback, new ProtocolConfig(false, PrologueRaw, AliceStaticRaw));

                            await alice.ReadHandshakeMessageAsync();

                            stream.Position = 0;
                        }
                        else
                        {
                            bob.Switch(test.Protocol, aliceConfig);
                            bob.SetInitializer(handshakeState => Utilities.SetDh(handshakeState, AliceEphemeralRaw.ToArray()));

                            await bob.IgnoreHandshakeMessageAsync();

                            stream.Position = 0;

                            await proxy.WriteHandshakeMessageAsync(bob, SwitchNegotiationData, queue.Dequeue());

                            await alice.ReadNegotiationDataAsync();

                            alice.Switch(test.Protocol, bobConfig);
                            alice.SetInitializer(handshakeState => Utilities.SetDh(handshakeState, BobEphemeralRaw.ToArray()));

                            await alice.ReadHandshakeMessageAsync();

                            stream.Position = 0;
                        }
                    }
                    else if (test.Response == Response.Retry)
                    {
                        await proxy.WriteHandshakeMessageAsync(alice, InitialNegotiationData, queue.Dequeue());

                        await bob.ReadNegotiationDataAsync();

                        bob.Retry(test.Protocol, bobConfig);

                        await bob.IgnoreHandshakeMessageAsync();

                        stream.Position = 0;

                        await proxy.WriteEmptyHandshakeMessageAsync(bob, RetryNegotiationData);

                        await alice.ReadNegotiationDataAsync();

                        alice.Retry(test.Protocol, aliceConfig);

                        await alice.IgnoreHandshakeMessageAsync();

                        stream.Position = 0;
                    }

                    while (queue.Count > 0)
                    {
                        if (writer.HandshakeHash.IsEmpty)
                        {
                            await proxy.WriteHandshakeMessageAsync(writer, null, queue.Dequeue());

                            await reader.ReadNegotiationDataAsync();

                            await reader.ReadHandshakeMessageAsync();

                            stream.Position = 0;
                        }
                        else
                        {
                            await proxy.WriteMessageAsync(writer, queue.Dequeue());
                        }

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

                    var initialConfig = new Config
                    {
                        ProtocolName      = Encoding.ASCII.GetString(test.Protocol.Name),
                        AliceStatic       = aliceConfig.LocalStatic,
                        AliceEphemeral    = AliceEphemeralRaw,
                        AliceRemoteStatic = aliceConfig.RemoteStatic,
                        BobStatic         = bobConfig.LocalStatic,
                        BobEphemeral      = BobEphemeralRaw,
                        BobRemoteStatic   = bobConfig.RemoteStatic
                    };

                    var switchConfig = new Config
                    {
                        ProtocolName      = Encoding.ASCII.GetString(test.Protocol.Name),
                        AliceStatic       = bobConfig.LocalStatic,
                        AliceEphemeral    = BobEphemeralRaw,
                        AliceRemoteStatic = bobConfig.RemoteStatic,
                        BobStatic         = aliceConfig.LocalStatic,
                        BobEphemeral      = AliceEphemeralRaw,
                        BobRemoteStatic   = aliceConfig.RemoteStatic
                    };

                    if (test.Fallback != null)
                    {
                        switchConfig = new Config
                        {
                            ProtocolName   = Encoding.ASCII.GetString(test.Fallback.Name),
                            AliceStatic    = AliceStaticRaw,
                            AliceEphemeral = AliceEphemeralRaw,
                            BobStatic      = BobStaticRaw,
                            BobEphemeral   = BobEphemeralRaw
                        };
                    }

                    var vector = new Vector
                    {
                        Initial       = initialConfig,
                        Switch        = test.Response == Response.Switch ? switchConfig : null,
                        Retry         = test.Response == Response.Retry ? initialConfig : null,
                        AlicePrologue = PrologueHex,
                        AlicePsks     = test.PsksRequired ? psksHex : null,
                        BobPrologue   = PrologueHex,
                        BobPsks       = test.PsksRequired ? psksHex : null,
                        HandshakeHash = Hex.Encode(writer.HandshakeHash.ToArray()),
                        Messages      = proxy.Messages
                    };

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

                    vectors.Add(vector);
                }
            }

            return(vectors);
        }