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