private static void DoTestClientServer(bool fragment)
        {
            SecureRandom secureRandom = new SecureRandom();

            TlsClientProtocol clientProtocol = new TlsClientProtocol(secureRandom);
            TlsServerProtocol serverProtocol = new TlsServerProtocol(secureRandom);

            clientProtocol.Connect(new MockTlsClient(null));
            serverProtocol.Accept(new MockTlsServer());

            // pump handshake
            bool hadDataFromServer = true;
            bool hadDataFromClient = true;

            while (hadDataFromServer || hadDataFromClient)
            {
                hadDataFromServer = PumpData(serverProtocol, clientProtocol, fragment);
                hadDataFromClient = PumpData(clientProtocol, serverProtocol, fragment);
            }

            // send data in both directions
            byte[] data = new byte[1024];
            secureRandom.NextBytes(data);
            WriteAndRead(clientProtocol, serverProtocol, data, fragment);
            WriteAndRead(serverProtocol, clientProtocol, data, fragment);

            // close the connection
            clientProtocol.Close();
            PumpData(clientProtocol, serverProtocol, fragment);
            serverProtocol.CloseInput();
            CheckClosed(serverProtocol);
            CheckClosed(clientProtocol);
        }
예제 #2
0
        protected void Disposing(bool dispose)
        {
            if (dispose & !disposed)
            {
                disposed = true;

                if (!(State == ChannelState.Closed || State == ChannelState.ClosedReceived))
                {
                    try
                    {
                        CloseAsync().GetAwaiter();
                        //Task task = CloseAsync();
                        //Task.WaitAll(task);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Exception Dispose/Closing TCP Client {0}", ex.Message);
                        Console.WriteLine("***** Inner Exception {0} *****", ex.InnerException);
                        Console.WriteLine("***** Stack Trace {0} *****", ex.InnerException.StackTrace);
                    }
                }

                protocol        = null;
                client          = null;
                readConnection  = null;
                writeConnection = null;
            }
        }
        private static void DoTestClientServer(bool fragment)
        {
            SecureRandom secureRandom = new SecureRandom();

            TlsClientProtocol clientProtocol = new TlsClientProtocol(secureRandom);
            TlsServerProtocol serverProtocol = new TlsServerProtocol(secureRandom);

            clientProtocol.Connect(new MockTlsClient(null));
            serverProtocol.Accept(new MockTlsServer());

            // pump handshake
            bool hadDataFromServer = true;
            bool hadDataFromClient = true;
            while (hadDataFromServer || hadDataFromClient)
            {
                hadDataFromServer = PumpData(serverProtocol, clientProtocol, fragment);
                hadDataFromClient = PumpData(clientProtocol, serverProtocol, fragment);
            }

            // send data in both directions
            byte[] data = new byte[1024];
            secureRandom.NextBytes(data);
            WriteAndRead(clientProtocol, serverProtocol, data, fragment);
            WriteAndRead(serverProtocol, clientProtocol, data, fragment);

            // close the connection
            clientProtocol.Close();
            PumpData(clientProtocol, serverProtocol, fragment);
            CheckClosed(serverProtocol);
            CheckClosed(clientProtocol);
        }
예제 #4
0
        public async static Task <TlsClientProtocol> PerformSSLHadshakeWithToken(ConnectionState connectionState, CancellationToken token)
        {
            byte[] random      = new byte[128];
            var    rngProvider = new System.Security.Cryptography.RNGCryptoServiceProvider();

            rngProvider.GetBytes(random);
            var secureRandomInstance = SecureRandom.GetInstance("SHA256PRNG");

            secureRandomInstance.SetSeed(random);

            TlsClientProtocol pkiClientProtocol = new TlsClientProtocol(secureRandomInstance);

            MyPKITlsClient pkiClient = new MyPKITlsClient();

            pkiClientProtocol.Connect(pkiClient);

            await SendSelectSslModuleApduAsync(connectionState, token);

            await SendSslResetApduAsync(connectionState, token);

            while (pkiClient.handshakeFinished != true)
            {
                int dataAvailable = pkiClientProtocol.GetAvailableOutputBytes();

                byte[] data = new byte[dataAvailable];

                pkiClientProtocol.ReadOutput(data, 0, dataAvailable);

                byte[] response = await SendHandshakeApduAsync(data, connectionState, token);

                pkiClientProtocol.OfferInput((byte[])response);
            }

            return(pkiClientProtocol);
        }
예제 #5
0
        private static byte[] WrapApdu(byte[] apdu, TlsClientProtocol tls)
        {
            byte[]      header    = { 0x84, 0x00, 0x00, 0x00 };
            List <byte> finalApdu = new List <byte>();

            tls.OfferOutput(apdu, 0, apdu.Length);
            int dataAvailable = tls.GetAvailableOutputBytes();

            byte[] wrappedData = new byte[dataAvailable];
            tls.ReadOutput(wrappedData, 0, wrappedData.Length);

            if (wrappedData.Length <= 255)
            {
                finalApdu.AddRange(header);
                finalApdu.Add((byte)wrappedData.Length);
                finalApdu.AddRange(wrappedData);
            }
            else
            {
                finalApdu.AddRange(header);
                finalApdu.Add((byte)0x00);
                finalApdu.Add((byte)(wrappedData.Length >> 8));
                finalApdu.Add((byte)wrappedData.Length);
                finalApdu.AddRange(wrappedData);
            }

            return(finalApdu.ToArray());
        }
    public static Stream WrapWithTls(Stream stream)
    {
        var client            = new MyTlsClient();
        var tlsClientProtocol = new TlsClientProtocol(stream, new SecureRandom());

        tlsClientProtocol.Connect(client);
        return(tlsClientProtocol.Stream);
    }
