private static async Task Client() { // Connect to the server using the named pipe. using (var client = new NamedPipeClientStream(ServerName, PipeName, PipeDirection.InOut)) { await client.ConnectAsync(); // Select the initial Noise protocol and configuration. var initial = Protocol.Parse("Noise_NN_25519_ChaChaPoly_SHA256".AsSpan()); var config = new ProtocolConfig(initiator: true); using (var noise = new NoiseSocket(initial, config, client)) { // Send the initial handshake message to the server. 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.WriteHandshakeMessageAsync(negotiationData : null); // Receive the negotiation data from the server. In this example we will // assume that the server decided to retry with Noise_XX_25519_AESGCM_BLAKE2b. await noise.ReadNegotiationDataAsync(); // New protocol requires static key, so it's generated here. using (var keyPair = KeyPair.Generate()) { // The client again plays the role of the initiator. config = new ProtocolConfig(initiator: true, s: keyPair.PrivateKey); // Retry with a protocol different from the initial one. noise.Retry(protocol, config); // Ignore the empty handshake message. await noise.IgnoreHandshakeMessageAsync(); // Finish the handshake using the new protocol. await noise.WriteHandshakeMessageAsync(); await noise.ReadNegotiationDataAsync(); await noise.ReadHandshakeMessageAsync(); await noise.WriteHandshakeMessageAsync(); // Send the transport message to the server. var request = Encoding.UTF8.GetBytes("I'm cooking MC's like a pound of bacon"); await noise.WriteMessageAsync(request); // Receive the transport message from the // server and print it to the standard output. var response = await noise.ReadMessageAsync(); Console.WriteLine(Encoding.UTF8.GetString(response)); } } } }
private static async Task Server() { // Listen for incoming TCP connections. using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { socket.Bind(new IPEndPoint(IPAddress.Loopback, Port)); socket.Listen((int)SocketOptionName.MaxConnections); // Generate the static key pair. using (var keyPair = KeyPair.Generate()) { var config = new ProtocolConfig(initiator: false, s: keyPair.PrivateKey); // Accept the connection and initialize the NoiseSocket with its network stream. using (var client = await socket.AcceptAsync()) using (var stream = new NetworkStream(client)) using (var noise = new NoiseSocket(initial, config, 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(); try { await noise.ReadHandshakeMessageAsync(); } catch (CryptographicException) { // The decryption of the initial handshake message failed // because the client had an outdated remote static public key. } // The server decides to switch to a fallback protocol. config = new ProtocolConfig(initiator: true, s: keyPair.PrivateKey); noise.Switch(fallback, config); // Send the first handshake message using the new protocol. In the // real world the negotiation data would encode the details about // the server's desicion to switch protocol. await noise.WriteHandshakeMessageAsync(negotiationData : null, paddedLength : PaddedLength); // Finish the handshake using the new protocol. 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); } } } }
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(); } }
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); } } } }
private static async Task Client() { // Connect to the server using the TCP socket. using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { await socket.ConnectAsync(IPAddress.Loopback, Port); // Generate the static key pair. using (var keyPair = KeyPair.Generate()) { // In this example the client has an outdated remote static public key. The server will // fail to decrypt the initial handshake message, which will trigger a fallback. var config = new ProtocolConfig(initiator: true, s: keyPair.PrivateKey, rs: new byte[32]); // Initialize the NoiseSocket with the network stream. using (var stream = new NetworkStream(socket)) using (var noise = new NoiseSocket(initial, config, stream)) { // Send the initial handshake message to the server. 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.WriteHandshakeMessageAsync(negotiationData : null, paddedLength : PaddedLength); // Receive the negotiation data from the server. In this example we will // assume that the server decided to switch to Noise_XX_25519_AESGCM_BLAKE2b. await noise.ReadNegotiationDataAsync(); // The client now plays the role of the responder. config = new ProtocolConfig(initiator: false, s: keyPair.PrivateKey); // Switch to a protocol different from the initial one. noise.Switch(fallback, config); // Finish the handshake using the new protocol. await noise.ReadHandshakeMessageAsync(); await noise.WriteHandshakeMessageAsync(paddedLength : PaddedLength); // Send the padded transport message to the server. var request = Encoding.UTF8.GetBytes("I'm cooking MC's like a pound of bacon"); await noise.WriteMessageAsync(request, PaddedLength); // Receive the transport message from the // server and print it to the standard output. var response = await noise.ReadMessageAsync(); Console.WriteLine(Encoding.UTF8.GetString(response)); } } } }
public async Task WriteMessageAsync(NoiseSocket socket, byte[] messageBody) { await socket.WriteMessageAsync(messageBody, paddedLength); var message = new Message { MessageBody = messageBody, PaddedLength = paddedLength, Value = Utilities.ReadMessage(stream) }; stream.Position = 0; Messages.Add(message); }
private static async Task Client() { // Open the TCP connection to the server. using (var client = new TcpClient()) { await client.ConnectAsync(IPAddress.Loopback, Port); // Generate the static key pair. using (var keyPair = KeyPair.Generate()) { var config = new ProtocolConfig(initiator: true, s: keyPair.PrivateKey); // Initialize the NoiseSocket with the network stream. using (var stream = client.GetStream()) using (var noise = new NoiseSocket(protocol, config, stream)) { // Send the initial handshake message to the server. 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.WriteHandshakeMessageAsync(negotiationData : null, paddedLength : PaddedLength); // Receive the negotiation data from the server. In this example we will // assume that the server decided to accept the offered protocol. await noise.ReadNegotiationDataAsync(); // Finish the handshake. await noise.ReadHandshakeMessageAsync(); await noise.WriteHandshakeMessageAsync(paddedLength : PaddedLength); // Send the padded transport message to the server. var request = Encoding.UTF8.GetBytes("I'm cooking MC's like a pound of bacon"); await noise.WriteMessageAsync(request, PaddedLength); // Receive the transport message from the // server and print it to the standard output. var response = await noise.ReadMessageAsync(); Console.WriteLine(Encoding.UTF8.GetString(response)); } } } }
private static async Task Run() { using (var client = new TcpClient()) { await client.ConnectAsync(IPAddress.Loopback, Port); using (var keyPair = KeyPair.Generate()) { var config = new ProtocolConfig(initiator: true, s: keyPair.PrivateKey); using (var stream = client.GetStream()) using (var noise = new NoiseSocket(protocol, config, stream)) { await noise.WriteHandshakeMessageAsync(negotiationData : clientNegotiationData, paddedLength : PaddedLength); var serverNegotiationData = await noise.ReadNegotiationDataAsync(); if (serverNegotiationData.Length > 0) { throw new Exception("Unsupported Noise protocol."); } await noise.ReadHandshakeMessageAsync(); await noise.WriteHandshakeMessageAsync(paddedLength : PaddedLength); var request = Encoding.UTF8.GetBytes("I'm cooking MC's like a pound of bacon"); await noise.WriteMessageAsync(request, PaddedLength); var response = await noise.ReadMessageAsync(); Console.WriteLine(Encoding.UTF8.GetString(response)); } } } }