Support for overriding SSL certificate validation?

Jan 16, 2014 at 9:00 PM
This question is related to this existing discussion "RemoteCertificateChainError"
http://websocket4net.codeplex.com/discussions/346505

My application needs to embed a self-signed, trusted root certificate authority. I've tried to implement this support through the use of ServicePointManager.ServerCertificateValidationCallback, however this is not being called so I assume that WebSocket4Net doesn't make use of ServicePointManager.

Is there any way to override the way Websocket4Net validates server certificates? This seems to me to be a vital feature, as mobile apps in particular often use "certificate pinning" to bake validation for a specific certificate right into the app.
Jan 16, 2014 at 9:35 PM
Edited Jan 16, 2014 at 9:36 PM
Ok, I just dug though the ClientEngine code and I see that there isn't at present a way to override this behavior. On the plus side, I see that the ValidateRemoteCertificate() method does have the same method signature as ServicePointManager.ServerCertificateValidationCallback, and it should be pretty simple to add a property to allow users to override the behavior.

Kerry-- if this were to be made a feature request, any chance you'd be up to tackle the implementation sometime soon? It appears to be a super-simple and highly useful addition.

Thanks!!
Coordinator
Jan 17, 2014 at 2:04 AM
Does the property "AllowUnstrustedCertificate" of websocket work for you?

Make sure you do two things correctly:

1) the dns name of your websocket server must be equal with the certificate's CN
2) set the property AllowUnstrustedCertificate to be true
Jan 17, 2014 at 2:34 AM
Hi Kerry!

Thanks for responding so quickly. Unfortunately, it doesn't work in my case. I had hoped to use it at least as a temporary work around, but as a work around it fails since the certificates for my application aren't self-signed, but rather they are signed by an untrusted root.

The eventual solution I need will require the ability to inject an alternative method to SslStreamTcpSession.ValidateRemoteCertificate(), that would then check for a valid chain rooted with the CA certificate that I embed in my application.

Perhaps adding a SslStreamTcpSession.ServerCertificateValidationCallback property (analogous to ServicePointManager.ServerCertificateValidationCallback ), that if defined would be called instead of ValidateRemoteCertificate? Then expose the property in ClientEngine and WebSocket4Net?

Cheers!
Coordinator
Jan 17, 2014 at 3:06 AM
Ok, I'll try to expose an API for you.
Jan 17, 2014 at 2:16 PM
Thanks, Kerry! I really appreciate it. Should I create an issue?
Coordinator
Jan 18, 2014 at 4:38 AM
I have made a change, the validation will check ServicePointManager.ServerCertificateValidationCallback, if it has been set, we'll use it directly.

So you can set the callback ServicePointManager.ServerCertificateValidationCallback directly to fix your issue.

Please take a look at this commit:
https://clientengine.codeplex.com/SourceControl/changeset/9df634273516a1b35d9036b54a2a4cf781a15ca3
Jan 20, 2014 at 7:35 PM
This is great! Thanks so much!

Checking it out now...
Jan 21, 2014 at 5:53 PM
Kerry, your update works like a charm! Thanks again!