예제 #7
0
        internal static TlsClientProtocol OpenTlsConnection(string hostname, int port, TlsClient client)
        {
            TcpClient tcp = new TcpClient(hostname, port);

            TlsClientProtocol protocol = new TlsClientProtocol(tcp.GetStream(), secureRandom);
            protocol.Connect(client);
            return protocol;
        }
예제 #8
0
        internal static TlsClientProtocol OpenTlsConnection(string hostname, int port, TlsClient client)
        {
            TcpClient tcp = new TcpClient(hostname, port);

            TlsClientProtocol protocol = new TlsClientProtocol(tcp.GetStream(), secureRandom);

            protocol.Connect(client);
            return(protocol);
        }
        public static void Main(string[] args)
        {
            string hostname = "localhost";
            int    port     = 5556;

            long time1 = DateTime.UtcNow.Ticks;

            /*
             * Note: This is the default PSK identity for 'openssl s_server' testing, the server must be
             * started with "-psk 6161616161" to make the keys match, and possibly the "-psk_hint"
             * option should be present.
             */
            //string psk_identity = "Client_identity";
            //byte[] psk = new byte[]{ 0x61, 0x61, 0x61, 0x61, 0x61 };

            // These correspond to the configuration of MockPskTlsServer
            string psk_identity = "client";

            byte[] psk = Strings.ToUtf8ByteArray("TLS_TEST_PSK");

            BasicTlsPskIdentity pskIdentity = new BasicTlsPskIdentity(psk_identity, psk);

            MockPskTlsClient  client   = new MockPskTlsClient(null, pskIdentity);
            TlsClientProtocol protocol = OpenTlsConnection(hostname, port, client);

            protocol.Close();

            long time2 = DateTime.UtcNow.Ticks;

            Console.WriteLine("Elapsed 1: " + (time2 - time1) / TimeSpan.TicksPerMillisecond + "ms");

            client   = new MockPskTlsClient(client.GetSessionToResume(), pskIdentity);
            protocol = OpenTlsConnection(hostname, port, client);

            long time3 = DateTime.UtcNow.Ticks;

            Console.WriteLine("Elapsed 2: " + (time3 - time2) / TimeSpan.TicksPerMillisecond + "ms");

            byte[] req = Encoding.UTF8.GetBytes("GET / HTTP/1.1\r\n\r\n");

            Stream tlsStream = protocol.Stream;

            tlsStream.Write(req, 0, req.Length);
            tlsStream.Flush();

            StreamReader reader = new StreamReader(tlsStream);

            String line;

            while ((line = reader.ReadLine()) != null)
            {
                Console.WriteLine(">>> " + line);
            }

            protocol.Close();
        }
예제 #10
0
        internal static Stream WrapStream(Stream stream, String hostName)
        {
            if (GSTlsClient.logger != null)
            {
                GSTlsClient.logger("Wrapping");
            }

            TlsClientProtocol tslcp = new TlsClientProtocol(stream, new SecureRandom());

            tslcp.Connect(new GSTlsClient(hostName));
            return(new DuplexTlsStream(tslcp.Stream));
        }
예제 #11
0
        public async static Task EstablishSRPChannelAsync(ConnectionState connectionState, CancellationToken token)
        {
            string keyAsString;

            Settings.GetSrpKey(out keyAsString);
            byte[] key = keyAsString.ConvertHexStringToByteArray();

            byte[] random      = new byte[128];
            var    rngProvider = new System.Security.Cryptography.RNGCryptoServiceProvider();

            rngProvider.GetBytes(random);
            var secureRandomInstance = SecureRandom.GetInstance("SHA256PRNG");

            secureRandomInstance.SetSeed(random);

            TlsClientProtocol srpClientProtocol = new TlsClientProtocol(secureRandomInstance);

            var srpClient = new MySrpTlsClient(Encoding.ASCII.GetBytes("user"), key);

            srpClientProtocol.Connect(srpClient);

            var stream = connectionState.client.GetStream();

            byte[] inputBuffer = new byte[4096];

            while (srpClient.handshakeFinished != true)
            {
                int dataAvailable = srpClientProtocol.GetAvailableOutputBytes();

                if (dataAvailable != 0)
                {
                    byte[] data = new byte[dataAvailable];

                    srpClientProtocol.ReadOutput(data, 0, dataAvailable);

                    await stream.WriteAsync(data, 0, dataAvailable, token);
                }

                int bytesReceived = await stream.ReadAsync(inputBuffer, 0, inputBuffer.Length, token);

                if (bytesReceived != 0)
                {
                    byte[] truncatedInputBuffer = new byte[bytesReceived];
                    Array.Copy(inputBuffer, 0, truncatedInputBuffer, 0, bytesReceived);

                    srpClientProtocol.OfferInput(truncatedInputBuffer);
                }
            }

            connectionState.srpClientProtocol = srpClientProtocol;
        }
예제 #12
0
        public override async Task CloseAsync()
        {
            if (State == ChannelState.Closed || State == ChannelState.ClosedReceived)
            {
                return;
            }

            State = ChannelState.ClosedReceived;

            try
            {
                if (protocol != null)
                {
                    protocol.Close();
                }
            }
            catch { }

            protocol = null;

            if (client != null && client.Client != null && (client.Client.Connected && client.Client.Poll(10, SelectMode.SelectRead)))
            {
                if (client.Client.UseOnlyOverlappedIO)
                {
                    client.Client.DuplicateAndClose(Process.GetCurrentProcess().Id);
                }
                else
                {
                    client.Close();
                }
            }

            client = null;

            if (readConnection != null)
            {
                readConnection.Dispose();
            }

            if (writeConnection != null)
            {
                writeConnection.Dispose();
            }

            State = ChannelState.Closed;
            OnClose?.Invoke(this, new ChannelCloseEventArgs(Id));

            await Task.CompletedTask;
        }
