private static async Task Server() { // Listen for connections from TCP network clients. var listener = new TcpListener(IPAddress.Loopback, Port); listener.Start(); try { // Accept the connection from the TCP client. using (var client = await listener.AcceptTcpClientAsync()) { // Generate the static key pair. using (var keyPair = KeyPair.Generate()) { var config = new ProtocolConfig(initiator: false, s: keyPair.PrivateKey); // Initialize the NoiseSocket with the network stream. using (var stream = client.GetStream()) using (var noise = new NoiseSocket(stream)) { // 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(); // Accept the offered protocol. noise.Accept(protocol, config); // Finish the handshake. await noise.ReadHandshakeMessageAsync(); await noise.WriteHandshakeMessageAsync(paddedLength : PaddedLength); 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, PaddedLength); } } } } finally { listener.Stop(); } }
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(); } } }
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); }