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:
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.
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.
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.
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 { }
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With