G
Guest
When I try to connect to a specific HTTPS website, I'm receiving the following error WebException message:
"The underlying connection was closed: Could not establish secure channel for SSL/TLS."
System Information:
1. Windows XP Professional SP1
2. Visual Studio 2003
3. NET Framework 1.1.4322
Important Notes:
1. The above error occurs ONLY when I attempt to access "https://adwords.google.com/".
2. I can connect/download using an HttpWebRequest/WebClient using HTTPS from many other websites without problems.
2. Google is using the following ROOT certificate: "Thawte Server CA" which expires 12/31/2020.
3. Google seems to be requiring some sort of "client cert". I tried doing some test on my localmachine's IIS, and HTTPS access worked great with my app, until I required "Client Certificates" at which point, I got the above error message. However, I could no longer navigate to https://localhost/ without IE fussing about Client Certs either.
4. I can navigate to Google's URL using IE, Netscape, Opera without any problems (no warning messages).
5. I have turned on schannel event logging (level 7) - and it only succeeds - no failure messages.
6. SChannel registers this when navigating (with IE) to https://adwords.google.com:
"Creating an SSL client credential"
and then about 6 of these:
"An SSL client handshake completed successfully. The negotiated cryptographic parameters are as follows." (and a bunch of ssl stuff)
Which seems normal.
7. When navigating to Google using my C# console app, I only get the first message: "Creating an SSL client credential" and no errors.
8. IE browser does NOT issue any warning when navigating to Google - the certificate is valid.
9. The CheckValidationResult method of a custom ICertificatePolicy class (assigned to the ServicePointManager) is never even reached in code.
10. Doing a "GET" or "POST" does not matter.
11. I am an Administrator on my local machine (no domain) - accessing the Key Store isn't a problem - I've got permission and so does the console app that's having problems.
12. I am not using a proxy server and I am not behind a firewall.
ANY IDEAS??????????
Code:
namespace Adwords {
public class MainProgram {
public static void Main() {
new MainProgram();
System.Console.WriteLine("Done...");
System.Console.ReadLine();
}
public MainProgram() {
string strUrl = "https://adwords.google.com/select/"; //fails
//string strUrl = "https://adwords.google.com/"; //also fails
//string strUrl = "https://www.thawte.com/buy/"; //works fine
//string strUrl = "https://www.paypal.com/"; //works fine (Verisign Cert - but other posts I read on the net had probs)
System.Net.HttpWebRequest httpWebRequest =
(System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(strUrl);
System.Net.ServicePointManager.CertificatePolicy = new //tried with & w/o - doesn't matter
AcceptAllCerts(); //see class below
string strThawteCert = @"C:\Thawte.cer"; //Thawte's public key
httpWebRequest.ClientCertificates.Add( //tried with & w/o - doesn't matter
//even if we export the Thawte cert, we will only have the
//public key - if Google requires "client certificates", we will never
//get the private key from Thawte. Does IE generate its own cert private key on the fly?
//if so, is there some point in the handshake that we can intercept in code and add one?
System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile(strThawteCert)
);
httpWebRequest.UserAgent = ""; //tried with & w/o - doesn't matter
httpWebRequest.Method = "GET"; //tried "GET" / "POST" - doesn't matter
httpWebRequest.AllowAutoRedirect = true; //tried true/false - doesn't matter
//FAILS USING THIS (optional - to write post data ONLY when using Method = "POST")
//System.IO.Stream streamRequest = httpWebRequest.GetRequestStream(); //this line of code will fail when going to Google
//streamRequest.Write(/* form post data*/);
//streamRequest.Close();
//OR THIS (required - to read response from server)
System.Net.HttpWebResponse httpWebResponse =
(System.Net.HttpWebResponse)httpWebRequest.GetResponse(); //this line of code will fail when going to Google
//note that if we get the RequestStream - it will fail at that line of code
//if we ignore the RequestStream and go straight to the GetResponse, it will fail at the GetResponse line
}
}
public class AcceptAllCerts : System.Net.ICertificatePolicy {
public AcceptAllCerts() {
}
public bool CheckValidationResult(
System.Net.ServicePoint servicePoint,
System.Security.Cryptography.X509Certificates.X509Certificate cert,
System.Net.WebRequest webRequest,
int iProblem)
{
//this line of code is never hit
return true;
}
}
}
"The underlying connection was closed: Could not establish secure channel for SSL/TLS."
System Information:
1. Windows XP Professional SP1
2. Visual Studio 2003
3. NET Framework 1.1.4322
Important Notes:
1. The above error occurs ONLY when I attempt to access "https://adwords.google.com/".
2. I can connect/download using an HttpWebRequest/WebClient using HTTPS from many other websites without problems.
2. Google is using the following ROOT certificate: "Thawte Server CA" which expires 12/31/2020.
3. Google seems to be requiring some sort of "client cert". I tried doing some test on my localmachine's IIS, and HTTPS access worked great with my app, until I required "Client Certificates" at which point, I got the above error message. However, I could no longer navigate to https://localhost/ without IE fussing about Client Certs either.
4. I can navigate to Google's URL using IE, Netscape, Opera without any problems (no warning messages).
5. I have turned on schannel event logging (level 7) - and it only succeeds - no failure messages.
6. SChannel registers this when navigating (with IE) to https://adwords.google.com:
"Creating an SSL client credential"
and then about 6 of these:
"An SSL client handshake completed successfully. The negotiated cryptographic parameters are as follows." (and a bunch of ssl stuff)
Which seems normal.
7. When navigating to Google using my C# console app, I only get the first message: "Creating an SSL client credential" and no errors.
8. IE browser does NOT issue any warning when navigating to Google - the certificate is valid.
9. The CheckValidationResult method of a custom ICertificatePolicy class (assigned to the ServicePointManager) is never even reached in code.
10. Doing a "GET" or "POST" does not matter.
11. I am an Administrator on my local machine (no domain) - accessing the Key Store isn't a problem - I've got permission and so does the console app that's having problems.
12. I am not using a proxy server and I am not behind a firewall.
ANY IDEAS??????????
Code:
namespace Adwords {
public class MainProgram {
public static void Main() {
new MainProgram();
System.Console.WriteLine("Done...");
System.Console.ReadLine();
}
public MainProgram() {
string strUrl = "https://adwords.google.com/select/"; //fails
//string strUrl = "https://adwords.google.com/"; //also fails
//string strUrl = "https://www.thawte.com/buy/"; //works fine
//string strUrl = "https://www.paypal.com/"; //works fine (Verisign Cert - but other posts I read on the net had probs)
System.Net.HttpWebRequest httpWebRequest =
(System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(strUrl);
System.Net.ServicePointManager.CertificatePolicy = new //tried with & w/o - doesn't matter
AcceptAllCerts(); //see class below
string strThawteCert = @"C:\Thawte.cer"; //Thawte's public key
httpWebRequest.ClientCertificates.Add( //tried with & w/o - doesn't matter
//even if we export the Thawte cert, we will only have the
//public key - if Google requires "client certificates", we will never
//get the private key from Thawte. Does IE generate its own cert private key on the fly?
//if so, is there some point in the handshake that we can intercept in code and add one?
System.Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile(strThawteCert)
);
httpWebRequest.UserAgent = ""; //tried with & w/o - doesn't matter
httpWebRequest.Method = "GET"; //tried "GET" / "POST" - doesn't matter
httpWebRequest.AllowAutoRedirect = true; //tried true/false - doesn't matter
//FAILS USING THIS (optional - to write post data ONLY when using Method = "POST")
//System.IO.Stream streamRequest = httpWebRequest.GetRequestStream(); //this line of code will fail when going to Google
//streamRequest.Write(/* form post data*/);
//streamRequest.Close();
//OR THIS (required - to read response from server)
System.Net.HttpWebResponse httpWebResponse =
(System.Net.HttpWebResponse)httpWebRequest.GetResponse(); //this line of code will fail when going to Google
//note that if we get the RequestStream - it will fail at that line of code
//if we ignore the RequestStream and go straight to the GetResponse, it will fail at the GetResponse line
}
}
public class AcceptAllCerts : System.Net.ICertificatePolicy {
public AcceptAllCerts() {
}
public bool CheckValidationResult(
System.Net.ServicePoint servicePoint,
System.Security.Cryptography.X509Certificates.X509Certificate cert,
System.Net.WebRequest webRequest,
int iProblem)
{
//this line of code is never hit
return true;
}
}
}