4

I’m trying to make a wcf client and server (self hosted) with ssl (transport security) both ways - server certificate and client certificate.

In windows XP everything works, but in Windows 7 it failed with client certificate. If the server is on winXp, and the client is on win7 – it’ll work, the opposite – it won’t work.

Here is app.config of the server:

<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>         
        </behavior>
        <behavior name="NewBehavior1">
          <serviceMetadata httpsGetEnabled="true"/>
          <serviceCredentials>
            <serviceCertificate findValue="ServerCert" storeName="My" x509FindType="FindBySubjectName" />
            <clientCertificate>
              <authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck" trustedStoreLocation="LocalMachine" />
            </clientCertificate>
            <windowsAuthentication allowAnonymousLogons="True"/>
          </serviceCredentials>

        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <basicHttpBinding>
        <binding name="Binding1">
          <security mode="Transport">
           <transport clientCredentialType="Certificate" proxyCredentialType="None" realm=""/>
          </security>
        </binding>
      </basicHttpBinding>

    </bindings>
    <services>
      <service behaviorConfiguration="NewBehavior1"
            name="Service.Calc">
        <endpoint
          address="https://172.18.96.116:8413/MyCalcService1"
          binding="basicHttpBinding"
          bindingConfiguration="Binding1"
          name="TestWCFService.Http"
          contract="Contarcts.ICalc" />
        <host>
          <baseAddresses>
            <add baseAddress="https://172.18.96.116:8413/MyCalcService1" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>

</configuration>

Client:

<system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="clientBehavior1">
          <clientCredentials>
            <clientCertificate findValue="ClientCert"
                 storeLocation="LocalMachine"
                 storeName="My"
                 x509FindType="FindBySubjectName" />
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>

    <bindings>
      <basicHttpBinding>
        <binding name="TestWCFService.Http1">
          <security mode="Transport">
          <transport clientCredentialType="Certificate" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="https://172.18.96.116:8413/MyCalcService1"
      binding="basicHttpBinding"
      bindingConfiguration="TestWCFService.Http1"
      contract="CalcProxy.ICalc"
      name="TestWCFService.WSHttp1"
      behaviorConfiguration="clientBehavior1"
      />
    </client>
  </system.serviceModel>

Server’s code:

ServiceHost calcHost = new ServiceHost(typeof(Calc));
calcHost.Open();

Client’s code:

System.Net.ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);


CalcClient proxy = new CalcClient();
int res = proxy.Add(2, 4);

My makecert commands are:

makecert -sv SignRoot.pvk -cy authority -r MyCA.cer -a sha1 -n "CN=MyCA" -ss my -sr localmachine

makecert -iv SignRoot.pvk -ic MyCA.cer -cy end -pe -n CN="ClientCert" -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localmachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12

makecert -iv SignRoot.pvk -ic MyCA.cer -cy end -pe -n CN="ServerCert" -eku 1.3.6.1.5.5.7.3.2 -ss my -sr localmachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12

I also validated that the ca is in the right location (Local computer - Trusted root CA), and the server/client certificates also in the right location (Local computer - Personal).

The private keys can be exportable and I validated that “Everyone” has permissions to private keys (C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys).

It works via fiddler.


The errors I get from SvcTraceViewer:

Client side - The HTTP request was forbidden with client authentication scheme 'Anonymous'.

Server side - Client certificate is required. No certificate was found in the request.

Error from http trace: Attempt by server application to receive client certificate failed with status: 0xC0000225.

Similar problem I’ve found, but I still stuck though: .NET application fails to send client certificate - Win 7 vs Win XP?

How can I make it work on Windows 7?

Thanks.

Community
  • 1
  • 1
programozo
  • 41
  • 1
  • 2

1 Answers1

1

Few things I would try:

  1. The friendly name of the certificate should be the same as the dns of the machine that is running the service. If both server and client are running on same machine, use "CN=localhost".

  2. Check this link for a great information on how to create and install certificates .

  3. When self hosting, you need to manually associate the certificate with the port. Use netsh command line. Check this.

Hope these steps will help... Good luck

Jaffi
  • 31
  • 6