Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clear any SSL Certificate data

I have a client - server setup. The client creates a proxy in order to communicate with the server. When the communication protocol is HTTPS the proxy listens for SSL certificate validation event via the following line:

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);

The ValidateRemoteCertificate method deals with Certificate exceptions.

In the client the user can select one of 3 security levels: low, medium and high. In low level the ValidateRemoteCertificate method ignores any errors and always return true. In Medium level the ValidateRemoteCertificate method fires an event that notifies the client of the problem. At this stage a message appears to the user informing him that the certificate is problematic and allows the user to select whether to continue and accept the connection with the server or decline. In High level the ValidateRemoteCertificate method declines the connection for any error.

So far so good.

The scenario is as follows:

  1. The client loads with a predefined security level of Medium which had already been accepted by the user and connection is established with the server without any certificate issues propagated.
  2. The user disconnects the client from the server (by a special button).
  3. The user attempts to reconnect the client. At this stage the client has the ability to test the connection via a test button. The test method returns success although a new proxy has been created for the connection test and all ValidateRemoteCertificate methods had been cleared from the ServerCertificateValidationCallback (of the specific proxy type). Also, no event is fired for the problematic certificate and the ValidateRemoteCertificate method is not called.

The behavior which I'm trying to achieve is that when the test is performed, the ServerCertificateValidationCallback will behave as if it's the first call to it after the client has been launched and the ValidateRemoteCertificate would come into play.

I tried looking for any method that clears any delegates / events in the ServicePointManager but I couldn't find any.

Is there a cache here that can be cleared? I hope the scenario is clear enough.

like image 808
owyn Avatar asked Jul 27 '11 14:07

owyn


People also ask

How do I remove old SSL certificates from Chrome?

In the top "Privacy and Security section, select "More". Scroll down and select "Manage Certificates". Select the certificate or certificates to delete, then click Remove. Click Yes in the Certificates warning box.

What happens if I clear my SSL state?

Clearing the SSL state eliminates the problems of caching certificates since it wipes out the cache. Doing this shouldn't be necessary in day-to-day computing, since resetting your computer or, in some cases, closing your browser, will also clear your SSL state.


1 Answers

I know it's been almost 4 years, but I just had this same issue and wanted to share my solution incase anyone else finds this.

I couldn't find any built in way to handle this, so looked at the source code of ServicePoint and ServicePointManager and here's what I came up with:

    public void EnsureNoServicePointCertificate(Uri uri)
    {
        // find the service point for the Uri
        ServicePoint sp = ServicePointManager.FindServicePoint(uri);
        // Check if there is a service point and there is a certificate
        if (sp != null && sp.Certificate != null)
        {
            try
            {
                // ServicePointManager has a hashtable (private static Hashtable s_ServicePointTable) of all service points
                Type servicePointType = sp.GetType();
                // ServicePoint.LookupString is the key for the hashtable
                PropertyInfo lookupStringProperty = servicePointType.GetProperty("LookupString", BindingFlags.Instance | BindingFlags.NonPublic);
                string lookupString = (string)lookupStringProperty.GetValue(sp, null);

                // Get the hashtable from ServicePointManager
                Hashtable s_ServicePointTable = (Hashtable)typeof(ServicePointManager).InvokeMember("s_ServicePointTable",
                    BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField, null, null, null);

                // ServicePointManager locks the hashtable and calls 
                // s_ServicePointTable.Remove(servicePoint.LookupString);
                lock (s_ServicePointTable)
                {
                    s_ServicePointTable.Remove(lookupString);
                }

                // At this point, ServicePointManager calls
                // servicePoint.ReleaseAllConnectionGroups();
                MethodInfo release = servicePointType.GetMethod("ReleaseAllConnectionGroups", BindingFlags.Instance | BindingFlags.NonPublic);
                release.Invoke(sp, null);
            }
            catch { }
        }
    }
like image 87
Ari Avatar answered Sep 22 '22 08:09

Ari