SSL/TLS client authentication?

May 17, 2013 at 3:27 PM
When running in TLS mode, does SuperSocket permit clients to present certificates?

If so, what functions are provided for us to perform authentication of those certificates?
Coordinator
May 19, 2013 at 2:44 AM
May 19, 2013 at 1:38 PM
I've read the documentation, but it only discusses the certificate at the server end - it doesn't mention certificates presented by clients.

What functions are provided for us to perform authentication of those certificates? (e.g. checking against a list of valid thumbprints, or checking the issuer is trusted)
Coordinator
May 19, 2013 at 2:05 PM
May 19, 2013 at 2:44 PM
OK, looks like I need to hook into the AuthenticateAsServer methods. Does the SuperSocket API expose any way to do this?
Coordinator
May 19, 2013 at 2:53 PM
No, you are wrong, what you need is AuthenticateAsClient. The client doesn't have relationship with SuperSocket. Please google more articles on how to use SslStream in cleint side.
May 19, 2013 at 3:47 PM
I understand that it's up to the client to present (or not) a certificate to the server.

But it is of course up to the server how to authenticate the presented client certificates. In the MSDN article you linked to, it looks like you call SslStream.AuthenticateAsServer Method (X509Certificate, Boolean, SslProtocols, Boolean). It says this:
Called by servers to begin an asynchronous operation to authenticate the server and optionally the client using the specified certificates, requirements and security protocol
There is an SslStream constructor that lets you specify a callback to allow you to validate the certificate:
SslStream Constructor (Stream, Boolean, RemoteCertificateValidationCallback)
Initializes a new instance of the SslStream class using the specified Stream, stream closure behavior and certificate validation delegate
I found a code snippet here.

So, does the SuperSocket API expose any way to specify the validation callback, and to request that clients must present a certificate?
Coordinator
May 19, 2013 at 3:54 PM
Edited May 19, 2013 at 3:57 PM
No, it's automatically.

The server will validate the clients automatically.

The fact is the certificate is provided by the server side. It is same with the certificate of https of websites.
May 19, 2013 at 4:11 PM
Yes, but there is also something slightly different (quite commonly used!) called 'mutual authentication', where both the server and client authenticate each other.

I'm not sure if SuperSocket does provide any validation of client certificates today, as the SslStream constructor it uses doesn't enforce clients presenting certificates.

What I need to do is use a different SslStream constructor to specify that client certificates must be presented, and use a different AuthenticateAsServer overload to specify a validation callback.

Does the SuperSocket API expose any way to allow this?
Coordinator
May 19, 2013 at 4:21 PM
It's a good point, currently SuperSocket doesn't support it. But it seems easy to implement.
Coordinator
May 21, 2013 at 4:47 PM
I have added the feature you asked in the master branch:
http://supersocket.codeplex.com/SourceControl/changeset/24ab8aab1c783e745b3a5833f8581003f299a0a3

What you should do:
1) override the AppServer's method "ValidateClientCertificate(xxxx)"
2) set the attribute "clientCertificateRequired" in the certificate config node to be "true"
May 22, 2013 at 12:05 PM
Wow, that was quick :)

I'll try this out later!
May 23, 2013 at 3:38 PM
Tried your changes and they work exactly as needed - many thanks for adding this functionality! (^_^)
Sep 24, 2013 at 10:31 PM
Hey Kerry,

I was wondering did these changes get removed as of the latest version? or did the procedure change? I can't seem to find it using a search "ValidateClientCertificate" through the entire source code solution.

Thanks for any and all help!
Coordinator
Sep 25, 2013 at 4:45 AM
It's included in SuperSocket 1.6 not in 1.5
Oct 2, 2013 at 2:40 AM
Hey Kerry,

Thanks for pointing me to 1.6, I was running a sample test build of the server with the clientCertificateRequired set to true, and the ValidateClientCertificate to be overridden and then I ran into an issue when a client tries to connect for some reason the stream becomes invalid, and the client can't process past the stream.AuthenticateAsClient("localhost") command.

This is the config file:
<configuration>
    <configSections>
        <section name="superSocket" type="SuperSocket.SocketEngine.Configuration.SocketServiceConfig, SuperSocket.SocketEngine"/>
    </configSections>
    <appSettings>
        <add key="ServiceName" value="CustomProtocolService"/>
    </appSettings>
    <superSocket>
        <servers>
             <server name="CustomProtocolServer" serverTypeName="CustomProtocolService"
                       ip="Any" port="2012" maxConnectionNumber="1000" security="tls">
                  <certificate storeName="TrustedPeople" thumbprint="8CE5D32E7C7667152B4D29A6D6E0883600C91591" clientCertificateRequired="true" />
             </server>
        </servers>
        <serverTypes>
            <add name="CustomProtocolService"
                 type="SuperSocket.QuickStart.CustomProtocol.CustomProtocolServer, SuperSocket.QuickStart.CustomProtocol" />
        </serverTypes>
    </superSocket>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
    </startup>
    <runtime>
        <gcServer enabled="true" />
    </runtime>
</configuration>
And this is the client sslstream test code:
var socketStream = new SslStream(new NetworkStream(socket), false, new RemoteCertificateValidationCallback(ValidateRemoteCertificate));
socketStream.AuthenticateAsClient("localhost");
               
Any ideas?
Coordinator
Oct 16, 2013 at 1:38 AM
I have no idea, I suggest you deep into the error/exception and review your client side code.

BTW, the documentation about client side certificate validation is updated:
http://docs.supersocket.net/v1-6/en-US/New-Features-and-Breaking-Changes#client-certificate-validation