I am looking for a way to retrieve the certificate chain of a targeted server. I already have code that lets me grab the server certificate that is presented when I connected, but I would also like the option of pulling each sub-certificate in the chain all the way to the root.
Here's the code I use to get the target server's public key. Unfortunately I wrote this back when I only knew VB.NET but I would prefer to have C# samples...
Private Function openSSLStream(ByRef server As ServerEntry) As SslStream
Dim sslStream As SslStream = Nothing
Dim newClient As New System.Net.Sockets.TcpClient
Try
newClient = New TcpClient
newClient.Connect(server.Name, server.Port)
sslStream = New SslStream(newClient.GetStream(), False, New RemoteCertificateValidationCallback(AddressOf ValidateServerCertificate), Nothing)
sslStream.AuthenticateAsClient(server.Name)
Return sslStream
Catch ex As Exception
Debug.WriteLine(ex.Message)
Return Nothing
Finally
If newClient.Connected Then newClient.Close()
End Try
End Function
Private Sub GetDetails(ByRef Server As ServerEntry)
Dim expcerdate As New Date
Dim newSSLstream As SslStream = openSSLStream(Server)
If Not newSSLstream Is Nothing Then
Dim newCertificate As New X509Certificate
Try
newCertificate = newSSLstream.RemoteCertificate()
expcerdate = CDate(newCertificate.GetExpirationDateString())
Server.Subject = newCertificate.Subject
newCertificate.GetPublicKeyString()
Server.ValidFrom = newCertificate.GetEffectiveDateString()
Server.ValidTo = newCertificate.GetExpirationDateString()
Catch ex As Exception
Server.Subject = ex.Message
Finally
newSSLstream = Nothing
newCertificate = Nothing
expcerdate = Nothing
End Try
End If
End Sub
The end result of this is that I have a local copy of the public key that I can save to the local drive. I would like to perform a similar task for each certificate in the chain so that I have a complete list of public certificates for a given target server.
For a look at the complete application as it is today you can download it from my site.