0

I am trying to make a C# program that listens for TCP tunnel in order to receive secure information via TLS. I have created a pair of certificate.crt and private.key files with OpenSSL following the usual way, so as to import an X509Certificate2 from my C# program.

My C# program:

using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Reflection;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using KeysExchange;
class Program
{
    static void Main(string[] args)
    {
        
        // Load the SSL certificate
        // Load the server certificate from an embedded resource
        string certFilePath = "/etc/ssl/private/certificate.crt";
        string skFilePath = "/etc/ssl/private/private.key";
        // Load the certificate with the associated private key
        X509Certificate2 serverCertificate = new X509Certificate2(certFilePath);
        int port = 443;
        IPAddress ipAddress = IPAddress.Parse("... my local IP");

        if (serverCertificate != null)
        {
            TcpListener listener = new TcpListener(ipAddress, port);
            listener.Start();

            Console.WriteLine("SSL listener started...");

            while (true)
            {
                var client = listener.AcceptTcpClient();
                Console.WriteLine($"[TCP] Listening on port: {port}, ipaddr: {ipAddress}. Client availability:" +
                    $"{client.Available}");

                // Wrap the stream with an SSL stream
                SslStream sslStream = new SslStream(client.GetStream(), false);
                try
                {
                    // Authenticate the SSL connection with the private key password
                    sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls12, true);

                    // Read the incoming message
                    using (StreamReader reader = new StreamReader(sslStream))
                    {
                        var message = reader.ReadLine();
                        Console.WriteLine($"Received message: {message}");

                        
                    }

                    // Close the SSL stream and the client connection
                    sslStream.Close();
                    client.Close();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error: {ex.Message}");
                    client.Close();
                }
            }
        }

        Console.ReadLine();
    }


}

The problem is when I launch the .NET program, displaying the following output:

SSL listener started...
[TCP] Listening on port: 443, ipaddr: (...). Client availability:165
Error: The server mode SSL must use a certificate with the associated private key.

My server is running in Ubuntu 20.04, a remote virtual server, in which the keys have been created in /etc/ssl/private location. Does anybody know why my C# program is not responding for that certificate? I tried several solutions such as adding my self-signed certificate to CA-certificates, and seeing if the following commands makes the same output:

openssl x509 -noout -modulus -in certificate.crt | openssl md5
openssl rsa -noout -modulus -in private.key | openssl md5

And obviously receiving the same output for both cases. I am a little bit desperate, I really do not know what is going wrong.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
Raul
  • 41
  • 4
  • Side note: `tcpClient` and `sslStream` need `using`, also you should hand off the `tcpClient` to another task if you want to deal with multiple simultaneous connections. – Charlieface Mar 20 '23 at 23:31
  • Do you have any example of multi threaded tcp and sslstream server? I just want a maximum of two connections btw. – Raul Mar 21 '23 at 09:23
  • This is a good start https://stackoverflow.com/a/72992487/14868997. Does the above link answer your actual question? If so you should be able to accept it. – Charlieface Mar 21 '23 at 10:23
  • Yes, that worked for me, thk u very much. I will work in spam avoiding, i do not know why I am receiving random HttpGet Requests. – Raul Mar 21 '23 at 18:07

1 Answers1

0

.NET uses its own certificate store which on Linux is located at ~/.dotnet/corefx/cryptography/x509stores/.
One of the ways to manage certificates in there is to use certificate-tool, e.g.:

certificate-tool add --cert ./certificate.crt --key ./private.key

Also note that LocalMachine store does not exist on Linux so you have to use CurrentUser instead.

Ed'ka
  • 6,595
  • 29
  • 30