tags:

views:

144

answers:

1

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.

A: 

I did some digging and found the answer I needed in the X509Chain and X509Certificate2 call. I'm not going to post the entire code but here's the most relevant portion:

Dim cert2 As X509Certificate2
Dim ch As New X509Chain()
ch.Build(cert2)

Dim element As X509ChainElement

For Each element In ch.ChainElements
    blob = element.Certificate.RawData()
Next Element
Dscoduc