예제 #13
0
        private static byte[] UnwrapApdu(byte[] response, TlsClientProtocol tls)
        {
            tls.OfferInput(response);
            int dataAvailable = tls.GetAvailableInputBytes();

            if (dataAvailable == 0)
            {
                throw new RemoteProtocolException("Error in APDU response");
            }

            byte[] unwrappedData = new byte[dataAvailable];
            tls.ReadInput(unwrappedData, 0, unwrappedData.Length);

            return(unwrappedData);
        }
예제 #14
0
 public static TlsClientProtocol ConnectPskTlsClientNonBlocking(string identity, byte[] psk)
 {
     try
     {
         SimplePskIdentity pskIdentity  = new SimplePskIdentity(identity, psk);
         PskTlsClient2     pskTlsClient = new PskTlsClient2(pskIdentity);
         TlsClientProtocol protocol     = new TlsClientProtocol(new SecureRandom());
         protocol.Connect(pskTlsClient);
         return(protocol);
     }
     catch (Exception ex)
     {
         Console.WriteLine("Exception in TLS protocol connnection '{0}'", ex.Message);
         throw ex;
     }
 }
예제 #15
0
        public async Task Connect(string host, int port)
        {
            _tcpClient = new TcpClient();

            await _tcpClient.ConnectAsync(host, port).ConfigureAwait(false);

            StartTlsResult sessionInitialized = await TryInitializeSession(_tcpClient.GetStream()).ConfigureAwait(false);

            if (!sessionInitialized.Success)
            {
                throw new Exception("Failed to initialize session.");
            }

            TlsClientProtocol clientProtocol = new TlsClientProtocol(_tcpClient.GetStream(), SecureRandom.GetInstance("SHA256PRNG"));

            clientProtocol.Connect(new BasicTlsClient());
        }
예제 #16
0
        public static void RunMainTests(string[] args)
        {
            string hostname = "localhost";
            int    port     = 5556;

            long time1 = DateTime.UtcNow.Ticks;

            MockTlsClient     client   = new MockTlsClient(null);
            TlsClientProtocol protocol = OpenTlsConnection(hostname, port, client);

            protocol.Close();

            long time2 = DateTime.UtcNow.Ticks;

            Console.WriteLine("Elapsed 1: " + (time2 - time1) / TimeSpan.TicksPerMillisecond + "ms");

            client   = new MockTlsClient(client.GetSessionToResume());
            protocol = OpenTlsConnection(hostname, port, client);

            long time3 = DateTime.UtcNow.Ticks;

            Console.WriteLine("Elapsed 2: " + (time3 - time2) / TimeSpan.TicksPerMillisecond + "ms");

            byte[] req = Encoding.UTF8.GetBytes("GET / HTTP/1.1\r\n\r\n");

            Stream tlsStream = protocol.Stream;

            tlsStream.Write(req, 0, req.Length);
            tlsStream.Flush();

            StreamReader reader = new StreamReader(tlsStream);

            String line;

            while ((line = reader.ReadLine()) != null)
            {
                Console.WriteLine(">>> " + line);
            }

            protocol.Close();
        }
예제 #17
0
        public void TestClientServer()
        {
            SecureRandom secureRandom = new SecureRandom();

            PipedStream clientPipe = new PipedStream();
            PipedStream serverPipe = new PipedStream(clientPipe);

            TlsClientProtocol clientProtocol = new TlsClientProtocol(clientPipe, secureRandom);
            TlsServerProtocol serverProtocol = new TlsServerProtocol(serverPipe, secureRandom);

            Server server = new Server(serverProtocol);

            Thread serverThread = new Thread(new ThreadStart(server.Run));

            serverThread.Start();

            MockPskTlsClient client = new MockPskTlsClient(null);

            clientProtocol.Connect(client);

            // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity
            int length = 1000;

            byte[] data = new byte[length];
            secureRandom.NextBytes(data);

            Stream output = clientProtocol.Stream;

            output.Write(data, 0, data.Length);

            byte[] echo  = new byte[data.Length];
            int    count = Streams.ReadFully(clientProtocol.Stream, echo);

            Assert.AreEqual(count, data.Length);
            Assert.IsTrue(Arrays.AreEqual(data, echo));

            output.Close();

            serverThread.Join();
        }
예제 #18
0
        /// <summary>
        /// Send a HTTP request to the remote socket
        /// </summary>
        /// <param name="method"></param>
        /// <param name="resource"></param>
        /// <param name="httpVersion"></param>
        /// <param name="client"></param>
        /// <param name="headers"></param>
        /// <returns>Response Stream</returns>
        public Stream SendHttp(string method, string resource, string data, string httpVersion, TlsClient client, HttpHeaders headers)
        {
            TlsClientProtocol protocol = new TlsClientProtocol(_tcpClient.GetStream(), new SecureRandom());

            try
            {
                protocol.Connect(client);
            }
            catch (TlsException)
            {
                throw new ProtocolVersionNotSupported();
            }

            // build protocol info, headers & body
            StringBuilder sb = new StringBuilder();

            sb.AppendLine($"{method.ToUpper()} {resource} HTTP/{httpVersion}");
            if (!headers.Contains("host"))
            {
                headers.Add("Host", _host);
            }
            sb.AppendLine(headers.ToString());

            // append data in case of POST or similar
            if (data != null)
            {
                sb.Append(data);
            }
            // Console.WriteLine(sb.ToString());

            var requestBytes = Encoding.ASCII.GetBytes(sb.ToString());

            Stream stream = protocol.Stream;

            stream.Write(requestBytes, 0, requestBytes.Length);
            stream.Flush();

            return(stream);
        }
