Retrieving certificate using OpenSSL .Net
.net, c#, openssl
Solution
I think there are two parts to the question:
- How do you retrieve the server's certificate
- How do you retrieve the certificate's chain
To rertrieve the server's certificate you use SslStream whose methods are similar to .NET's own SslStream
var serverName = "...;
var client = new TcpClient(serverName, 443);
// Create an SSL stream that will close the client's stream.
using (var sslStream = new SslStream(client.GetStream(),true))
{
sslStream.AuthenticateAsClient(serverName);
var serverCertificate = sslStream.RemoteCertificate;
}
It seems that OpenSSL.Net can't retrieve a certificate's chain. The -showcerts parameter uses the SSL_get_peer_cert_chain function which is not implemented in OpenSSL.NET.
If you don't mind mixing OpenSSL.Net and the built-in .NET classes, you can convert an OpenSSL.Net certificate to a .NET certificate and retrieve the chain using .NET's X509Chain.Build . You can convert the .NET certificates back to OpenSSL.NET certificates using the .NET certificate's RawData property.
var managedCert = new System.Security.Cryptography.X509Certificates.X509Certificate2(serverCertificate.DER);
var chain = new System.Security.Cryptography.X509Certificates.X509Chain();
chain.Build(managedCert);
foreach (var element in chain.ChainElements)
{
var raw = element.Certificate.RawData;
using (var bio = new BIO(raw))
{
var oc = OpenSSL.X509.X509Certificate.FromDER(bio);
}
}
Perhaps you can use .NET's SslStream and X509Certificate2 object to do what you want using the raw certificate data without using OpenSSL.Net at all.
Problem
I'd like to use the OpenSSL .Net wrapper to retrieve a certificate from a remote server to my C# code. Essentially, I'd like to replicate ``` openssl s_client -connect 192.168.254.13:636 -showcerts ``` .. and ultimate bring the results into an X509Certificate. Is this possible, and if so can anyone point me in the right direction?