Nos enfrentamos a un problema similar al tratar de conectarnos a la API de negocios mediante SSL mutuo. Las bibliotecas .NET estándar no funcionan. Puede usar la biblioteca de terceros http://curl.haxx.se/libcurl/ como una de las posibles soluciones.
libcurl es una biblioteca libre y fácil de usar de transferencia de URL del lado del cliente, apoyando DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP , RTSP, SCP, SFTP, SMTP, SMTPS, Telnet y TFTP. libcurl admite certificados SSL, HTTP POST, HTTP PUT, carga de FTP, carga basada en formularios HTTP, proxies, cookies, autenticación de usuario + contraseña (Básico, Resumen, NTLM, Negociar, Kerberos), reanudación de transferencia de archivos, túnel proxy http y más.
biblioteca .NET se puede cargar desde http://sourceforge.net/projects/libcurl-net/
Al cargar cambia libcurl.dll a la última versión se puede encontrar (debe ser 7.18.1 o posterior). En el paquete libcurl-nel actual, es anterior a lo necesario.
public string HTTPGet(string URL, string Proxy, string certName = null, string certPassword = null)
{
Easy easy = new Easy();
SockBuff = "";
try
{
Easy.WriteFunction wf = new Easy.WriteFunction(OnWriteData);
easy.SetOpt(CURLoption.CURLOPT_URL, URL);
easy.SetOpt(CURLoption.CURLOPT_TIMEOUT, "60");
easy.SetOpt(CURLoption.CURLOPT_WRITEFUNCTION, wf);
easy.SetOpt(CURLoption.CURLOPT_USERAGENT, UserAgent);
easy.SetOpt(CURLoption.CURLOPT_COOKIEFILE, CookieFile);
easy.SetOpt(CURLoption.CURLOPT_COOKIEJAR, CookieFile);
easy.SetOpt(CURLoption.CURLOPT_FOLLOWLOCATION, true);
if (!string.IsNullOrEmpty(certName))
{
easy.SetOpt(CURLoption.CURLOPT_SSLCERT, certName);
if (!string.IsNullOrEmpty(certPassword))
{
easy.SetOpt(CURLoption.CURLOPT_SSLCERTPASSWD, certPassword);
}
}
if (URL.Contains("https"))
{
easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYHOST, 1);
easy.SetOpt(CURLoption.CURLOPT_SSL_VERIFYPEER, 0);
}
if (!string.IsNullOrEmpty(Proxy))
{
easy.SetOpt(CURLoption.CURLOPT_PROXY, Proxy);
easy.SetOpt(CURLoption.CURLOPT_PROXYTYPE, CURLproxyType.CURLPROXY_HTTP);
}
var code = easy.Perform();
easy.Cleanup();
Console.WriteLine(code);
}
catch
{
Console.WriteLine("Get Request Error");
}
return SockBuff;
}
public static Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb, Object extraData)
{
// Console.Write(System.Text.Encoding.UTF8.GetString(buf));
SockBuff = SockBuff + System.Text.Encoding.UTF8.GetString(buf);
return size * nmemb;
}
Sería de gran ayuda para conocer en detalles que las versiones de Windows .Net y que está utilizando, ya que el apoyo SNI dependerá de ellos. – Bruno
@Bruno Buen punto: he actualizado la pregunta. – TonyM
Parece que es posible que necesite una biblioteca externa en lugar de 'SslStream': http://connect.microsoft.com/VisualStudio/feedback/details/729925/net-4-4-5-sslstream-no-supports-the-tls-server-name-indication-sni – Bruno