예제 #19
0
 public static TlsClientProtocol ConnectPskTlsClientNonBlocking(this TcpClient client, string identity, byte[] psk)
 {
     try
     {
         SimplePskIdentity pskIdentity  = new SimplePskIdentity(identity, psk);
         PskTlsClient2     pskTlsClient = new PskTlsClient2(pskIdentity);
         TlsClientProtocol protocol     = new TlsClientProtocol(new SecureRandom());
         protocol.Connect(pskTlsClient);
         return(protocol);
     }
     catch (AggregateException ae)
     {
         string msg = String.Format("AggregateException in TLS protocol connnection '{0}'", ae.Flatten().InnerException.Message);
         Console.WriteLine(msg);
         throw new Exception(msg, ae.Flatten().InnerException);
     }
     catch (Exception ex)
     {
         Console.WriteLine("Exception in TLS protocol connnection '{0}'", ex.Message);
         throw ex;
     }
 }
예제 #20
0
        public void TestClientServer()
        {
            SecureRandom secureRandom = new SecureRandom();

            PipedStream clientPipe = new PipedStream();
            PipedStream serverPipe = new PipedStream(clientPipe);

            TlsClientProtocol clientProtocol = new TlsClientProtocol(clientPipe, secureRandom);
            TlsServerProtocol serverProtocol = new TlsServerProtocol(serverPipe, secureRandom);

            Server server = new Server(serverProtocol);

            Thread serverThread = new Thread(new ThreadStart(server.Run));
            serverThread.Start();

            MockSrpTlsClient client = new MockSrpTlsClient(null, MockSrpTlsServer.TEST_IDENTITY, MockSrpTlsServer.TEST_PASSWORD);
            clientProtocol.Connect(client);

            // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity
            int length = 1000;

            byte[] data = new byte[length];
            secureRandom.NextBytes(data);

            Stream output = clientProtocol.Stream;
            output.Write(data, 0, data.Length);

            byte[] echo = new byte[data.Length];
            int count = Streams.ReadFully(clientProtocol.Stream, echo);

            Assert.AreEqual(count, data.Length);
            Assert.IsTrue(Arrays.AreEqual(data, echo));

            output.Close();

            serverThread.Join();
        }
 public void Connect(IPAddress IPAddress, UInt16 Port, byte[] PSK, UInt64 ClientID)
 {
     AssertInitialized();
     if (IPAddress == null)
     {
         throw new ArgumentNullException("IPAddress");
     }
     if (Port == 0)
     {
         throw new ArgumentOutOfRangeException("Port", "Must be greater than 0");
     }
     if (PSK.Length != 32)
     {
         throw new ArgumentException("Must be 32 bytes", "PSK");
     }
     if (ClientID == 0)
     {
         throw new ArgumentOutOfRangeException("ClientID", "Must be greater than 0");
     }
     this.IPAddress = IPAddress;
     try
     {
         this.ClientID = ClientID;
         TcpClient           TcpClient           = new TcpClient(IPAddress.ToString(), Port);
         TlsClientProtocol   TlsClientProtocol   = new TlsClientProtocol(TcpClient.GetStream(), new SecureRandom());
         SteamPSKTLSIdentity SteamPSKTLSIdentity = new SteamPSKTLSIdentity(Encoding.UTF8.GetBytes(PSKIdentity), PSK);
         SteamPSKTLSClient   Client = new SteamPSKTLSClient(SteamPSKTLSIdentity);
         TlsClientProtocol.Connect(Client);
         TLSStream = TlsClientProtocol.Stream;
         IncomingMessageProcessingThread.Start();
         OutgoingMessageProcessingThread.Start();
     }
     catch (Exception e)
     {
         ExceptionHandler(e);
     }
 }
예제 #22
0
 public HttpResponse Do(HttpRequest req)
 {
     using (var tcpClient = new TcpClient(req.RequestUri.Host, req.RequestUri.Port))
     {
         if (req.RequestUri.Scheme == Uri.UriSchemeHttps)
         {
             var protocol  = new TlsClientProtocol(tcpClient.GetStream(), new SecureRandom());
             var tlsClient = new MyTlsClient();
             protocol.Connect(tlsClient);
             var stream = protocol.Stream;
             WriteRequest(req, stream);
             var res = ReadResponse(stream);
             protocol.Close();
             return(res);
         }
         else
         {
             var stream = tcpClient.GetStream();
             WriteRequest(req, stream);
             var res = ReadResponse(stream);
             return(res);
         }
     }
 }
