Reputation: 917
I'm trying to call a webservice (not mine), Service-Referencing it within Visual Studio 2008. According to it's owner, it requires a certificate, which they kindly provided for testing purposes.
I'm an absolute newbie in certificates, SSL and else, so I could be doing something terribly wrong here. Anyways, this is what I did.
First, I registered the P12 file along with it's password (also provided) in my client machine. Then, I referenced the service using the Service Reference option in VS2008, and pointed to their URL (which, btw, uses a VPN tunnel) for it to be called within a windows form application. All of their underlying methods are recognized by the generated assemblies.
Here's the code I used:
WebServiceClient client = new WebServiceClient();
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly);
X509Certificate2 certificate = store.Certificates[0];
client.ClientCredentials.ClientCertificate.Certificate = certificate;
client.ReturnSomeData(); //Error here
At the last line, the following exception is thrown:
Could not establish trust relationship for the SSL/TLS secure channel with authority '<webservice URI here>'
The inner exceptions are the same 2 levels deep, and the third one is
The remote certificate is invalid according to the validation procedure
Problem is, I can call that very method using that very certificate at SoapUI, and data is returned.
Also, I've seen the Troubleshooting Marc Gravel posted here , so ...
The website's identity could not be confirmed
. I assumed it would be due to eh fact that we're using a VPN connection here. Is there a problem?Any help deeply appreciated.
Upvotes: 2
Views: 2440
Reputation: 917
I managed to receive the certificate directly importing it from the .p12 file. The following code
X509Certificate2 certificate = new X509Certificate2();
certificate.Import(@"<FilePath>",password,X509KeyStorageFlags.DefaultKeySet);
client.ClientCredentials.ClientCertificate.Certificate = certificate;
client.ReturnSomeData();
is successfull, so I'm sticking with this solution for now. It's not ideal, but seeing how urgent this matter is, I'm changing it later on.
Still not a definitive answer, though this might help whomever has a similar problem.
UPDATE
I think I figured out why this answers the question. So, as it turns out, something is still wrong with the way I retrieve the certificate from the store. Directly importing it ensures that the certificate is there, but a few extra steps were needed for the client to connect.
First, defining the transport mode in the binding.
<binding name="<bindingName>">
<security mode="Transport" >
<transport clientCredentialType="Certificate" />
</security>
</binding>
Secondly, ensuring that the ServerCertificateValidationCallBack
callback is doing the right validation. As bad as it seems,
ServicePointManager.ServerCertificateValidationCallback +=
(sender, x509Certificate, chain, errors) => true;
will work FOR NON-PRODUCTION PURPOSES.
Upvotes: 1
Reputation: 10747
To me it sounds like there is a trust issue. If the third party service gave you their certificate is probably the CA certificate and not the server certificate itself. Try to install the certificate within windows certificate store. There are plenty of tutorials if you look for them.
If the certificate that they gave you is self-signed then you need to add their CA certificate to the windows certificate store so that the system trusts the issuer and hence the server certificate is trusted as well.
Update: Here is another link with a tutorial to import a root CA and trust it, remember that it is not enough to import the certificate, you have to explicitly trust it, look at the bottom images on the link.
Upvotes: 0