s441

Hello All,

I used makecert to generate a certificate named 'ServiceModelSamples-HTTPS-Server and installed it in LocalMachine\My store on the server. I used the FindPrivateKey utility to find the keyset file and gave full control to NetworkService, InternetGuestAccount and ASPNET machine account.

I installed the certificate on my client machine as well in CurrentUser\Root as well as LocalMachine\My.

My service is hosted in IIS and I have enabled 'Anonymouse Access' to the virtual directory and checked 'Accept Client Certificates'.

I can browse the svc file to view the wsdl from the client machine. However, I get the aforementioned error when I run my client app and make a call to the method using the service proxy.

My client side code is as follows:

PermissiveCertificatePolicy.Enact("CN=ServiceModelSamples-HTTPS-Server");

TestServiceClient c = new TestServiceClient();

c.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.Root, X509FindType.FindBySubjectName, "ServiceModelSamples-HTTPS-Server");

 

Here is my web.config:

< xml version="1.0" ><configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">  <system.serviceModel> 
    <services>
      <service behaviorConfiguration="credentialConfig" name="WCF.Server.Train.Services.TrainService" >
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="wsHttpBindingForTrain"
                  contract="WCF.Server.Train.Contracts.ITrainService"/>
        <endpoint address="mex"
                binding="wsHttpBinding"
                bindingConfiguration="wsHttpBindingForTrain"
                contract="IMetadataExchange"/>
      </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="wsHttpBindingForTrain">
          <security mode="Message">
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </wsHttpBinding>    
    </bindings>   
    <behaviors>
      <serviceBehaviors>
        <behavior name="credentialConfig">
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceCredentials>
            <serviceCertificate findValue="ServiceModelSamples-HTTPS-Server"
                           storeLocation="LocalMachine"
                           storeName="My"
                           x509FindType="FindBySubjectName"/>
            <clientCertificate>
              <certificate findValue="ServiceModelSamples-HTTPS-Server"
                           storeLocation="LocalMachine"
                           storeName="My"
                           x509FindType="FindBySubjectName"/>
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>     
    </behaviors>
  </system.serviceModel>  <system.web>
    <compilation debug="true"/>
    <customErrors mode="Off"/>
  </system.web> 
</configuration>

Here is my client side app.config:

< xml version="1.0" encoding="utf-8" >

<configuration>

<system.serviceModel>

<bindings>

<wsHttpBinding>

<binding name="WSHttpBinding_ITrainService" closeTimeout="00:01:00"

openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"

bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"

maxBufferPoolSize="524288" maxReceivedMessageSize="65536"

messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"

allowCookies="false">

<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"

maxBytesPerRead="4096" maxNameTableCharCount="16384" />

<reliableSession ordered="true" inactivityTimeout="00:10:00"

enabled="false" />

<security mode="Message">

<transport clientCredentialType="Windows" proxyCredentialType="None"

realm="" />

<message clientCredentialType="Certificate" negotiateServiceCredential="true"

algorithmSuite="Default" establishSecurityContext="true" />

</security>

</binding>

</wsHttpBinding>

</bindings>

<client>

<endpoint address="http://x.x.x.x/Train/TrainService.svc"

binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITrainService"

contract="WCF.Client.Train.App.Train.ITrainService" name="WSHttpBinding_ITrainService">

<identity>

<certificate encodedValue="AwAAAAEAAAAUAAAAatGUhVinmH27v0e7N5iYlZxhZTogAAAAAQAAANQBAAAwggHQMIIBeqADAgECAhAWKTX2EwdzhEnzbDYNRL0nMA0GCSqGSIb3DQEBBAUAMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTA3MDEwMjE2MzAyMVoXDTM5MTIzMTIzNTk1OVowKzEpMCcGA1UEAxMgU2VydmljZU1vZGVsU2FtcGxlcy1IVFRQUy1TZXJ2ZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMa2QWEnCtt0DcdKvlfyLCuI4ykRrztkMS7cHMCYk46+Yt0Y3KUvQkW8zZ0o1Jg9MaM/7Cu5utRpGvzxa/BPa4gxLFJOCP551/Zy8yp4iaWXEPlp8J9ub/l7guQr9yC6NfzXNu0Ky+C+n22kdnVEOf810n/9Hu4tn7LkS9F4VvTNAgMBAAGjSzBJMEcGA1UdAQRAMD6AEBLkCS0GHR1PAI1hIdwWZGOhGDAWMRQwEgYDVQQDEwtSb290IEFnZW5jeYIQBjdsAKoAZIoRz7jUqlw19DANBgkqhkiG9w0BAQQFAANBAG4FnNeRqXcFhK1L5ZzKfhFjaYYDcRfclwJ6qkZgNWCjKBlwv78QVtR7uEapIO90OIT7ejfnYHqG1pt6be1n6Cs=" />