예제 #23
0
        private void Connect()
        {
            Uri uri =
#if !BESTHTTP_DISABLE_PROXY
                CurrentRequest.HasProxy ? CurrentRequest.Proxy.Address :
#endif
                CurrentRequest.CurrentUri;

            #region TCP Connection

            if (Client == null)
            {
                Client = new TcpClient();
            }

            if (!Client.Connected)
            {
                Client.ConnectTimeout = CurrentRequest.ConnectTimeout;

#if NETFX_CORE || (UNITY_WP8 && !UNITY_EDITOR)
                Client.UseHTTPSProtocol =
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
                    !CurrentRequest.UseAlternateSSL &&
#endif
                    HTTPProtocolFactory.IsSecureProtocol(uri);
#endif

                Client.Connect(uri.Host, uri.Port);

                if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
                {
                    HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host + ":" + uri.Port.ToString());
                }
            }
            else if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
            {
                HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host + ":" + uri.Port.ToString());
            }

            #endregion

            lock (HTTPManager.Locker)
                StartTime = DateTime.UtcNow;

            if (Stream == null)
            {
                bool isSecure = HTTPProtocolFactory.IsSecureProtocol(CurrentRequest.CurrentUri);

#if !BESTHTTP_DISABLE_PROXY
                #region Proxy Handling

                if (HasProxy && (!Proxy.IsTransparent || (isSecure && Proxy.NonTransparentForHTTPS)))
                {
                    Stream = Client.GetStream();
                    var outStream = new BinaryWriter(Stream);

                    bool retry;
                    do
                    {
                        // If we have to becouse of a authentication request, we will switch it to true
                        retry = false;

                        outStream.SendAsASCII(string.Format("CONNECT {0}:{1} HTTP/1.1", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port));
                        outStream.Write(HTTPRequest.EOL);

                        outStream.SendAsASCII("Proxy-Connection: Keep-Alive");
                        outStream.Write(HTTPRequest.EOL);

                        outStream.SendAsASCII("Connection: Keep-Alive");
                        outStream.Write(HTTPRequest.EOL);

                        outStream.SendAsASCII(string.Format("Host: {0}:{1}", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port));
                        outStream.Write(HTTPRequest.EOL);

                        // Proxy Authentication
                        if (HasProxy && Proxy.Credentials != null)
                        {
                            switch (Proxy.Credentials.Type)
                            {
                            case AuthenticationTypes.Basic:
                                // With Basic authentication we don't want to wait for a challange, we will send the hash with the first request
                                outStream.Write(string.Format("Proxy-Authorization: {0}", string.Concat("Basic ", Convert.ToBase64String(Encoding.UTF8.GetBytes(Proxy.Credentials.UserName + ":" + Proxy.Credentials.Password)))).GetASCIIBytes());
                                outStream.Write(HTTPRequest.EOL);
                                break;

                            case AuthenticationTypes.Unknown:
                            case AuthenticationTypes.Digest:
                                var digest = DigestStore.Get(Proxy.Address);
                                if (digest != null)
                                {
                                    string authentication = digest.GenerateResponseHeader(CurrentRequest, Proxy.Credentials);
                                    if (!string.IsNullOrEmpty(authentication))
                                    {
                                        outStream.Write(string.Format("Proxy-Authorization: {0}", authentication).GetASCIIBytes());
                                        outStream.Write(HTTPRequest.EOL);
                                    }
                                }

                                break;
                            }
                        }

                        outStream.Write(HTTPRequest.EOL);

                        // Make sure to send all the wrote data to the wire
                        outStream.Flush();

                        CurrentRequest.ProxyResponse = new HTTPResponse(CurrentRequest, Stream, false, false);

                        // Read back the response of the proxy
                        if (!CurrentRequest.ProxyResponse.Receive(-1, true))
                        {
                            throw new Exception("Connection to the Proxy Server failed!");
                        }

                        if (HTTPManager.Logger.Level <= Logger.Loglevels.Information)
                        {
                            HTTPManager.Logger.Information("HTTPConnection", "Proxy returned - status code: " + CurrentRequest.ProxyResponse.StatusCode + " message: " + CurrentRequest.ProxyResponse.Message);
                        }

                        switch (CurrentRequest.ProxyResponse.StatusCode)
                        {
                        // Proxy authentication required
                        // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.8
                        case 407:
                        {
                            string authHeader = DigestStore.FindBest(CurrentRequest.ProxyResponse.GetHeaderValues("proxy-authenticate"));
                            if (!string.IsNullOrEmpty(authHeader))
                            {
                                var digest = DigestStore.GetOrCreate(Proxy.Address);
                                digest.ParseChallange(authHeader);

                                if (Proxy.Credentials != null && digest.IsUriProtected(Proxy.Address) && (!CurrentRequest.HasHeader("Proxy-Authorization") || digest.Stale))
                                {
                                    retry = true;
                                }
                            }
                            break;
                        }

                        default:
                            if (!CurrentRequest.ProxyResponse.IsSuccess)
                            {
                                throw new Exception(string.Format("Proxy returned Status Code: \"{0}\", Message: \"{1}\" and Response: {2}", CurrentRequest.ProxyResponse.StatusCode, CurrentRequest.ProxyResponse.Message, CurrentRequest.ProxyResponse.DataAsText));
                            }
                            break;
                        }
                    } while (retry);
                }
                #endregion
#endif // #if !BESTHTTP_DISABLE_PROXY

                // We have to use CurrentRequest.CurrentUri here, becouse uri can be a proxy uri with a different protocol
                if (isSecure)
                {
                    #region SSL Upgrade

#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
                    if (CurrentRequest.UseAlternateSSL)
                    {
                        var handler = new TlsClientProtocol(Client.GetStream(), new Org.BouncyCastle.Security.SecureRandom());

                        // http://tools.ietf.org/html/rfc3546#section-3.1
                        // It is RECOMMENDED that clients include an extension of type "server_name" in the client hello whenever they locate a server by a supported name type.
                        List <string> hostNames = new List <string>(1);
                        hostNames.Add(CurrentRequest.CurrentUri.Host);

                        handler.Connect(new LegacyTlsClient(CurrentRequest.CurrentUri,
                                                            CurrentRequest.CustomCertificateVerifyer == null ? new AlwaysValidVerifyer() : CurrentRequest.CustomCertificateVerifyer,
                                                            CurrentRequest.CustomClientCredentialsProvider,
                                                            hostNames));

                        Stream = handler.Stream;
                    }
                    else
#endif
                    {
#if !NETFX_CORE && !UNITY_WP8
                        SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) =>
                        {
                            return(CurrentRequest.CallCustomCertificationValidator(cert, chain));
                        });

                        if (!sslStream.IsAuthenticated)
                        {
                            sslStream.AuthenticateAsClient(CurrentRequest.CurrentUri.Host);
                        }
                        Stream = sslStream;
#else
                        Stream = Client.GetStream();
#endif
                    }

                    #endregion
                }
                else
                {
                    Stream = Client.GetStream();
                }
            }
        }
