4

I am trying to extend WCF by following this how-to guide from microsoft. The basic idea is to use a hardware security module as the client-side private key holder, which means all cryptographic operations involving the client's private key must be carried out by the security module chip.

Setup

dotnet framework: 4.7.2
binding: netTcp
binding security: Message
clientCredentialType: Certificate (X509Certificate2) 
serverCertificate: X509Certificate2 

All certificates ( 1 server cert and 2 client certs ) are signed off by the same CA. The server certificate is a normal pfx file that contains both the certificate and private key. I prepared two different client certificates one with the private key and one without the private key. (two client side pfx files have the identical certificate )

Observations:

  1. When using the client pfx file contains the private key, the client is able to communicate to the server in the mtls fashion.
  2. When using the client pfx file without the private key, the attempt to set up secure session fails with the following exception
System.ArgumentException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
The certificate '<cert name>' must have a private key. The process must have access rights for the private key.

Stack Trace

System.ServiceModel.Security.TlsSspiNegotiation.ValidatePrivateKey(X509Certificate2 certificate)
System.ServiceModel.Security.TlsSspiNegotiation..ctor(String destination, Boolean isServer, SchProtocols protocolFlags, X509Certificate2 serverCertificate, X509Certificate2 clientCertificate, Boolean clientCertRequired)
System.ServiceModel.Security.TlsnegoTokenProvider.CreateTlsSspiState(X509SecurityToken token)
System.ServiceModel.Security.TlsnegoTokenProvider.CreateNegotiationState(EndpointAddress target, Uri via, TimeSpan timeout)
System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
  1. In neither case, the provided CustomX509AsymmetricSecurityKey as per the how-to above was NOT used by the WCF framework. Did not even instantiate the class. The CustomX509SecurityToken was instantiated via the CustomX509SecurityTokenProvider. But the SecurityKeys property of the CustomX509SecurityToken class was never called, which is where the custom private key comes to play.

Questions

  1. Is the how-to guide out of date? Notice it is dated 03/30/2017.
  2. The exception when using the pfx without private key is sort of self-explanatory. I did not provide the private key. Why didn't WCF use the provided CustomX509AsymmetricSecurityKey as the private key? Isnt this the whole point that the user is providing an alternative private key in the form of a X509AsymmetricSecurityKey?
  3. Am I following the wrong guide to achieve what I want? I did try to set the PrivateKey property of the X509Certificate2 class with a custom RSA implementation. But got lost trying to implement the ICspAsymmetricAlgorithm interface which is required by the X509Certificate2.PrivateKey
Frank Liu
  • 1,466
  • 3
  • 23
  • 36
  • Your current problem is that the settings in the document do not work for you, right? – Ding Peng Aug 11 '20 at 09:32
  • I am trying to find a correct way to plugin a custom private key to WCF. Following the how-to did not get me there. – Frank Liu Aug 12 '20 at 08:49
  • Have you successfully applied the configuration to the service? You can refer to this link, which includes applying custom client credentials to the service:https://learn.microsoft.com/en-us/dotnet/framework/wcf/extending/walkthrough-creating-custom-client-and-service-credentials – Ding Peng Aug 13 '20 at 09:38
  • Thx. I think the custom client credentials on the SERVER side may not be the problem. The custom private key is on the client side. – Frank Liu Aug 14 '20 at 10:01
  • did you check this reference may be helpful. https://security.stackexchange.com/questions/190290/should-the-client-or-the-server-generate-the-clients-public-private-key-pair – Nadeem Taj Aug 18 '20 at 04:53

0 Answers0