</identity>

</endpoint>

</client>

</system.serviceModel>

</configuration>

 

Thanks much in advance!!!

 



Re: Windows Communication Foundation (Indigo) The certificate must have a private key. The process must have access rights for the private key.

Pedro Felix

Hello:

According to you configuration file, you are using a binding with client credential type set to certificate. So, the client also has to have a certificate (and the associated private key!).
You cannot use the server certificate as the client certificate (unless the client has the server private key, which would be very strange)

In conclusion:
1) The server must have a certificate and associated private key
2) The client must have a certificate and associated private key
3) The server certificate does not have to be in the client. It will be automatically retrived by the client during the session negotiation
4) The server must trust directly the client certificate (PeerTrust configuration) or the client's root CA (RootTrust configuration)

Hope it helps
Pedro Felix





Re: Windows Communication Foundation (Indigo) The certificate must have a private key. The process must have access rights for the private key.

s441

Thanks for that insight, Pedro!

Now I get "{"The caller was not authenticated by the service."} error message.

I did the following (following instructions in http://msdn2.microsoft.com/en-us/library/ms751516.aspx):

1. Created a client certificate with CN=client.com using the SDK's setup.bat.

2. Installed the client cert in my client machine's LocalMachine\My

3. Physically transferred the client.cer file to the server machine and installed the client cert in the server's LocalMachine\TrustedPeople

4. Server had a certificate already installed with CN=ServiceModelSamples-HTTPS-Server in LocalMachine\My. I exported this server cert to a .cer file and physically transferred this .cer file to the client machine and installed it in the client machine's CurrentUser\TrustedPeople

5. My web.config has the following:

...

<behaviors>
<serviceBehaviors>
<behavior name="credentialConfig">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<serviceCertificate findValue="ServiceModelSamples-HTTPS-Server"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName"/>
<clientCertificate>
<authentication certificateValidationMode="PeerOrChainTrust"/>
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>

...

6. My client app's config has the following:

<system.serviceModel>

<behaviors>

<endpointBehaviors>

<behavior name="ClientCertificateBehavior">

<clientCredentials>

<clientCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="client.com"/>

<serviceCertificate>

<authentication certificateValidationMode="PeerOrChainTrust"/>

</serviceCertificate>

</clientCredentials>

</behavior>

</endpointBehaviors>

</behaviors>

<bindings>

<wsHttpBinding>

<binding name="WSHttpBinding_ITrainService" closeTimeout="00:01:00"

openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"

bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"

maxBufferPoolSize="524288" maxReceivedMessageSize="65536"

messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"

allowCookies="false">

<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"

maxBytesPerRead="4096" maxNameTableCharCount="16384" />

<reliableSession ordered="true" inactivityTimeout="00:10:00"

enabled="false" />

<security mode="Message">

<transport clientCredentialType="Windows" proxyCredentialType="None"

realm="" />

<message clientCredentialType="Certificate" negotiateServiceCredential="true"

algorithmSuite="Default" establishSecurityContext="true" />

</security>

</binding>

</wsHttpBinding>

</bindings>

<client>

<endpoint address="http://x.x.x.x/Train/TrainService.svc"

binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITrainService" behaviorConfiguration="ClientCertificateBehavior"

contract="WCF.Client.Train.App.Train.ITrainService" name="WSHttpBinding_ITrainService">

<identity>

<certificate encodedValue="AwAAAAEAAAAUAAAAatGUhVinmH27v0e7N5iYlZxhZTogAAAAAQAAANQBAAAwggHQMIIBeqADAgECAhAWKTX2EwdzhEnzbDYNRL0nMA0GCSqGSIb3DQEBBAUAMBYxFDASBgNVBAMTC1Jvb3QgQWdlbmN5MB4XDTA3MDEwMjE2MzAyMVoXDTM5MTIzMTIzNTk1OVowKzEpMCcGA1UEAxMgU2VydmljZU1vZGVsU2FtcGxlcy1IVFRQUy1TZXJ2ZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMa2QWEnCtt0DcdKvlfyLCuI4ykRrztkMS7cHMCYk46+Yt0Y3KUvQkW8zZ0o1Jg9MaM/7Cu5utRpGvzxa/BPa4gxLFJOCP551/Zy8yp4iaWXEPlp8J9ub/l7guQr9yC6NfzXNu0Ky+C+n22kdnVEOf810n/9Hu4tn7LkS9F4VvTNAgMBAAGjSzBJMEcGA1UdAQRAMD6AEBLkCS0GHR1PAI1hIdwWZGOhGDAWMRQwEgYDVQQDEwtSb290IEFnZW5jeYIQBjdsAKoAZIoRz7jUqlw19DANBgkqhkiG9w0BAQQFAANBAG4FnNeRqXcFhK1L5ZzKfhFjaYYDcRfclwJ6qkZgNWCjKBlwv78QVtR7uEapIO90OIT7ejfnYHqG1pt6be1n6Cs=" />

</identity>

</endpoint>

</client>

</system.serviceModel>

Any ideas





Re: Windows Communication Foundation (Indigo) The certificate must have a private key. The process must have access rights for the private key.

Sajay - MSFT

Check if your certificate if the process trying to decrypt message has access to the private key or use something like this

http://msdn2.microsoft.com/en-us/library/aa384088.aspx






Re: Windows Communication Foundation (Indigo) The certificate must have a private key. The process must have access rights for the private key.

Pedro Felix

Hello.

Turn on the tracing at the service side (use SvcConfigEditor) and locate the error messages at the generated trace file (use SvcTraceViewer).

Hope it helps
Pedro Felix




Re: Windows Communication Foundation (Indigo) The certificate must have a private key. The process must have access rights for the private key.

s441

I figured out which keyset file is being used by the server cert using FindPrivateKey.exe

I have given the 'Network Service' account full access to the keyset file in C:\DocsAndSettings\AllUsers\AppData\Microsoft\Crypto\MachineKeys corresponding to the server certificate that is installed in LocalMachine\My.

Sajay, is there any other file that needs to have access specified





Re: Windows Communication Foundation (Indigo) The certificate must have a private key. The process must have access rights for the private key.

s441

This is the error I get:

Security negotiation failed.
Service: http://x.x.x.x/Train/TrainService.svc
Action: http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue
ClientIdentity: CN=client.com; 055C986C45ED6ABA5F249833BF99A63BFF7D7F93
ActivityId: <null>
Negotiation: TlsnegoTokenAuthenticator
SecurityTokenValidationException: The X.509 certificate CN=client.com is not in the trusted people store. The X.509 certificate CN=client.com chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.

FYI, my server has "ServiceModelSamples-HTTPS-Server" installed in LocalMachine\My and "client.com" installed in LocalMachine\TrustedPeople

My client machine has "client.com" installed in CurrentUser\My and "ServiceModelSamples-HTTPS-Server" installed in CurrentUser\TrustedPeople

My web.config has <serviceCredentials><clientCertificate><authentication certifcateValidationMode="PeerOrChainTrust"/><clientCertificate><serviceCertificate findValue="ServiceModelSamples-HTTPS-Server" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/></serviceCredentials>

My client side app.config has:

<behaviors>

<endpointBehaviors>

<behavior name="ClientCertificateBehavior">

<clientCredentials>

<clientCertificate storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName" findValue="client.com"/>

<serviceCertificate>

<authentication certificateValidationMode="PeerOrChainTrust"/>

</serviceCertificate>

</clientCredentials>

</behavior>

</endpointBehaviors>

</behaviors>





Re: Windows Communication Foundation (Indigo) The certificate must have a private key. The process must have access rights for the private key.

s441

I got this scenario to work.

I noticed that the thumbprint of the client certificate that the server wanted in its TrustedPeople store was different that the client cert on the client machine.

I exported the "client.com" without the private key and installed it in the server's LocalMachine\TrustedPeople and it worked!!!

Grazie!!!!