2

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 ...

  1. Do you have DNS and line-of-sight to the server? Yes
  2. Are you using the correct name from the certificate? Yes, I checked it with Immediate.
  3. Is the certificate still valid? Hopefully. If SoapUI accepted it, I guess it is? (Really have my doubts here)
  4. Is a badly configured load balancer messing things up? Also doesn't explain SoapUI's behaviour.
  5. Does the new server machine have the clock set correctly (i.e. so that the UTC time is correct [ignore local time, it is largely irrelevent]) - this certainly matters for WCF, so may impact regular SOAP? Dunno if appliable.
  6. Is there a certificate trust chain issue? if you browse from the server to the soap service, can you get SSL? Actually, there is. Chrome reports that 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?
  7. Is the server's machine-level proxy set correctly? (which different to the user's proxy); see proxycfg for XP / 2003 (not sure about Vista etc) Again, won't explain SoapUI's behaviour.

Any help deeply appreciated.

Community
  • 1
  • 1
Eric Wu
  • 908
  • 12
  • 35
  • Check your webservice SSL version and set your `ServicePointManager.SecurityProtocol` appropriately. – Hamlet Hakobyan Jan 26 '16 at 20:14
  • Is that property a server-specific configuration? Because it's not mine. – Eric Wu Jan 27 '16 at 11:54
  • No, it should be set in your client application, in C# code. – Hamlet Hakobyan Jan 27 '16 at 12:35
  • In step 6 above - if you repeat the test with IE, what does IE say? Also, is the code above running with your permissions, or service (different user) permissions? – jglouie Jan 27 '16 at 12:41
  • @jglouie It reports that "There's a problem in the website's security certificate" and that it "was not issued by a reliable certification authority". – Eric Wu Jan 27 '16 at 13:07
  • @HamletHakobyan `ServicePointManager` seems to be a static class that doesn't leave that property visible. How do I set it? – Eric Wu Jan 27 '16 at 13:07
  • @EricWu How are you trusting the issuer? Are you doing it through the MMC? If so, are you importing them into the Trusted Root Certificates for "My user account", "Service account", or "Computer account?" – jglouie Jan 28 '16 at 01:44
  • @jglouie, I used MMC, and I imported it to Trusted Root Certificates, under "Computer Account". – Eric Wu Jan 28 '16 at 15:33
  • @EricWu Are you running the client application as yourself? If so, could you try to use the "My user account" store instead? – jglouie Jan 28 '16 at 23:52
  • @jglouie, sorry for the last response. The certificate is already under "My user account" store. Do I try to remove it from the "Computer Account"? – Eric Wu Feb 01 '16 at 16:59

2 Answers2

1

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.

Eric Wu
  • 908
  • 12
  • 35
0

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.

Gustavo Rubio
  • 10,209
  • 8
  • 39
  • 57
  • Thanks for the answer, @GustavoRubio. I installed the certificate within the store as directed by the link you provided. The error persists. I also checked if it was self-signed, and the IssuerName differs from the SubjectName. Does that suffice to say it is not? – Eric Wu Jan 27 '16 at 12:22
  • @EricWu It depends, usually a "self-signed" certificate means that the CA (Certificate Authority) is not one of those in the "known authorities" by browsers, operative systems and such, like verisign, thawte, comodo, etc. If the issuer of the cert is the company you are working with than chances are it is a self-signed certificate indeed. Who is the Issuer of the cert that you were given? – Gustavo Rubio Jan 27 '16 at 20:23
  • Just checked it. Indeed, the issuer is not a 'known authority'. I was confused at first, since the Issuer was being reported as another company, and I just found out it's the very same (just another fantasy name). – Eric Wu Jan 27 '16 at 20:56
  • That being said, I did import (successfully) it at Trusted Root Certificates Authorities, so it should be recognized as a... trusted authority, right? – Eric Wu Jan 27 '16 at 21:00
  • Yes, but you also need to set it as "trusted" so that when you make requests the channel that pulls the server certificate knows that the authority is trusted and you don't get the warning – Gustavo Rubio Jan 27 '16 at 21:03
  • I still don't get how I can set it to "trusted" other than simply importing it to TRC. Can you provide further instructions? – Eric Wu Feb 01 '16 at 17:30
  • thanks for you answer. I did all the steps your link provided, and then, the remote certificate was deemed invalid. >.< Considering I can override the `ServicePointManager.ServerCertificateValidationCallback`, and I did (again, for testing purposes), and that the exception shifted to `The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was ''."`, does that mean that the original question was solved? – Eric Wu Feb 03 '16 at 11:02
  • @EricWu What you could try is going within the browser to the URI of the webservice that you need to call, you may get an error from the service, yes (wrong gateway, method, etc.) but if you check the icon on the browser bar you should still get the httpS cert info as valid, if you are not then something is still wrong with the CA – Gustavo Rubio Feb 03 '16 at 20:32