foens / hpop

OpenPOP.NET code repository
http://hpop.sourceforge.net/
202 stars 114 forks source link

Connect() does not use tls 1.2 by default for SslStream #64

Open rdub1a4 opened 6 years ago

rdub1a4 commented 6 years ago

Would be nice for Connect() to use tls 1.2 by default or allow for SslProtocols to be passed to sslStream.AuthenticateAsClient().

Workaround is to create SslStream manually and pass to Pop3Client.Connect(Stream):


/// <summary>
        /// Need to manually create Pop3Client.Connect TcpStream to force tls1.2 to be used since not on .net 4.6 yet 
        /// </summary>
        /// <param name="client"></param>
        /// <param name="host"></param>
        /// <param name="port"></param>
        /// <param name="useSsl"></param>
        private void OpenPopConnect(Pop3Client client, string host, int port, bool useSsl, int receiveTimeout, int sendTimeout, RemoteCertificateValidationCallback certificateValidator)
        {
            TcpClient clientSocket = new TcpClient();
            clientSocket.ReceiveTimeout = receiveTimeout;
            clientSocket.SendTimeout = sendTimeout;

            try
            {
                clientSocket.Connect(host, port);
            }
            catch (SocketException e)
            {
                // Close the socket - we are not connected, so no need to close stream underneath
                clientSocket.Close();

                throw new PopServerNotFoundException("Server not found", e);
            }

            Stream stream;
            if (useSsl)
            {
                // If we want to use SSL, open a new SSLStream on top of the open TCP stream.
                // We also want to close the TCP stream when the SSL stream is closed
                // If a validator was passed to us, use it.
                SslStream sslStream;
                if (certificateValidator == null)
                {
                    sslStream = new SslStream(clientSocket.GetStream(), false);
                }
                else
                {
                    sslStream = new SslStream(clientSocket.GetStream(), false, certificateValidator);
                }
                sslStream.ReadTimeout = receiveTimeout;
                sslStream.WriteTimeout = sendTimeout;

                // Authenticate the server
                sslStream.AuthenticateAsClient(host, null, System.Security.Authentication.SslProtocols.Tls12, true);

                stream = sslStream;
            }
            else
            {
                // If we do not want to use SSL, use plain TCP
                stream = clientSocket.GetStream();
            }

            // Now do the connect with the same stream being used to read and write to
            client.Connect(stream);
        }
wriedmann commented 5 years ago

Thank you very much! Your comment helped me to solve issues - Italian PEC requires at least TLS 1.2, and thanks to your comment I was able to make it work.