2011-07-27 25 views
5

Tengo una configuración de servidor de cliente. El cliente crea un proxy para comunicarse con el servidor. Cuando el protocolo de comunicación es el proxy HTTPS procese el evento de validación del certificado SSL a través de la línea siguiente:Cómo borrar cualquier dato de certificado SSL

ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate); 

Los ValidateRemoteCertificate método trata de certificados excepciones.

En el cliente, el usuario puede seleccionar uno de los 3 niveles de seguridad: bajo, medio y alto. En el nivel bajo, el método ValidateRemoteCertificate ignora cualquier error y siempre devuelve verdadero. En el nivel medio, el método ValidateRemoteCertificate activa un evento que notifica al cliente del problema. En esta etapa, aparece un mensaje para el usuario que le informa que el certificado es problemático y le permite al usuario seleccionar si desea continuar y aceptar la conexión con el servidor o declinar. En nivel alto, el método ValidateRemoteCertificate rechaza la conexión por cualquier error.

Hasta ahora todo bien.

El escenario es el siguiente:

  1. Las cargas de cliente con un nivel de seguridad predefinido de media que ya había sido aceptado por el usuario y se establece la conexión con el servidor sin ningún problema de certificado propagadas.
  2. El usuario desconecta el cliente del servidor (mediante un botón especial).
  3. El usuario intenta volver a conectar el cliente. En esta etapa, el cliente tiene la capacidad de probar la conexión a través de un botón de prueba. El método de prueba devuelve éxito, aunque se ha creado un nuevo proxy para la prueba de conexión y todos los métodos ValidateRemoteCertificate se han borrado de ServerCertificateValidationCallback (del tipo de proxy específico). Además, no se activa ningún evento para el certificado problemático y no se llama al método ValidateRemoteCertificate.

La conducta que yo estoy tratando de lograr es que cuando se realiza el examen, el ServerCertificateValidationCallback se comportará como si fuera la primera llamada a la misma vez que el cliente ha puesto en marcha y el ValidateRemoteCertificate entraría en juego.

Intenté buscar cualquier método que elimine cualquier delegado/evento en el ServicePointManager pero no pude encontrar ninguno.

¿Hay un caché aquí que se pueda borrar? Espero que el escenario sea lo suficientemente claro.

Respuesta

4

Sé que han pasado casi 4 años, pero tuve este mismo problema y quería compartir mi solución en caso de que alguien más encuentre esto.

no pude encontrar ninguna construido en forma de manejar esto, por lo visto en el código fuente de ServicePoint y ServicePointManager y esto es lo que ocurrió:

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 { } 
     } 
    } 
Cuestiones relacionadas