C# SSL secure sockets

Mateusz Chromiński picture Mateusz Chromiński · Jun 23, 2011 · Viewed 13.7k times · Source

I have a fine, working communicator application, written in C#. Now I need to implement a secure connection to the server. I've tried changing Socket and TcpClient objects into SslStream, but I got a few errors.

Firstly I generated a .cer certificate using makecert. OpenSSL certificates didn't worked for me, because they didn't include private key. Next I created a certificate object on the server and bound it to the SslStream:

X509Certificate serverCertificate = X509Certificate.CreateFromCertFile("ca.cer");
TcpClient clientSocket = this.tcpListener.AcceptTcpClient();
SslStream ssls = new SslStream(clientSocket.GetStream(), false);
ssls.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);

On the client side I'm doing this:

TcpClient client = new TcpClient(settings.IP, settings.Port);                                
sslStream = new SslStream(client.GetStream(), false,
    new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
sslStream.AuthenticateAsClient(settings.IP);

public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
    if (sslPolicyErrors == SslPolicyErrors.None)
        return true;

    Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
    return false;
}

but the AuthenticateAsClient function throws an exception. I tried several other method parameters, but none of this worked for me.

Could anyone help me, or explain step by step how to change simple sockets into secure ones? To be clear, SSL isn't the requirement - if there is simpler way to make the connection secure I can use that.


Edit: Message in exception is following:

The remote certificate is invalid according to the validation procedure.

Answer

KMeda picture KMeda · Jun 23, 2011

What's the exception ?

I guess you are getting the exception because your client certificate is rejected as valid from the server (unless you did the necessary things to set up trust).

When you use self signed certificates(the ones created by makecert), you would have to also supply a Client Certificate Validation callback when creating the SslStream object. Use this constructor overload http://msdn.microsoft.com/en-us/library/ms145056.aspx