internal HttpListenerWebSocketContext( HttpListenerContext context, Logger logger) { _context = context; _stream = WsStream.CreateServerStream(context); _websocket = new WebSocket(this, logger ?? new Logger()); }
internal HttpListenerWebSocketContext( HttpListenerContext context, Logger logger) { _context = context; _stream = WsStream.CreateServerStream (context); _websocket = new WebSocket (this, logger ?? new Logger ()); }
internal TcpListenerWebSocketContext(TcpClient client, bool secure) { _client = client; _isSecure = secure; _stream = WsStream.CreateServerStream(client, secure); _request = RequestHandshake.Parse(_stream.ReadHandshake()); _socket = new WebSocket(this); }
internal TcpListenerWebSocketContext(TcpClient client, bool secure, X509Certificate cert) { _client = client; _secure = secure; _stream = WsStream.CreateServerStream (client, secure, cert); _request = HandshakeRequest.Parse (_stream.ReadHandshake ()); _websocket = new WebSocket (this); }
internal TcpListenerWebSocketContext(TcpClient client, bool secure, X509Certificate cert) { _client = client; _secure = secure; _stream = WsStream.CreateServerStream(client, secure, cert); _request = HandshakeRequest.Parse(_stream.ReadHandshake()); _websocket = new WebSocket(this); }
internal TcpListenerWebSocketContext(TcpClient client, X509Certificate cert, bool secure, Logger logger) { this._client = client; this._secure = secure; this._stream = WsStream.CreateServerStream(client, cert, secure); this._request = this._stream.ReadHandshake <HandshakeRequest>(new Func <string[], HandshakeRequest>(HandshakeRequest.Parse), 90000); this._websocket = new WebSocket(this, logger); }
internal TcpListenerWebSocketContext( TcpClient client, X509Certificate cert, bool secure, Logger logger) { _client = client; _secure = secure; _stream = WsStream.CreateServerStream (client, cert, secure); _request = _stream.ReadHandshake<HandshakeRequest> ( HandshakeRequest.Parse, 90000); _websocket = new WebSocket (this, logger); }
/// <summary> /// Establishes encryption in the current socket. It is required that both the client and server call this! /// </summary> /// <remarks> /// It is highly recommended to validate the returned fingerprint with a trusted store. /// </remarks> /// <param name="stream"></param> /// <param name="parameters">ECDSA public / private keypair used for signing</param> /// <returns>The fingerprint (public key) of the remote</returns> public static async Task <ECPoint> EncryptAsync(this WsStream stream, ECParameters parameters) { var(secret, fingerprint) = await ExchangeKeyAsync(stream, parameters); // wrap stream await stream.WrapSocketAsync(x => Task.FromResult <WStreamSocket>(new WStreamCryptoSocket(x, secret))); return(fingerprint); }
public IntegrityTestFixture() { // create the server var server = new WsServer(); server.StartAsync(new IPEndPoint(IPAddress.Loopback, 0), async stream => { Server = stream; }).GetAwaiter().GetResult(); // start client var client = new WsClient(); Client = client.ConnectAsync(new Uri("ws://" + server.ListeningAddresses[0].Substring(7))).GetAwaiter().GetResult(); Thread.Sleep(1000); Reader = new AsyncBinaryReader(Client); Writer = new AsyncBinaryWriter(Server); }
internal HttpListenerWebSocketContext(HttpListenerContext context) { _context = context; _stream = WsStream.CreateServerStream(context); _socket = new WebSocket(this); }
/// <summary> /// Establishes encryption in the current socket. It is required that both the client and server call this! /// <remarks> /// This method overload will create a random ECDSA signing key every time it is called. It is highly recommended to use fixed keys and validate the returned fingerprint with a trusted store. /// </remarks> /// </summary> /// <param name="stream"></param> /// <returns></returns> public static Task <ECPoint> EncryptAsync(this WsStream stream) { return(EncryptAsync(stream, ECDsa.Create(ECCurve.CreateFromFriendlyName("secp384r1")).ExportParameters(true))); }
/// <summary> /// Securely exchanges a secret key /// </summary> /// <param name="stream"></param> /// <param name="ecParams">ECDSA public / private keypair used for signing</param> /// <returns>A tuple containing a 256 bit hashed secret key, and the fingerprint of the remote</returns> /// <exception cref="CryptographicException"></exception> /// <exception cref="InvalidDataException">Thrown when the remote sends invalid data</exception> public static async Task <(byte[], ECPoint)> ExchangeKeyAsync(this WsStream stream, ECParameters ecParams) { if (ecParams.D is null) { throw new CryptographicException("Private key must be provided"); } ECDsa ecDsa = ECDsa.Create(ecParams); // TODO: Harden security (prevent abuse, double check everything) // host authentication var pubBytes = ecDsa.ExportSubjectPublicKeyInfo(); // key exchange var ecdh = ECDiffieHellman.Create(); var kePubBytes = ecdh.ExportSubjectPublicKeyInfo(); // sign ecdh key to authenticate var signed = ecDsa.SignData(kePubBytes, HashAlgorithmName.SHA256); var bw = new AsyncBinaryWriter(stream); var br = new AsyncBinaryReader(stream); //1 await bw.WriteAsync(pubBytes.Length); await bw.WriteAsync(pubBytes); //2 await bw.WriteAsync(signed.Length); await bw.WriteAsync(signed); //3 await bw.WriteAsync(kePubBytes.Length); await bw.WriteAsync(kePubBytes); // read remote public key and verify signature //1 var remotePubKey = ECDsa.Create(); var remotePubBytes = await br.ReadBytesAsync(await br.ReadAssertAsync(120)); remotePubKey.ImportSubjectPublicKeyInfo(remotePubBytes, out _); //2 var remoteSignature = await br.ReadBytesAsync(await br.ReadAssertAsync(96)); //3 var remoteKePub = await br.ReadBytesAsync(await br.ReadAssertAsync(158)); var remoteEcdh = ECDiffieHellman.Create(); remoteEcdh.ImportSubjectPublicKeyInfo(remoteKePub, out _); // verify signed public key exchange key if (!remotePubKey.VerifyData(remoteKePub, remoteSignature, HashAlgorithmName.SHA256)) { throw new CryptographicException("Remote public key does not match hash!"); } // derive shared secret var sharedSecret = ecdh.DeriveKeyMaterial(remoteEcdh.PublicKey); // return the public key (fingerprint) of the remote, and the hashed shared secret return(SHA256.HashData(sharedSecret), remotePubKey.ExportParameters(false).Q); }