user740521
user740521

Reputation: 1204

SSL Connection is failing without client side authentication

I read that client side authentication is optional, so I am trying to connect to my SSL server without authenticating on the client side. When I do this I get the following error on the server:

, in accept_connection
    ssl_version=ssl.PROTOCOL_SSLv23
  File "/usr/lib/python2.7/ssl.py", line 933, in wrap_socket
    ciphers=ciphers)
  File "/usr/lib/python2.7/ssl.py", line 601, in __init__
    self.do_handshake()
  File "/usr/lib/python2.7/ssl.py", line 830, in do_handshake
    self._sslobj.do_handshake()
SSLEOFError: EOF occurred in violation of protocol (_ssl.c:590)

Here is the working server and client code, everything works fine when I authenticate on the client side, but the error shows up when I comment that line out.

Server (python):

def accept_connection(self, sock):
    client, (addr, port) = sock.accept()
    sslclient = ssl.wrap_socket(
        client,
        server_side=True,
        certfile=self.ssl_cert_file,
        keyfile=self.ssl_key_file,
        ssl_version=ssl.PROTOCOL_SSLv23
    )

Client (C#):

public bool Connect()
    {
        try
        {
            client = new TcpClient(this.ServerAddress, this.ServerPort);

            sslStream = new SslStream(
                client.GetStream(),
                false,
                new RemoteCertificateValidationCallback(ValidateCert),
                null
            );

            try
            {
                sslStream.AuthenticateAsClient(this.ServerAddress);
            }
            catch (AuthenticationException e)
            {
                sslStream = null;
                client.Close();
                client = null;
                return false;
            }
        }
        catch (Exception e)
        {
            return false;
        }

        return true;
    }

The above is working code with no errors.

When I comment out the following code on the client:

//sslStream.AuthenticateAsClient(this.ServerAddress);

The python error mentioned above shows up, and the client connection doesn't throw any exceptions and continues running until its first read, then fails with:

This operation is only allowed using a successfully authenticated context.

How can I go about making this work if I do not call AuthenticateAsClient?

This is how i generate certfile and keyfile

openssl req -x509 -newkey rsa:1024 -keyout my.key -out my.crt -days 365 -nodes -subj "/C=US/ST=VA/L=Junk/O=None/OU=Junk/CN=example.local"

Python is version 2.

Perhaps I have just been misinformed that the call to AuthenticateAsClient is optional?

Upvotes: 3

Views: 3106

Answers (1)

Evk
Evk

Reputation: 101463

Ssl client certificate authentication is indeed optional. It's when client sends its certificate to server, and server verifies this certificate is valid, is what server expects, and authenticates client with that certificate.

However, this is not what is performed by

sslStream.AuthenticateAsClient(this.ServerAddress);

As documentation states, this method is

Called by clients to authenticate the server and optionally the client in a client-server connection.

Authenticating the server (verifying its certificate is valid, was issued for the expected domain, was issued by trusted authority) is a required step in ssl handshake. For example, using description by this link we see that step 3 is:

The SSL or TLS client verifies the server's digital certificate

Server waits for the result of this step from client to proceed. For that reason, if you skip this step by commenting the call to AuthenticateAsClient - your python server correctly complains about protocol violation.

To use client authentication you would use another overload:

X509CertificateCollection clientCerts = GetClientCerts();
sslStream.AuthenticateAsClient(this.ServerAddress, clientCerts, true);

Since you are not doing that - you are not performing (optional) client authentication.

Upvotes: 3

Related Questions