1

This has been bothering me for three days now and after tons of googling around I decided to post a question. I have a WCF service application ("local service") that connects to a "remote web service" (Java) securely (2-way certificate authentication).

My service-side config:

<system.serviceModel>
  <bindings>
      <basicHttpBinding>
          <binding name="IhAdapterPortBinding" closeTimeout="00:01:00"
              openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
              allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
              maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
              messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
              useDefaultWebProxy="true">
              <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
              <security mode="Transport">
                  <transport clientCredentialType="Certificate" proxyCredentialType="None"
                      realm="" />
                  <message clientCredentialType="UserName" algorithmSuite="Default" />
              </security>
          </binding>              
      </basicHttpBinding>
  </bindings>
  <client>
      <endpoint address="https://someserver.com:8085/IhAdapter" binding="basicHttpBinding"
          bindingConfiguration="IhAdapterPortBinding" contract="IHAdapter.IhAdapter"
          name="IhAdapterPort" behaviorConfiguration="IHAdapterEndpointBehavior" />       
  </client>
<services>
  <service name="SomeCompany.SomeService">
    <endpoint address="" binding="basicHttpBinding"
      contract="SomeCompany.ISomeService" />
  </service>
</services>
<behaviors>
  <endpointBehaviors>
    <behavior name="IHAdapterEndpointBehavior">
             <clientCredentials>
                  <clientCertificate storeLocation="LocalMachine" storeName="My" findValue="123...abc" x509FindType="FindByThumbprint"/>
                  <serviceCertificate>
                       <authentication certificateValidationMode="None" revocationMode="NoCheck"/>
                  </serviceCertificate>
             </clientCredentials>
        </behavior>
  </endpointBehaviors>
  <serviceBehaviors>
    <behavior name="">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

Now to the problem. When hosting the service in Visual Studio Web Development Server or calling the remote service from local test client (.exe), the call succeeds. But when the local service is IIS-hosted (localhost or some other server IIS), I get exception:

Could not establish secure channel for SSL/TLS with authority 'https://someserver.com:8085'

with Inner Exception:

The request was aborted: Could not create SSL/TLS secure channel.

What I tried or checked so far:

  • correct cert store location (Local Computer, not User)
  • Private Key Permissions (went to MMC, found cert, right click, All Tasks, Manage Private Key, set to all permissions to Everyone)
  • set the IIS application user (Connect As) to the local user with administrative privileges

One more thing: the current remote server cert is issued for another hostname, so I have to override the validation programmatically. So to create a remote service object in local service, I have theese lines of code:

ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
ServicePointManager.ServerCertificateValidationCallback = ((senderParam, certificate, chain, sslPolicyErrors) => true);

IHAdapter.IhAdapterClient ihAdapter = new IHAdapter.IhAdapterClient();

ihAdapter.SomeMethod(parameters); // the exception gets thrown here

What else could I be missing? Any ideas, pointers?

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
dabor
  • 127
  • 1
  • 3
  • 13
  • Is the server having a self signed certificate? Verify that the issuer of the service certificate is available in your cert store. If the service is using a self signed certificate you would need to override the ServiceCertificateValidation method that would bypass the server certificate validation – Rajesh Feb 20 '13 at 10:02
  • Seems to me that I have both of these set: issuer cert is in the server trust store, ServiceCertificateValidation is programmatically overridden. This looks like IIS issue, webdev server or standalone exe work ok. – dabor Feb 20 '13 at 17:22
  • IS your client certificate self signed as well? If yes then have you placed it in the Local Machine --> Trusted Store on the server – Rajesh Feb 21 '13 at 09:16
  • Client cert is not self signed and the remote server is not "ours". I think remote server trusts our server's cert because I can connect and call its methods from self hosted local service (exe). Problem exists only when local service is IIS hosted... – dabor Feb 21 '13 at 10:37
  • Can you try enabling tracing(http://msdn.microsoft.com/en-us/library/ms733025.aspx) on your service and see the inner stack for any exceptions. – Rajesh Feb 21 '13 at 18:02

2 Answers2

5

Ok, answering my own question.

Based on this link: How to give ASP.NET access to a private key in a certificate in the certificate store? I solved my problem.

The key to my solution was this check list:

  1. Create / Purchase certificate. Make sure it has a private key.
  2. Import the certificate into the "Local Computer" account. Best to use Certificates MMC. Make sure to check "Allow private key to be exported"
  3. Based upon which, IIS 7.5 Application Pool's identity use one of the following:
    • IIS 7.5 Website is running under ApplicationPoolIdentity. Using Certificates MMC, added "IIS AppPool\AppPoolName" to Full Trust on certificate in "Local Computer\Personal". Replace "AppPoolName" with the name of your application pool.
    • IIS 7.5 Website is running under NETWORK SERVICE. Using Certificates MMC, added "NETWORK SERVICE" to Full Trust on certificate in "Local Computer\Personal".
    • IIS 7.5 Website is running under "MyIISUser" local computer user account. Using Certificates MMC, added "MyIISUser" (a new local computer user account) to Full Trust on certificate in "Local Computer\Personal".

I almost surely did all of those things but obviously never all together at once. Hopefully this helps someone else. Thanks anyway for all the help.

Community
  • 1
  • 1
dabor
  • 127
  • 1
  • 3
  • 13
  • Thanks! Just what I neeeded! – Rikard Uppström Oct 28 '14 at 13:41
  • Just wanted to say I was diagnosing *precisely* the same problem and came across this answer - BINGO - essentially *zero* documentation or enlightenment on ANY aspect of this anywhere other than this five-year-old post. Thanks! – David W May 06 '22 at 14:07
0

I think all such messages are due to some machine in the chain (client, proxy, server) not "liking" a certificate for some reason.

To elaborate on what twk said, if you're using self-signed certificates, or your own CA, you need to install the signing cert in the trusted authorities store on the server at least, and possibly on the proxy.

Common problems I've encountered:

  • The certificate on the server is not signed by an authority that the PROXY or the CLIENT trusts
  • The certificate on the CLIENT is not signed by an authority that the PROXY or the SERVER trusts
  • Oops, I forgot to export the private key when I created the cert to be installed on the client
  • My process does not have read permissions to the private key on the client
  • The client certificate is password protected and I didn't specify credentials when reading the certificate.

For more visit Could not create SSL/TLS secure channel - Could the problem be a proxy server?

Community
  • 1
  • 1
Vandana
  • 161
  • 7
  • No proxy, direct network connection between servers. Local server trusts remote server's cert, permissions on cert are set to Everyone. – dabor Feb 20 '13 at 17:27