Client certificate (from commercial CA) was changed due to expiration and communication to one service stopped functioning - we get following error on server trace
System.IdentityModel.Tokens.SecurityTokenValidationException: The X.509 certificate CN=aaa.ccc.ff, O=XXXXX, L=Brbr, C=XX chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. A certification chain processed correctly, but one of the CA certificates is not trusted by the policy provider.
The same certificate is used to authenticate to other company's service that uses the same configuration and it's working fine the whole time.
service's configuration is following:
<system.serviceModel>
<extensions>
<behaviorExtensions>
<add name="A2AValidation" type="xxxyyyzzz.A2AValidation+CustomBehaviorSection, xxxyyyzzz A2A, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<protocolMapping>
<add scheme="http" binding="wsHttpBinding" />
</protocolMapping>
<bindings>
<wsHttpBinding>
<binding name="WcfServiceBinding">
<security mode="Message">
<message clientCredentialType="Certificate" negotiateServiceCredential="true" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ClientSecBehavior" name="xxxyyyzzz.Service">
<endpoint address="" behaviorConfiguration="A2AValidationBehavior" binding="wsHttpBinding" bindingConfiguration="WcfServiceBinding" name="A2AmessageEndpoint" contract="xxxyyyzzz.IService" />
<endpoint address="mex" binding="mexHttpsBinding" name="A2AMessageEndpointMex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://xxxyyyzzz:10002/XX/A2A/Service.svc" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="A2AValidationBehavior">
<A2AValidation />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ClientSecBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerOrChainTrust" trustedStoreLocation="LocalMachine" revocationMode="NoCheck" mapClientCertificateToWindowsAccount="true" />
</clientCertificate>
<serviceCertificate findValue="______" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<diagnostics wmiProviderEnabled="true">
<messageLogging logEntireMessage="true" logKnownPii="false" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="500" />
<endToEndTracing messageFlowTracing="true" />
</diagnostics>
</system.serviceModel>
Client side config is as following (also contains config for the other service that runs OK in other company):
<system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
maxSizeOfMessageToLog="2000"/>
</diagnostics>
<bindings>
<wsHttpBinding>
<binding name="YYYY_A2AMessageEndpoint_BindingConfig" maxReceivedMessageSize="2147483647">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
<binding name="XXXYYYZZZ_A2AMessageEndpoint_BindingConfig">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="YYYY_A2AMessageEndpoint_BehaviorConfig">
<clientCredentials>
<serviceCertificate>
<authentication
certificateValidationMode="PeerOrChainTrust"
revocationMode="NoCheck"
trustedStoreLocation="LocalMachine" />
</serviceCertificate>
<clientCertificate findValue="__________" x509FindType="FindByThumbprint" storeLocation="LocalMachine" storeName="My" />
</clientCredentials>
</behavior>
<behavior name="XXXYYYZZZ_A2AMessageEndpoint_BehaviorConfig">
<clientCredentials>
<serviceCertificate>
<authentication
certificateValidationMode="PeerOrChainTrust"
revocationMode="NoCheck"
trustedStoreLocation="LocalMachine" />
</serviceCertificate>
<clientCertificate findValue="__________" x509FindType="FindByThumbprint" storeLocation="LocalMachine" storeName="My" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint
name="YYYY_A2AMessageEndpoint"
contract="A2AMessageService.IService"
address="http://YYYY:10002/a2a/Service.svc"
binding="wsHttpBinding" bindingConfiguration="YYYY_A2AMessageEndpoint_BindingConfig"
behaviorConfiguration="YYYY_A2AMessageEndpoint_BehaviorConfig" >
<identity>
<certificate encodedValue="xyz=" />
</identity>
</endpoint>
<endpoint
name="XXXYYYZZZ_A2AMessageEndpoint"
contract="A2APTAMessageService.IService"
address="http://XXXYYYZZZ:10002/PTA/A2A/Service.svc"
binding="wsHttpBinding" bindingConfiguration="XXXYYYZZZ_A2AMessageEndpoint_BindingConfig"
behaviorConfiguration="XXXYYYZZZ_A2AMessageEndpoint_BehaviorConfig" >
<identity>
<certificate encodedValue="xyz=" />
</identity>
</endpoint>
</client>
</system.serviceModel>
The certificate is correctly registered in IIS Certificate Mapping and also in AD Certificate mapping, the whole certificate chain is displayed correctly on IIS and on AD for client certificate. The certificate that the client uses has following purposes:
- Proves your identity to a remote computer
- Ensures the identity of a remote computer
- 2.23.140.1.2.2
But I don't see this as a problem as one service does not have problem with such type of certificate to use.