2012-02-29 22 views
5

Escribí un programa C# que usa HttpWebRequest para conectarme a un sitio HTTPS. El método GetResponse() lanza una excepción:Cómo agregar un certificado de CA confiable (NO un certificado de cliente) a HttpWebRequest?

SystemError: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

soy capaz de conectarse a la misma página web utilizando curl.exe --cacert CAFile.pem. Me gustaría poder usar los mismos certificados de CA confiables del programa C#.

¿Cómo puedo obtener HttpWebRequest para usar este archivo de certificado CA (o un X509CertificateCollection que contiene los certificados analizados)?

Respuesta

6

Intente configurar su ServerCertificateValidationCallback utilizar este:

public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) 
{ 
    if (sslPolicyErrors == SslPolicyErrors.None) 
    return true; 

    X509Chain privateChain = new X509Chain(); 
    privateChain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; 

    X509Certificate2 cert2 = new X509Certificate2(certificate); 
    X509Certificate2 signerCert2 = new X509Certificate2(@"C:\MyCACert.PEM"); 

    privateChain.ChainPolicy.ExtraStore.Add(signerCert2);  
    privateChain.Build(cert2); 

    bool isValid = true; 

    foreach (X509ChainStatus chainStatus in privateChain.ChainStatus) 
    { 
     if (chainStatus.Status != X509ChainStatusFlags.NoError) 
     { 
      isValid = false; 
      break; 
     } 
    } 

    return isValid; 
} 

No he tenido la oportunidad de probar esto, así que me haga saber si se produce algún error y voy a modificar la respuesta si es necesario.

+0

Gracias, lo intentarán mañana – ThiefMaster

1

La solución que finalmente implementado fue escribir una clase que implementa ICertificatePolicy con la lógica de validación personalizada:

private X509CertificateCollection _certs; 
private ICertificatePolicy   _defaultPolicy; 

public bool CheckValidationResult(ServicePoint svcPoint, X509Certificate cert, WebRequest req, int problem) 
{ 
    if ((_defaultPolicy != null) && _defaultPolicy.CheckValidationResult(svcPoint, cert, req, problem)) 
    { 
     return true; 
    } 

    foreach (X509Certificate caCert in _certs) 
    { 
     if (caCert.Equals(cert)) 
     { 
      return true; 
     } 
    } 

    return false; 
} 

(Comprobación de errores omitidos por razones de brevedad.)

_defaultPolicy se puede configurar para ServicePointManager.CertificatePolicy para permitir que el almacén de certificados predeterminado que se utilizará además de los certificados personalizados.

_certs contiene el certificado adicional (s). Se genera analizando el archivo PEM y llamando al _certs.Add(new X509Certificate(Convert.FromBase64String(base64cert)));

CertificatePolicy ha sido obsoleto por ServerCertificateValidationCallback, pero necesitaba una versión anterior de .NET.

Cuestiones relacionadas