I am trying to call a webservice using WCF with a certificate to sign the message.
The server only supports the following canonicalization algorithm : 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments'
By default, WCF uses 'http://www.w3.org/2001/10/xml-exc-c14n#'
Since I couldn't configure it with the config file, I created a custom binding in which I set a custom SecurityAlgorithmSuite to force WCF to use the canonicalization algorithm expected by the service. Here is my custom binding :
public class TestBinding : Binding
{
public override BindingElementCollection CreateBindingElements()
{
var sec = TransportSecurityBindingElement.CreateCertificateOverTransportBindingElement();
sec.MessageSecurityVersion = MessageSecurityVersion
.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
sec.EnableUnsecuredResponse = true;
sec.DefaultAlgorithmSuite = new TestSecurityAlgorithmSuite();
return new BindingElementCollection(new BindingElement[] {
new TextMessageEncodingBindingElement() { MessageVersion = MessageVersion.Soap11WSAddressing10 },
sec,
new HttpsTransportBindingElement() { RequireClientCertificate = true }
});
}
public override string Scheme
{
get { return new HttpsTransportBindingElement().Scheme; }
}
}
And the algorithm suite :
public class TestSecurityAlgorithmSuite : Basic256SecurityAlgorithmSuite
{
public override string DefaultCanonicalizationAlgorithm
{
get { return "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"; }
}
public override string ToString()
{
return "TestSecurityAlgorithmSuite";
}
}
Unfortunately, I get the error :
Canonicalization algorithm 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments' is not supported.
Server stack trace:
à System.ServiceModel.Security.WSSecurityOneDotZeroSendSecurityHeader.StartPrimarySignatureCore(SecurityToken token, SecurityKeyIdentifier keyIdentifier, MessagePartSpecification signatureParts, Boolean generateTargettableSignature)
à System.ServiceModel.Security.WSSecurityOneDotZeroSendSecurityHeader.CreateSupportingSignature(SecurityToken token, SecurityKeyIdentifier identifier)
à System.ServiceModel.Security.SendSecurityHeader.SignWithSupportingToken(SecurityToken token, SecurityKeyIdentifierClause identifierClause)
à System.ServiceModel.Security.SendSecurityHeader.SignWithSupportingTokens()
à System.ServiceModel.Security.SendSecurityHeader.CompleteSecurityApplication()
à System.ServiceModel.Security.SecurityAppliedMessage.OnWriteMessage(XmlDictionaryWriter writer)
à System.ServiceModel.Channels.Message.WriteMessage(XmlDictionaryWriter writer)
à System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(Message message, BufferManager bufferManager, Int32 initialOffset, Int32 maxSizeQuota)
à System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset)
à System.ServiceModel.Channels.MessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager)
à System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message, Boolean shouldRecycleBuffer)
à System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message)
à System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout)
à System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout)
à System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
à System.ServiceModel.Channels.SecurityChannelFactory`1.SecurityRequestChannel.Request(Message message, TimeSpan timeout)
à System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
à System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
à System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
à System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)'
I am starting to think all hope is lost. Is there any way to make WCF work with the desired algorithm?
Unfortuantelly the exception is self descriptive: current version of WCF does not support "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" canonicalization algorithm.