예제 #24
0
        public async static Task <byte[]> ReadXrpTransaction(uint length, ConnectionState connectionState, CancellationToken token, TlsClientProtocol tls)
        {
            List <byte> apdu = new List <byte>();

            byte[]      header = { 0x80, 0xE0, 0x01, 0x00 };
            byte[]      response;
            uint        chunksToRead;
            uint        chunkSize       = 128;
            uint        remainingLength = length;
            List <byte> transaction     = new List <byte>();

            chunksToRead = length / chunkSize;

            if ((length % chunkSize) != 0)
            {
                chunksToRead++;
            }

            for (int i = 0; i < chunksToRead; i++)
            {
                apdu.Clear();
                apdu.AddRange(header);
                apdu.Add(0x02);
                apdu.Add((byte)(i >> 8));
                apdu.Add((byte)i);

                response = await SendWrappedAPDU(apdu.ToArray(), chunkSize, connectionState, token, tls);

                if (remainingLength < chunkSize)
                {
                    response = response.Take((int)remainingLength).ToArray();
                }

                transaction.AddRange(response);

                remainingLength -= chunkSize;
            }

            return(transaction.ToArray());
        }
예제 #25
0
        public async static Task <RippleTransactionInfo> GetXrpTransactionDetails(ConnectionState connectionState, CancellationToken token, TlsClientProtocol tls)
        {
            byte[] apdu = { 0x80, 0xE0, 0x00, 0x00 };
            byte[] response;

            try
            {
                response = await SendWrappedAPDU(apdu, 7, connectionState, token, tls);
            }
            catch (Non9000SwException)
            {
                throw new TransactionNotActiveException();
            }

            RippleTransactionInfo transactionInfo = new RippleTransactionInfo();

            if (response[0] != 0x00)
            {
                transactionInfo.transactionTooBigToDisplay = true;
            }
            else
            {
                transactionInfo.transactionTooBigToDisplay = false;
            }

            transactionInfo.currentOffset = Helper.MakeUint16(response, 1);
            transactionInfo.remainingTime = Helper.MakeUint32(response, 3);

            return(transactionInfo);
        }
예제 #26
0
        public async static Task SelectXrpApp(ConnectionState connectionState, CancellationToken token, TlsClientProtocol tls)
        {
            byte[] apdu = { 0x00, 0xA4, 0x04, 0x00, 0x09, 0x58, 0x52, 0x50, 0x41, 0x50, 0x50, 0x4C, 0x45, 0x54 };

            try
            {
                await SendWrappedAPDU(apdu, 0, connectionState, token, tls);
            }
            catch (Non9000SwException)
            {
                throw new AppNotPresentException();
            }
        }
예제 #27
0
        public async static Task <Int64[]> GetBtcInputAmounts(uint numberOfInputs, ConnectionState connectionState, CancellationToken token, TlsClientProtocol tls)
        {
            List <byte> apdu = new List <byte>();

            byte[]  header = { 0xE0, 0xE0, 0x02, 0x00 };
            byte[]  response;
            Int64[] amounts;

            amounts = new Int64[numberOfInputs];

            apdu.Clear();
            apdu.AddRange(header);

            response = await SendWrappedAPDU(apdu.ToArray(), (numberOfInputs * 8), connectionState, token, tls);

            for (int j = 0; j < numberOfInputs; j++)
            {
                amounts[j] = Helper.MakeInt64(response, j * 8);
            }

            return(amounts);
        }
예제 #28
0
        public async static Task SelectBtcApp(ConnectionState connectionState, CancellationToken token, TlsClientProtocol tls)
        {
            byte[] apdu = { 0x00, 0xA4, 0x04, 0x00, 0x09, 0x42, 0x54, 0x43, 0x41, 0x50, 0x50, 0x4C, 0x45, 0x54 };

            await SendWrappedAPDU(apdu, 0, connectionState, token, tls);
        }
예제 #29
0
        private async static Task <byte[]> SendWrappedAPDU(byte[] apdu, uint expectedLength,
                                                           ConnectionState connectionState, CancellationToken token, TlsClientProtocol tls)
        {
            byte[] wrappedApdu = WrapApdu(apdu, tls);

            byte[] response = await SendApduAsync(wrappedApdu, connectionState, token);

            if ((response[response.Length - 1] != 0x00) || (response[response.Length - 2] != 0x90))
            {
                throw new RemoteProtocolException("Invalid APDU response");
            }

            response = response.Take(response.Count() - 2).ToArray();

            response = UnwrapApdu(response, tls);

            if ((response[response.Length - 1] != 0x00) || (response[response.Length - 2] != 0x90))
            {
                throw new Non9000SwException("Invalid APDU response");
            }

            if ((response.Length) != expectedLength + 2)
            {
                throw new RemoteProtocolException("Invalid APDU response");
            }

            return(response.Take(response.Count() - 2).ToArray());
        }
