Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving certificate using OpenSSL .Net

Tags:

c#

.net

openssl

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?

like image 336
KenD Avatar asked May 10 '12 14:05

KenD


2 Answers

I think there are two parts to the question:

  1. How do you retrieve the server's certificate
  2. 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.

like image 156
Panagiotis Kanavos Avatar answered Sep 21 '22 20:09

Panagiotis Kanavos


Try using the ServicePointManager.ServerCertificateValidationCallback. That will be called with the server's X509 certificate et voila

http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.servercertificatevalidationcallback.aspx

like image 21
Dave Lawrence Avatar answered Sep 21 '22 20:09

Dave Lawrence