Since HTTPS proxies will replace the SSL certificate with their own, what are my options to determine if a given HTTPS connection has a proxy in the middle?
I will use this information to determine my application policy, since there are cases where I want a 100% end-to-end encrypted tunnel with no decryption by any 3rd party.
Even better if you can tell me how to determine this via C# in a .NET application or Silverlight.
For starters, here is a sample method to validate a certificate using .NET, but I'm still not sure how to use this to determine what part of the cert to validate. In addition, I think the ServicePointManger is more of a "global" connection class. Using this may be too broad when I'm testing 开发者_Go百科a single HTTP connection, and I'm not sure if ServicePointManager is available within Silverlight.
http://msdn.microsoft.com/en-us/library/bb408523.aspx
You have a couple of options. The first option is to use the ServicePointManager class. You are correct in that it manages all service points, but you can use the "sender" parameter in the callback method to differentiate between the different service points:
void SomeMethod()
{
ServicePointManager.ServerCertificateValidationCallback +=
ValidateServerCertificate;
var url = "https://mail.google.com/mail/?shva=1#inbox";
var request = (HttpWebRequest)WebRequest.Create(url);
request.GetResponse();
}
private static bool ValidateServerCertificate(object sender,
X509Certificate certificate, X509Chain chain,
SslPolicyErrors sslpolicyerrors)
{
if(sender is HttpWebRequest)
{
var request = (HttpWebRequest) sender;
if(request.RequestUri.ToString() == "https://mail.google.com/mail/?shva=1#inbox")
{
return (certificate.GetPublicKeyString() == "The public key string you expect");
}
}
return true;
}
This option will work for manually-created HttpWebRequest and WCF-created requests, as the "sender" will be HttpWebRequest for both. I'm not sure if the "sender" will be anything other than an HttpWebRequest.
The second option is to get the certificate from the service point directly:
void SomeMethod()
{
ServicePointManager.ServerCertificateValidationCallback +=
ValidateServerCertificate;
var url = "https://mail.google.com/mail/?shva=1#inbox";
var request = (HttpWebRequest)WebRequest.Create(url);
request.GetResponse();
var serverCert = request.ServicePoint.Certificate;
// Validate the certificate.
}
I couldn't figure out if it's possible to get the ServicePoint used by a WCF proxy. If it's not possible, this option won't work for WCF. Other than that, the biggest difference is that the first option prevents the connection if the certificate validation fails, while the second method won't validate until after the connection has been made.
If you just need to determine if a request is going to pass through a proxy:
var httpRequest = (HttpWebRequest)WebRequest.Create("someurl");
var isUsingProxy = DoesRequstUseProxy(request);
bool DoesRequestUseProxy(HttpWebRequest request)
{
if(request.Proxy == null)
{
return false;
}
return request.Proxy.GetProxy(request.RequestUri) != request.RequestUri;
}
精彩评论