예제 #30
0
        public void RunTest(TlsTestConfig config)
        {
            CheckTlsVersion(config.clientMinimumVersion);
            CheckTlsVersion(config.clientOfferVersion);
            CheckTlsVersion(config.serverMaximumVersion);
            CheckTlsVersion(config.serverMinimumVersion);

            SecureRandom secureRandom = new SecureRandom();

            PipedStream clientPipe = new PipedStream();
            PipedStream serverPipe = new PipedStream(clientPipe);

            NetworkStream clientNet = new NetworkStream(clientPipe);
            NetworkStream serverNet = new NetworkStream(serverPipe);

            TlsClientProtocol clientProtocol = new TlsClientProtocol(clientNet, secureRandom);
            TlsServerProtocol serverProtocol = new TlsServerProtocol(serverNet, secureRandom);

            TlsTestClientImpl clientImpl = new TlsTestClientImpl(config);
            TlsTestServerImpl serverImpl = new TlsTestServerImpl(config);

            Server server = new Server(this, serverProtocol, serverImpl);

            Thread serverThread = new Thread(new ThreadStart(server.Run));
            serverThread.Start();

            Exception caught = null;
            try
            {
                clientProtocol.Connect(clientImpl);

                // NOTE: Because we write-all before we read-any, this length can't be more than the pipe capacity
                int length = 1000;

                byte[] data = new byte[length];
                secureRandom.NextBytes(data);
    
                Stream output = clientProtocol.Stream;
                output.Write(data, 0, data.Length);

                byte[] echo = new byte[data.Length];
                int count = Streams.ReadFully(clientProtocol.Stream, echo);

                Assert.AreEqual(count, data.Length);
                Assert.IsTrue(Arrays.AreEqual(data, echo));

                output.Close();
            }
            catch (Exception e)
            {
                caught = e;
                LogException(caught);
            }

            server.AllowExit();
            serverThread.Join();

            Assert.IsTrue(clientNet.IsClosed, "Client Stream not closed");
            Assert.IsTrue(serverNet.IsClosed, "Server Stream not closed");

            Assert.AreEqual(config.expectFatalAlertConnectionEnd, clientImpl.FirstFatalAlertConnectionEnd, "Client fatal alert connection end");
            Assert.AreEqual(config.expectFatalAlertConnectionEnd, serverImpl.FirstFatalAlertConnectionEnd, "Server fatal alert connection end");

            Assert.AreEqual(config.expectFatalAlertDescription, clientImpl.FirstFatalAlertDescription, "Client fatal alert description");
            Assert.AreEqual(config.expectFatalAlertDescription, serverImpl.FirstFatalAlertDescription, "Server fatal alert description");

            if (config.expectFatalAlertConnectionEnd == -1)
            {
                Assert.IsNull(caught, "Unexpected client exception");
                Assert.IsNull(server.mCaught, "Unexpected server exception");
            }
        }
예제 #31
0
 public ConnectionState()
 {
     client            = null;
     srpClientProtocol = null;
 }
예제 #32
0
        private void Connect()
        {
            Uri uri = CurrentRequest.HasProxy ? CurrentRequest.Proxy.Address : CurrentRequest.CurrentUri;

            if (Client == null)
            {
                Client = new TcpClient();
            }

            if (!Client.Connected)
            {
                Client.ConnectTimeout = CurrentRequest.ConnectTimeout;

#if NETFX_CORE
                Client.UseHTTPSProtocol = !CurrentRequest.UseAlternateSSL && HTTPProtocolFactory.IsSecureProtocol(uri);

                // On WinRT and >WP8 we use the more secure Tls12 protocol, but on WP8 only Ssl is available...
                #if UNITY_WP_8_1 || UNITY_METRO_8_1
                Client.HTTPSProtocol = (int)SocketProtectionLevel.Tls12;
                #else
                Client.HTTPSProtocol = (int)SocketProtectionLevel.Ssl;
                #endif
#endif
                Client.Connect(uri.Host, uri.Port);

                HTTPManager.Logger.Information("HTTPConnection", "Connected to " + uri.Host);
            }
            else
            {
                HTTPManager.Logger.Information("HTTPConnection", "Already connected to " + uri.Host);
            }

            lock (HTTPManager.Locker)
                StartTime = DateTime.UtcNow;

            if (Stream == null)
            {
                if (HasProxy && !Proxy.IsTransparent)
                {
                    Stream = Client.GetStream();

                    var outStream = new BinaryWriter(Stream);
                    outStream.Write(string.Format("CONNECT {0}:{1} HTTP/1.1", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port).GetASCIIBytes());
                    outStream.Write(HTTPRequest.EOL);

                    outStream.Write(string.Format("Proxy-Connection: Keep-Alive"));
                    outStream.Write(HTTPRequest.EOL);

                    outStream.Write(string.Format("Connection: Keep-Alive"));
                    outStream.Write(HTTPRequest.EOL);

                    outStream.Write(string.Format("Host: {0}:{1}", CurrentRequest.CurrentUri.Host, CurrentRequest.CurrentUri.Port).GetASCIIBytes());
                    outStream.Write(HTTPRequest.EOL);

                    outStream.Write(HTTPRequest.EOL);
                    outStream.Flush();

                    CurrentRequest.ProxyResponse = new HTTPProxyResponse(CurrentRequest, Stream, false, false);
                    if (!CurrentRequest.ProxyResponse.Receive())
                    {
                        throw new Exception("Connection to the Proxy Server failed!");
                    }

                    // TODO: check & handle proxy status code?
                }

                // We have to use CurrentRequest.CurrentUri here, becouse uri can be a proxy uri with a different protocol
                if (HTTPProtocolFactory.IsSecureProtocol(CurrentRequest.CurrentUri))
                {
                    // On WP8 there are no Mono, so we must use the 'alternate' TlsHandlers
                    if (CurrentRequest.UseAlternateSSL)
                    {
                        var handler = new TlsClientProtocol(Client.GetStream(), new Org.BouncyCastle.Security.SecureRandom());
                        if (CurrentRequest.CustomCertificateVerifyer == null)
                        {
                            handler.Connect(new LegacyTlsClient(new AlwaysValidVerifyer()));
                        }
                        else
                        {
                            handler.Connect(new LegacyTlsClient(CurrentRequest.CustomCertificateVerifyer));
                        }
                        Stream = handler.Stream;
                    }
                    else
                    {
#if !UNITY_WP8 && !NETFX_CORE
                        SslStream sslStream = new SslStream(Client.GetStream(), false, (sender, cert, chain, errors) =>
                        {
                            return(CurrentRequest.CallCustomCertificationValidator(cert, chain));
                        });

                        if (!sslStream.IsAuthenticated)
                        {
                            sslStream.AuthenticateAsClient(uri.Host);
                        }
                        Stream = sslStream;
#else
                        Stream = Client.GetStream();
#endif
                    }
                }
                else
                {
                    Stream = Client.GetStream();
                }
            }
        }
