title: Secure WCF via X.509 certificate with BinarySecurityToken
body: <p>i'm not a WCF expert, and i know just the basics of service security, so maybe most of the things that i'll point out will be wrong.
  That said, i need to invoke a 3d party service that requires a specific format for the SOAP header. 
  They require that the soap header provides:
  1) timestamp block
  2) Binary Token
  3) digest (checksum of a part of data to encrypt)</p>
  
  <p>They've provided me this exemple of request (i've removed the sensible parts)</p>
  
  <pre><code>&lt;S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"&gt;
    &lt;S:Header&gt;
      &lt;wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;
        &lt;wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"
                                  wsu:Id="...omissis..."&gt;
        &lt;/wsse:BinarySecurityToken&gt;
  
        &lt;ds:Signature Id="SIG-6" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"&gt;
          &lt;ds:SignedInfo&gt;
            &lt;ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;
              &lt;ec:InclusiveNamespaces PrefixList="S" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;
            &lt;/ds:CanonicalizationMethod&gt;
            &lt;ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/&gt;
            &lt;ds:Reference URI="#TS-5"&gt;
              &lt;ds:Transforms&gt;
                &lt;ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;
                  &lt;ec:InclusiveNamespaces PrefixList="wsse S" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/&gt;
                &lt;/ds:Transform&gt;
              &lt;/ds:Transforms&gt;
              &lt;ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/&gt;
              &lt;ds:DigestValue&gt;...omissis...&lt;/ds:DigestValue&gt;
            &lt;/ds:Reference&gt;
          &lt;/ds:SignedInfo&gt;
          &lt;ds:SignatureValue&gt;
            ....
            ...omissis...
            ....
          &lt;/ds:SignatureValue&gt;
          &lt;ds:KeyInfo Id="KI-...omissis..."&gt;
            &lt;wsse:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1" wsu:Id="STR-...omissis..." xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd"&gt;
              &lt;wsse:Reference URI="#X509-...omissis..." ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"/&gt;
            &lt;/wsse:SecurityTokenReference&gt;
          &lt;/ds:KeyInfo&gt;
        &lt;/ds:Signature&gt;
        &lt;wsu:Timestamp wsu:Id="TS-5"&gt;
          &lt;wsu:Created&gt;2013-03-27T15:10:18.523Z&lt;/wsu:Created&gt;
          &lt;wsu:Expires&gt;2013-03-27T15:26:58.523Z&lt;/wsu:Expires&gt;
        &lt;/wsu:Timestamp&gt;
      &lt;/wsse:Security&gt;
    &lt;/S:Header&gt;
  &lt;S:Body&gt;
      ...clear (not encrypted) body of the soap request
  &lt;/S:Body&gt;
  &lt;/S:Envelope&gt;
  </code></pre>
  
  <p>They gave me also a WSDL and an xsd.
  What i've done was to create a new web application, using the wsdl as service reference.
  Checking the web.config, i can see that this have created a basicHttpBinding like this</p>
  
  <pre><code>&lt;system.serviceModel&gt;
      &lt;bindings&gt;
        &lt;basicHttpBinding&gt;
          &lt;binding name="CPBinding"&gt;
            &lt;security mode="Transport" /&gt;
          &lt;/binding&gt;
          &lt;binding name="CPBinding1" /&gt;
        &lt;/basicHttpBinding&gt;
      &lt;/bindings&gt;
      &lt;client&gt;
        &lt;endpoint address="https://...omissis"
          binding="basicHttpBinding" bindingConfiguration="CPBinding"
          contract="BTClient.CPCUVPortType" name="CPCUVPort" /&gt;
      &lt;/client&gt;
    &lt;/system.serviceModel&gt;
  </code></pre>
  
  <p>But this binding doesn't use any kind of security policy, so i've created a behaviour that takes into account the certificates (for a mutual certificate) like that</p>
  
  <pre><code> &lt;behaviors&gt;
        &lt;endpointBehaviors&gt;
          &lt;behavior name="CustomBehaviorForCertificates"&gt;
            &lt;clientCredentials&gt;
              &lt;clientCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint" findValue="...omissis..." /&gt;
              &lt;serviceCertificate&gt;
                &lt;scopedCertificates&gt;
                  &lt;add targetUri="https://...omissis..." storeLocation="LocalMachine" storeName="TrustedPeople" x509FindType="FindByThumbprint" findValue="...omissis..." /&gt;
                &lt;/scopedCertificates&gt;
                &lt;authentication certificateValidationMode="PeerTrust" revocationMode="NoCheck" /&gt;
              &lt;/serviceCertificate&gt;
            &lt;/clientCredentials&gt;
          &lt;/behavior&gt;
        &lt;/endpointBehaviors&gt;
      &lt;/behaviors&gt;
  </code></pre>
  
  <p>And referenced this on the binding. By inspecting the outgoing messages (using the method BeforeSendRequest of a custom Inspector) i can see that it totally ignores the certificates, sending  the same request as the without-behaviour one. 
  The 3d party service answer to my request like this:</p>
  
  <pre><code>&lt;SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"&gt;
    &lt;SOAP-ENV:Header&gt;
      &lt;wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;
        &lt;wsu:Timestamp wsu:Id="Timestamp-..." xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;
          &lt;wsu:Created&gt;2013-09-06T14:31:28Z&lt;/wsu:Created&gt;
          &lt;wsu:Expires&gt;2013-09-06T14:36:28Z&lt;/wsu:Expires&gt;
        &lt;/wsu:Timestamp&gt;
        &lt;wsse:BinarySecurityToken wsu:Id="SecurityToken-...." EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;
          ...omissis...
        &lt;/wsse:BinarySecurityToken&gt;
        &lt;Signature xmlns="http://www.w3.org/2000/09/xmldsig#"&gt;
          &lt;SignedInfo&gt;
            &lt;CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
            &lt;SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /&gt;
            &lt;Reference URI="#Timestamp-..."&gt;
              &lt;Transforms&gt;
                &lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /&gt;
              &lt;/Transforms&gt;
              &lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /&gt;
              &lt;DigestValue&gt;...omissis...&lt;/DigestValue&gt;
            &lt;/Reference&gt;
          &lt;/SignedInfo&gt;
          &lt;SignatureValue&gt;...omissis...&lt;/SignatureValue&gt;
              &lt;KeyInfo&gt;
                  &lt;wsse:SecurityTokenReference xmlns=""&gt;
                      &lt;wsse:Reference URI="#SecurityToken-...omissis..." ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" /&gt;
                  &lt;/wsse:SecurityTokenReference&gt;
              &lt;/KeyInfo&gt;
          &lt;/Signature&gt;
      &lt;/wsse:Security&gt;
    &lt;/SOAP-ENV:Header&gt;
    &lt;SOAP-ENV:Body wsu:Id="..." xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;
      &lt;SOAP-ENV:Fault&gt;
        &lt;faultcode&gt;wsse:FailedCheck&lt;/faultcode&gt;
        &lt;faultstring&gt;The signature or decryption was invalid&lt;/faultstring&gt;
        &lt;detail&gt;
          &lt;e:myfaultdetails xmlns:e="Some-URI"&gt;
            &lt;errorCode&gt;500&lt;/errorCode&gt;
            &lt;message&gt;INTERNAL_SERVER_ERROR&lt;/message&gt;
          &lt;/e:myfaultdetails&gt;
        &lt;/detail&gt;
      &lt;/SOAP-ENV:Fault&gt;
    &lt;/SOAP-ENV:Body&gt;
  &lt;/SOAP-ENV:Envelope&gt;
  </code></pre>
  
  <p>After doing some research i've read that to provide a BinarySecurityToken as requested i need to implement a customBinding. I've tried different approaches and combinations but i always fail to make progress. </p>
  
  <p>For example, by using this custom behaviour:</p>
  
  <pre><code>  &lt;customBinding&gt;
      &lt;binding name="cb"&gt;
        &lt;security authenticationMode="MutualCertificateDuplex" requireDerivedKeys="false" includeTimestamp="true"
          messageProtectionOrder="EncryptBeforeSign" messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10" /&gt;
        &lt;textMessageEncoding messageVersion="Soap11" /&gt;
        &lt;httpsTransport /&gt;
      &lt;/binding&gt;
    &lt;/customBinding&gt;
  </code></pre>
  
  <p>I receive an Internal server error like this:</p>
  
  <pre><code>ExceptionType: System.ServiceModel.Security.MessageSecurityException: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.InnerException: System.ServiceModel.FaultException:Internal Error
  </code></pre>
  
  <p>and, most important...my outgoing request is ALWAYS the same as the basicHttpBinding one!
  Obviously i have not well understood something. I can see that, using the basicHttpBindig i can correctly communicate with them, but i fail to provide the required security fragments. If i try to use any other king of binding (for example wsHttpBinding or a customBinding) i receive an error message.
  Can someone please help me understanding the correct way to do such job? any help would be very appreciated.</p>
  
  <p>Thanks a lot.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>I'm adding the outgoing request:</p>
  
  <pre><code>&lt;s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"&gt;
    &lt;s:Header&gt;
      &lt;ActivityId CorrelationId="dd479557-7e51-41de-822b-d2ac669ff827" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics"&gt;bbd2f92b-33d5-4ec0-87b6-690f2142cdf5&lt;/ActivityId&gt;
      &lt;o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"&gt;
        &lt;u:Timestamp u:Id="uuid-7b22e181-f551-4821-91e0-cf8c9b8d9eef-1"&gt;
          &lt;u:Created&gt;2013-09-09T12:24:03.563Z&lt;/u:Created&gt;
          &lt;u:Expires&gt;2013-09-09T12:29:03.563Z&lt;/u:Expires&gt;
        &lt;/u:Timestamp&gt;
        &lt;o:BinarySecurityToken&gt;
          &lt;!-- Removed--&gt;
        &lt;/o:BinarySecurityToken&gt;
        &lt;Signature xmlns="http://www.w3.org/2000/09/xmldsig#"&gt;
          &lt;SignedInfo&gt;
            &lt;CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;&lt;/CanonicalizationMethod&gt;
            &lt;SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"&gt;&lt;/SignatureMethod&gt;
            &lt;Reference URI="#_1"&gt;
              &lt;Transforms&gt;
                &lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;&lt;/Transform&gt;
              &lt;/Transforms&gt;
              &lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"&gt;&lt;/DigestMethod&gt;
              &lt;DigestValue&gt;...omissis...&lt;/DigestValue&gt;
            &lt;/Reference&gt;
            &lt;Reference URI="#uuid-7b22e181-f551-4821-91e0-cf8c9b8d9eef-1"&gt;
              &lt;Transforms&gt;
                &lt;Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"&gt;&lt;/Transform&gt;
              &lt;/Transforms&gt;
              &lt;DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"&gt;&lt;/DigestMethod&gt;
              &lt;DigestValue&gt;...omissis...=&lt;/DigestValue&gt;
            &lt;/Reference&gt;
          &lt;/SignedInfo&gt;
          &lt;SignatureValue&gt;...omissis...&lt;/SignatureValue&gt;
          &lt;KeyInfo&gt;
            &lt;o:SecurityTokenReference&gt;
              &lt;o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#uuid-e31a3eed-6ac7-4dcb-bfb2-2384764acd93-2"&gt;&lt;/o:Reference&gt;
            &lt;/o:SecurityTokenReference&gt;
          &lt;/KeyInfo&gt;
        &lt;/Signature&gt;
      &lt;/o:Security&gt;
    &lt;/s:Header&gt;
    &lt;s:Body u:Id="_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
      &lt;CPCUValidityRequest xmlns="http://......omissis..."&gt;
        &lt;serviceType&gt;3&lt;/serviceType&gt;
        &lt;arg1&gt;arg1&lt;/arg1&gt;
        &lt;arg2&gt;arg2&lt;/arg2&gt;
        ...omissis...
      &lt;/CPCUValidityRequest&gt;
    &lt;/s:Body&gt;
  &lt;/s:Envelope&gt;
  </code></pre>
  
  <p><strong>Solution</strong>:
  Actually i can't successfully invoke the remote service due to an error (as stated in the comments to the accepted solution. But i can say that this question is answered due to the fact that i've managed to create a request mostly similar to the required one. Many thanks to Yaron.</p>
  
  <p>PS:( An hint for those who will have a similar issue, to check the outgoing/incoming request, try to use the Microsoft Trace Viewer, enabling tracing as suggested in this answer <a href="https://stackoverflow.com/a/11678740/2274007">https://stackoverflow.com/a/11678740/2274007</a> (remember to follow also the advice in the comment))</p>