My C#.NET SSL connect works when I import the certificate manually in IE (Tools/Internet Options/Content/Certificates), but how can I load the certificate by code? Here is my code:
TcpClient client = new TcpClient(ConfigManager.SSLSwitchIP, Convert.ToInt32(ConfigManager.SSLSwitchPort));
SslStream sslStream = new SslStream(
client.GetStream(),
false,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
null
);
sslStream.AuthenticateAsClient("Test");
The above code works fine if i import my certificate file manually in Internet Explorer. But if i remove my certificate from IE and use the following code instead, i get Authentication exception:
sslStream.AuthenticateAsClient("Test", GetX509CertificateCollection(), SslProtocols.Default, false);
and here is the 'GetX509CertificateCollection' method :
public static X509CertificateCollection GetX509CertificateCollection()
{
X509Certificate2 certificate1 = new X509Certificate2("c:\\ssl.txt");
X509CertificateCollection collection1 = new X509CertificateCollection();
collection1.Add(certificate1);
return collection1;
}
What should I do to load my certificate dynamically?
To build upon owlstead's answer, here's how I use a single CA certificate and a custom chain in the verification callback to avoid Microsoft's store.
I have not figured out how to use this chain (
chain2
below) by default such that there's no need for the callback. That is, install it on the ssl socket and the connection will "just work". And I have not figured out how install it such that its passed into the callback. That is, I have to build the chain for each invocation of the callback. I think these are architectural defects in .Net, but I might be missing something obvious.The name of the function does not matter. Below,
VerifyServerCertificate
is the same callback asRemoteCertificateValidationCallback
. You can also use it for theServerCertificateValidationCallback
inServicePointManager
.I wrote another method to add my certificate to Trusted Root Certification Authorities (root) before attempting to authenticate as client via SSLStream object:
And then:
It works fine without any warnings or errors. But base question still remains unsolved:
How can I use a certificate to authenticate as client without installing it in Windows?
A quick Google pointed me to a piece of text from the Microsoft
SslStream
class.So simply implement the delegate and do the verification yourself.