예제 #33
0
        public override async Task OnConnectedAsync(ConnectionContext connection)
        {
            Logger.Debug($"Connecting to {_proxySettings.RemoteHost}:{_proxySettings.RemotePort}");
            var proxyClient = new TcpClient();
            await proxyClient.ConnectAsync(_proxySettings.RemoteHost, _proxySettings.RemotePort);

            var ogStream = proxyClient.GetStream();

            Stream proxyStream = ogStream;

            if (_proxySettings.Secure)
            {
                var protocol = new TlsClientProtocol(proxyStream, new Org.BouncyCastle.Security.SecureRandom());
                protocol.Connect(new BlazeTlsClient());
                proxyStream = protocol.Stream;
            }

            var blazeProtocol = new BlazeProxyProtocol();
            var localReader   = connection.CreateReader();
            var localWriter   = connection.CreateWriter();

            var remoteReader = new ProtocolReader(proxyStream);
            var remoteWriter = new ProtocolWriter(proxyStream);


            while (true)
            {
                try
                {
                    var result = await localReader.ReadAsync(blazeProtocol);

                    var message = result.Message;

                    if (message != null)
                    {
                        var header = message.Header;
                        Logger.Debug(
                            $"Client -> Proxy; Length:{header.Length} Component:{header.Component} Command:0x{header.Command:X2} ErrorCode:{header.ErrorCode} MessageType:{header.MessageType} MessageId:{header.MessageId}");

                        var requestPayload = message.Payload;

                        if (!requestPayload.IsEmpty)
                        {
                            if (!_parser.TryParseBody(requestPayload))
                            {
                                Logger.Error("Failed to parse request message");
                            }
                        }

                        await remoteWriter.WriteAsync(blazeProtocol, message);
                    }

                    if (result.IsCompleted)
                    {
                        break;
                    }
                }
                finally
                {
                    localReader.Advance();
                }

                do
                {
                    try
                    {
                        var result = await remoteReader.ReadAsync(blazeProtocol);

                        var message = result.Message;

                        if (message != null)
                        {
                            var header = message.Header;
                            Logger.Debug(
                                $"Proxy <- Server; Length:{header.Length} Component:{header.Component} Command:0x{header.Command:X2} ErrorCode:{header.ErrorCode} MessageType:{header.MessageType} MessageId:{header.MessageId}");

                            var responsePayload = message.Payload;

                            if (!responsePayload.IsEmpty)
                            {
                                if (!_parser.TryParseBody(responsePayload))
                                {
                                    Logger.Error("Failed to parse response message");
                                }
                            }

                            await localWriter.WriteAsync(blazeProtocol, message);
                        }

                        if (result.IsCompleted)
                        {
                            break;
                        }
                    }
                    finally
                    {
                        remoteReader.Advance();
                    }
                } while (ogStream.DataAvailable);
            }
        }
예제 #34
0
        public async static Task <EthereumTransactionInfo> GetEthTransactionDetails(ConnectionState connectionState, CancellationToken token, TlsClientProtocol tls)
        {
            byte[] apdu = { 0x80, 0xE0, 0x00, 0x00 };
            byte[] response;

            try
            {
                response = await SendWrappedAPDU(apdu, 29, connectionState, token, tls);
            }
            catch (Non9000SwException)
            {
                throw new TransactionNotActiveException();
            }

            EthereumTransactionInfo transactionInfo = new EthereumTransactionInfo();

            transactionInfo.type = Helper.MakeUint16(response, 0);

            if (response[2] != 0x00)
            {
                transactionInfo.transactionTooBigToDisplay = true;
            }
            else
            {
                transactionInfo.transactionTooBigToDisplay = false;
            }

            transactionInfo.currentOffset = Helper.MakeUint16(response, 3);
            transactionInfo.address       = new byte[20];
            Array.Copy(response, 5, transactionInfo.address, 0, 20);
            transactionInfo.remainingTime = Helper.MakeUint32(response, 25);
            return(transactionInfo);
        }