Trying to do basic SSL-authenticated Web Service using Visual Studio 2008 .NET 3.5 "Service Reference" object created from WSDL. We have tried three methods 1) Setting Client Certificates (to match server-supplied), 2) setting store for server-supplied, and 3) using custom server validator.
The .NET exception (detailed below) is consistent (for three methods described below) "Could not establish trust relationship for the SSL/TLS secure channel with authority 'ABC.DEF.com'."
Ethereal capture is consistent (for three methods described below) and shows what looks like correct Client and Service handshaking for the SERVER-SUPPLIED certificate version of SSL. That is, we see all the basic message described here (http://en.wikipedia.org/wiki/Transport%5FLayer%5FSecurity#Simple%5FTLS%5Fhandshake):
Client --> Server: Client Hello
Server --> Client: Server Hello, Certificate, Server Hello Done
Client --> Server: Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
Server --> Client: Change Cipher Spec, Encrypted Handshake Message.
After receipt of last (which we assume to be the SSL MAC message), Client immediately closes (TCP FIN/ACK) connection
1) Attempt at setting client credentials using what the server has supplied (w/ the expectation that the X509 library will use this to validate what the server is supplying during SSL negotiation, but w/ the understanding that this could very well be meant only to be supplied from client to server during client-supplied certificate negotiation)
X509Certificate2 _cert = new X509Certificate2("\\SomePath\...\ServerSuppliedCert.cer");
getPrequalInfo_v1 _getInfo = new getPrequalInfo_v1(); // WEB SERVICE-SPECIFIC
_getInfo.arg0 = GetRequestArgs(); // WEB SERVICE-SPECIFIC
PreQualBeanClient _preq = new PreQualBeanClient(); // WEB SERVICE-SPECIFIC
_preq.ClientCredentials.ClientCertificate.Certificate = _cert;
getPrequalInfo_v1Response _resp = new getPrequalInfo_v1Response(); // WEB SERVICE-SPECIFIC
_resp = _preq.getPrequalInfo_v1(_getInfo); // << EXCEPTION RAISED HERE, // WEB SERVICE-SPECIFIC
2) Attempting to create store for ostensible use of validating service certificate (again, could totally be wrong approach)
X509Certificate2Collection _collection = new X509Certificate2Collection();
_store = new X509Store(StoreLocation.CurrentUser);
_store.Open(OpenFlags.ReadOnly);
X509Certificate2 _cert = new X509Certificate2("\\SomePath\...\ServerSuppliedCert.cer");
_collection.Add(_cert);
_store.AddRange(_collection);
_store.Close();
getPrequalInfo_v1 _getInfo = new getPrequalInfo_v1(); // WEB SERVICE-SPECIFIC
_getInfo.arg0 = GetRequestArgs(); // WEB SERVICE-SPECIFIC
PreQualBeanClient _preq = new PreQualBeanClient(); // WEB SERVICE-SPECIFIC
_preq.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode
= System.ServiceModel.Security.X509CertificateValidationMode.PeerOrChainTrust;
_preq.ClientCredentials.ServiceCertificate.Authentication.TrustedStoreLocation = _store.Location;
getPrequalInfo_v1Response _resp = new getPrequalInfo_v1Response(); // WEB SERVICE-SPECIFIC
_resp = _preq.getPrequalInfo_v1(_getInfo); // << EXCEPTION RAISED HERE, // WEB SERVICE-SPECIFIC
3) Here we have tried to create a customer service credential validator. NOTE that in this case the MyX509CertificateValidator.Validate method does NOT appear to be called at all.
getPrequalInfo_v1 _getInfo = new getPrequalInfo_v1(); // WEB SERVICE-SPECIFIC
_getInfo.arg0 = GetRequestArgs(); // WEB SERVICE-SPECIFIC
PreQualBeanClient _preq = new PreQualBeanClient(); // WEB SERVICE-SPECIFIC
_preq.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode
= System.ServiceModel.Security.X509CertificateValidationMode.Custom;
_preq.ClientCredentials.ServiceCertificate.Authentication.CustomCertificateValidator
= new MyX509CertificateValidator("Name");
getPrequalInfo_v1Response _resp = new getPrequalInfo_v1Response(); // WEB SERVICE-SPECIFIC
_resp = _preq.getPrequalInfo_v1(_getInfo); // << EXCEPTION RAISED HERE, // WEB SERVICE-SPECIFIC
We have the following relevant part of the WSDL
<soap:address location='https://ABC.DEF.com/.../PreQualBean'/>
.NET Exception, which is common to the three methods described:
System.ServiceModel.Security.SecurityNegotiationException was unhandled
Message="Could not establish trust relationship for the SSL/TLS secure channel with authority 'ABC.DEF.com'."
Source="mscorlib"
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
...
w/ inner exception
InnerException: System.Security.Authentication.AuthenticationException
Message="The remote certificate is invalid according to the validation procedure."
Source="System"
StackTrace:
at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
...