Could not establish trust relationship with remote server.
When you use HTTPS for your web services, you may get a System.Net.WebException that, "The underlying connection was closed: Could not establish trust relationship with remote server." This indicates that the client is unable to negotiate a secure connection with the server.
Try visiting the URL of your web service with IE. You will likely get a Security Alert message box warning about one or more of the following:
1) The certificate is not from a trusted authority. This happens if the issuing authority is not trusted by the Certificate Manager. For testing, you can issue your own certificates and add yourself to the trusted authorities list. For production, you should probably buy a certificate.
2) The date on the certificate is invalid. The certificate's dates don't match those on the client computer. If this happens only on some computers, check that the clock on the offending computers is set to the right day.
3) The name on the certificate does not match the name of the site. Most certificates are issued with a www prefix; for example:
www.yahoo.com. If your web service is hosted on a named server, (daffy.yahoo.com) you will get this warning. I understand you can buy wildcard certificates that accept any server name, but I've never used them.Once you know the problem, you can decide to fix it, or ignore it when establishing the connection. The following class shows how to selectively ignore any CertificateProblems that you choose. Use this carefully, as establishing a secure connection to an attacker's server is worse than sending data in the clear.
using System;
using System.Net;
using System.Security.Cryptography.X509Certificates;
namespace Graham.Utilities
{
public class AcceptServerNameMismatch : ICertificatePolicy
{
// HACK: This is a workaround. The .NET Framwork should expose these, but they don't.
public enum CertificateProblem : long
{
CertEXPIRED = 2148204801,
CertVALIDITYPERIODNESTING = 2148204802,
CertROLE = 2148204803,
CertPATHLENCONST = 2148204804,
CertCRITICAL = 2148204805,
CertPURPOSE = 2148204806,
CertISSUERCHAINING = 2148204807,
CertMALFORMED = 2148204808,
CertUNTRUSTEDROOT = 2148204809,
CertCHAINING = 2148204810,
CertREVOKED = 2148204812,
CertUNTRUSTEDTESTROOT = 2148204813,
CertREVOCATION_FAILURE = 2148204814,
CertCN_NO_MATCH = 2148204815,
CertWRONG_USAGE = 2148204816,
CertUNTRUSTEDCA = 2148204818
}
/// <summary>
/// Implement CheckValidationResult to ignore problems that we are willing to accept.
/// </summary>
public bool CheckValidationResult(ServicePoint sp, X509Certificate cert,
WebRequest request, int problem)
{
int CertificateNameDoesntMatch = unchecked( (int) CertificateProblem.CertCN_NO_MATCH);
if ( problem == CertificateNameDoesntMatch ) // only accept server name failed match
return true;
// The 1.1 framework calls this method with a problem of 0, even if nothing is wrong
return (problem == 0);
}
}
}