Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically set x509 to use for WCF duplex comms

I am connecting to a duplex WCF service with an x509 cert, specifying the certificate details in the client config file like this:

<behaviors>
  <endpointBehaviors>
    <behavior name="ScannerManagerBehavior">
      <clientCredentials>
        <clientCertificate findValue="ClientName" x509FindType="FindBySubjectName" storeLocation="CurrentUser" storeName="My" />
        <serviceCertificate>
          <authentication certificateValidationMode="PeerTrust" />
        </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

The code that then connects to the WCF service:

DuplexChannelFactory<IScannerManager> _smFactory 
= new DuplexChannelFactory<IScannerManager>(instanceContext, nameOfEndPoint);
var _commsChannel = _smFactory.CreateChannel();

I now need to specify the client certificate name that will be used programatically, in code. Is it possible for me to do that? I can see that I can create my own x509Certificate2 class, but I'm not sure how to change/set the findValue="clientName" bit...

Thanks

like image 419
Matt Roberts Avatar asked Nov 04 '22 08:11

Matt Roberts


1 Answers

Ok, so using the helpful comment from wal (thanks!) I managed to get it working. The trouble i faced was the discovery that if you are going to dynamically set any part of the client config in code, you can't use any of the .config - you have to define it all in code. So it's pretty much all or nothing. At least that was my experience.

So, for me, I had to do this:

 var binding = new NetTcpBinding();
 binding.Security.Mode = SecurityMode.Transport;
 binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
 binding.Security.Transport.ProtectionLevel = ProtectionLevel.EncryptAndSign;
 binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

 var identity = new DnsEndpointIdentity("localhost");
 Uri uri = new Uri("tcp:URI goes here");
 var address = new EndpointAddress(uri, identity, new AddressHeaderCollection());

 _smFactory = new DuplexChannelFactory<IScannerManager>(instanceContext, binding, address);

 _smFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "CustomCertificateNameHere");
 _commsChannel = _smFactory.CreateChannel();

Which replaced my config.

like image 189
Matt Roberts Avatar answered Nov 09 '22 06:11

Matt Roberts