0

I have a application which accesses devices through HTTP or HTTPS. All these devices are on the internet and usually the customer gives us direct IP access with a firewall forwarding rule allowing only our external IP address in. I.e. the connection is relatively secure as only we are allowed access.

I want my application to check the site and see if it's using a valid certificate and if not give the user the option to save the certificate to the computers store so the device is trusted in the future. I do not want to blindly accept any certificate ( re: Accept self-signed TLS/SSL certificate in VB.NET ) but more download the certificate like this python example: How to get response SSL certificate from requests in python? . But I'm trying to do the equivalent in VB.Net

I also found this example using OpelSSL to get the certificate which I would consider if there is no other way to do this: https://www.baeldung.com/linux/ssl-certificates and also a decent example in Java: https://self-learning-java-tutorial.blogspot.com/2017/12/how-to-get-client-certificate-from.html but in both cases I'm having trouble getting that into a VB.Net way of doing it.

Another option is this one listed here Is it safe to test the X509Certificate.Thumbprint property when you know an invalid certificate is safe? where they are getting the thumbprint of a certificate and then comparing it against a known list. That would also work, I would get the thumbprint on the initial connection and store it with the device record and use that. But again I'm having trouble getting this into a workable format in VB.Net.

Does anyone have a idea of how I would go about this? Currently I'm doing my test using a simple WebRequest and looking for a status OK and if I don't get that checking the exception for the invalid certificate. I have gotten that far so I know when it is a site with a invalid certificate but now I need to figure out a way to save that information so I can connect to it in the future.

ADY
  • 101
  • 1
  • 9

1 Answers1

0

After more searching I figured this out. Here is my quick check to see if there is a valid cert and prompt to install it:

Try
    Dim request As HttpWebRequest = CType(WebRequest.Create(ServerAddressTextEdit.Text), HttpWebRequest)
    Dim response As HttpWebResponse = Nothing
    response = CType(request.GetResponse(), HttpWebResponse)
    Dim responseStatus As String = (CType(response, HttpWebResponse)).StatusDescription
    Debug.WriteLine(responseStatus) ' If the conection was good then we can just continue. 
Catch ex As Exception ' We have a exception.  Check for a invalid certificate or otherwise just let the user know.
    Debug.WriteLine(ex.Message)
    If ex.InnerException.Message Is Nothing Then
        ResultsMemoEdit.Text = "Connection to the device failed.  Reason given: " & ex.Message & vbCrLf
    Else
        If ex.InnerException.Message.Contains("The remote certificate is invalid according to the validation procedure") Then
            If MsgBox("The connection was sucessful however the site has a invalid SSL Certificate.  The program can attempt to download the invalid certificate and trust it for future communications.  Only do this if you trust the device for secure communications.  Do you want to do this?", MsgBoxStyle.YesNo, "Trust Invalid Certificate?") = MsgBoxResult.Yes Then
               Dim cert As X509Certificate = request.ServicePoint.Certificate
               Dim cert2 As New X509Certificate2(cert)
               Dim certData As Byte() = cert2.Export(X509ContentType.Cert)
               InstallCertificate(certData)
            End If
        End If
    End If
Finally
    If response IsNot Nothing Then response.Close()
End Try

Then the function to install it:

Private Function InstallCertificate(certData As Byte()) As Boolean
    Try
        Dim certificate As New X509Certificate2(certData)
        Dim store As New X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine)
        store.Open(OpenFlags.ReadWrite)
        store.Add(certificate)
        store.Close()
        Return True
    Catch ex As Exception
        Return False
    End Try
End Function

My program already runs as a admin so this all works. Will modify to allow the certificate name to be changed, probably using the device IP address, and also some extra checks to make sure the date is valid.

Now I have to get the computer to actually trust it as I'm still getting a error on connecting.

ADY
  • 101
  • 1
  • 9