3

I must make my WCF Client consume a web service (IBM DataPower) and sign/encrypt the request using Web Services Security X.509 Certificate Token Profile 1.1 OASIS Standard Specification, 1 February 2006.

So far I have created a custom binding and "think" I am working along the right lines:

Updated to reflect latest attempt

Private Function CreateCustomBinding() As Channels.Binding

    Dim asbe As New Channels.AsymmetricSecurityBindingElement

    asbe.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10

    asbe.InitiatorTokenParameters = New ServiceModel.Security.Tokens.X509SecurityTokenParameters
    asbe.RecipientTokenParameters = New ServiceModel.Security.Tokens.X509SecurityTokenParameters

    asbe.MessageProtectionOrder = Security.MessageProtectionOrder.EncryptBeforeSign

    asbe.SecurityHeaderLayout = SecurityHeaderLayout.Strict

    asbe.IncludeTimestamp = True
    asbe.SetKeyDerivation(False)

    asbe.DefaultAlgorithmSuite = Security.SecurityAlgorithmSuite.Basic128Rsa15  'By default, AES-128 is used as the encryption algorithm.

    'Add the elements to the custom binding
    Dim myBinding As New CustomBinding

    'element order is important - see http://msdn.microsoft.com/en-us/library/ms733893(v=vs.90).aspx

    'Protocol Binding Elements (security)
    myBinding.Elements.Add(asbe)

    'Encoding Binding Element  
    myBinding.Elements.Add(New TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10, System.Text.Encoding.UTF8))

    'Transport Binding Element
    Dim httpsBindingElement As New HttpsTransportBindingElement()
    httpsBindingElement.RequireClientCertificate = True
    myBinding.Elements.Add(httpsBindingElement)

    Return myBinding

End Function

Then use this binding like so:

Dim epi As EndpointIdentity = EndpointIdentity.CreateDnsIdentity("xgtwsqa.theirdomain.com")

Dim epuri As Uri = New Uri("https://xgtwqa.theirdomain.com/5067/ProcessRepairOrder")
Dim ea As New EndpointAddress(epuri, epi, New AddressHeaderCollection)

Dim myBinding As Binding = GetCustomBinding2()

' Create the client. 
Dim starClientProxy As New wcfStarServiceProxy.starTransportPortTypesClient(myBinding, ea)

' Specify a certificate to use for authenticating the client.
starClientProxy.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, "*.mydomain.org.uk")

starClientProxy.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.CurrentUser, StoreName.AddressBook, X509FindType.FindBySubjectName, "xgtwsqa.theirdomain.com")

'starClientProxy.ClientCredentials.ServiceCertificate.SetScopedCertificate(StoreLocation.CurrentUser, StoreName.AddressBook, X509FindType.FindBySubjectName, "xgtwsqa.theirdomain.com", New Uri("https://xgtwqa.thedomain.com/5067/ProcessRepairOrder"))

' Begin using the client.
Dim response As wcfStarServiceProxy.AcknowledgeRepairOrderPayload = starClientProxy.ProcessMessage(payload)

Would someone either tell me what else I need to configure in the binding (I am pretty sure the binding method isn't quite right) or provide me with the code I need?

The above produces the following SOAP:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:a="http://www.w3.org/2005/08/addressing"
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">

  <s:Header>
    <a:Action s:mustUnderstand="1" u:Id="_3">
    http://www.starstandards.org/webservices/2009/transport/operations/ProcessMessage</a:Action>
    <a:MessageID u:Id="_4">
    urn:uuid:c2acbb72-49c2-465b-b177-e806494cdef7</a:MessageID>
    <a:ReplyTo u:Id="_5">
      <a:Address>
      http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
    <a:To s:mustUnderstand="1" u:Id="_6">
    https://xgtwqa.theirdomain.com/5067/ProcessRepairOrder</a:To>
    <o:Security s:mustUnderstand="1"
    xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">

      <u:Timestamp u:Id="uuid-b8d302ff-a098-42bb-afc6-694e647c23b0-1">

        <u:Created>2012-06-01T14:35:18.781Z</u:Created>
        <u:Expires>2012-06-01T14:40:18.781Z</u:Expires>
      </u:Timestamp>
      <o:BinarySecurityToken u:Id="uuid-7f9c9673-ae43-4fb5-8510-03cc4b98fa93-2"
      ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
      EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
      removed</o:BinarySecurityToken>
      <o:BinarySecurityToken u:Id="uuid-7f9c9673-ae43-4fb5-8510-03cc4b98fa93-1"
      ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
      EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
      removed</o:BinarySecurityToken>
      <e:EncryptedKey Id="_0"
      xmlns:e="http://www.w3.org/2001/04/xmlenc#">
        <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <o:SecurityTokenReference>
            <o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
            URI="#uuid-7f9c9673-ae43-4fb5-8510-03cc4b98fa93-1" />
          </o:SecurityTokenReference>
        </KeyInfo>
        <e:CipherData>
          <e:CipherValue>
          removed</e:CipherValue>
        </e:CipherData>
      </e:EncryptedKey>
      <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
          <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
          <Reference URI="#_2">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>removed</DigestValue>
          </Reference>
          <Reference URI="#_3">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>removed</DigestValue>
          </Reference>
          <Reference URI="#_4">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>removed</DigestValue>
          </Reference>
          <Reference URI="#_5">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>removed</DigestValue>
          </Reference>
          <Reference URI="#_6">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>removed</DigestValue>
          </Reference>
          <Reference URI="#uuid-b8d302ff-a098-42bb-afc6-694e647c23b0-1">

            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>removed</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>
        removed</SignatureValue>
        <KeyInfo>
          <o:SecurityTokenReference>
            <o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
            URI="#uuid-7f9c9673-ae43-4fb5-8510-03cc4b98fa93-2" />
          </o:SecurityTokenReference>
        </KeyInfo>
      </Signature>
      <e:ReferenceList xmlns:e="http://www.w3.org/2001/04/xmlenc#">
        <e:DataReference URI="#_1" />
      </e:ReferenceList>
    </o:Security>
  </s:Header>
  <s:Body u:Id="_2"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <e:EncryptedData Id="_1"
    Type="http://www.w3.org/2001/04/xmlenc#Content"
    xmlns:e="http://www.w3.org/2001/04/xmlenc#">
      <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc">
      </e:EncryptionMethod>
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
          <o:Reference URI="#_0"></o:Reference>
        </o:SecurityTokenReference>
      </KeyInfo>
      <e:CipherData>
        <e:CipherValue>removed</e:CipherValue>
      </e:CipherData>
    </e:EncryptedData>
  </s:Body>
</s:Envelope>

This is a sample of the SOAP I am expected to send:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsa="http://www.w3.org/2005/08/addressing"
xmlns:star="http://www.starstandard.org/STAR/5"
xmlns:tran="http://www.starstandards.org/webservices/2005/10/transport">

  <soap:Header>
    <wsa:To>urn:removed/star/services/v1/GetConditionCodes</wsa:To>
    <wsa:Action>
    http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage</wsa:Action>
    <wsa:MessageID>
    ef67ec85-d5c7-4669-b1a6-440ec2fe938b</wsa:MessageID>

    <tns:RespondTo xmlns:tns="urn:removed/soa/routing/v1.0">
      <tns:Endpoint>
      https://b2b-test.mydomain.com/Async/removed/StarWebService.ashx</tns:Endpoint>
    </tns:RespondTo>
    <tran:payloadManifest>
      <tran:manifest contentID="A0"
      namespaceURI="http://www.starstandard.org/STAR/5"
      element="GetStandardCodes" version="5.2.4" />
    </tran:payloadManifest>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    mustUnderstand="1">
      <u:Timestamp xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
      Id="timestamp" u:Id="timestamp">
        <u:Created>2012-05-30T16:39:39Z</u:Created>
        <u:Expires>2012-05-30T16:44:39Z</u:Expires>
      </u:Timestamp>
      <wsse:BinarySecurityToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
      ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
      EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
      wsu:Id="binary_security_token">
      removed</wsse:BinarySecurityToken>
      <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
        <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" />
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <wsse:SecurityTokenReference>
            <wsse:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier"
            EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
            4qEuhS3IWjReFLSSCOcVoN6Ywzo=</wsse:KeyIdentifier>
          </wsse:SecurityTokenReference>
        </KeyInfo>
        <CipherData>
          <CipherValue>
          removed</CipherValue>
        </CipherData>
        <ReferenceList>
          <DataReference URI="#encrypt" />
        </ReferenceList>
      </EncryptedKey>
      <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
        <SignedInfo>
          <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
          <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
          <Reference URI="#body">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>removeddigestvalue</DigestValue>
          </Reference>
          <Reference URI="#timestamp">
            <Transforms>
              <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>removeddigestvalue</DigestValue>
          </Reference>
        </SignedInfo>
        <SignatureValue>
        removed</SignatureValue>
        <KeyInfo>
          <wsse:SecurityTokenReference>
            <wsse:Reference URI="#binary_security_token"
            ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
          </wsse:SecurityTokenReference>
        </KeyInfo>
      </Signature>
    </wsse:Security>
  </soap:Header>
  <soap:Body xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
  id="body" u:Id="body">
    <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#"
    Id="encrypt" Type="http://www.w3.org/2001/04/xmlenc#Content">
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
      <CipherData>
        <CipherValue>
        removed</CipherValue>
      </CipherData>
    </EncryptedData>
  </soap:Body>
</soap:Envelope>
Mr Shoubs
  • 14,629
  • 17
  • 68
  • 107
  • please publish a sample of the desired soap – Yaron Naveh May 31 '12 at 16:03
  • @YaronNaveh - I've updated my question with the only sample I have. I can see it is different to what I have produced. If you can work out what I need to do from that, it would also be useful to know "how to know" how to work it out. – Mr Shoubs May 31 '12 at 16:21

1 Answers1

5

try to use this config:

      <customBinding>
            <binding name="NewBinding0">
                <textMessageEncoding messageVersion="Soap11WSAddressing10" />
                <security authenticationMode="MutualCertificate" messageProtectionOrder="SignBeforeEncrypt"
                    messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
                    <secureConversationBootstrap />
                </security>
                <httpTransport />
            </binding>
        </customBinding>
    </bindings>

if you want to use code the main difference is the use of WSSEcurity10 in the version (even though you need 11, this is compatible) and the messageProtectionOrder (which is why you only see encryption and not signature).

this may require further fine tuning, let me know the progress.

since you use code also set:

asbe.RecipientTokenParameters.X509ReferenceStyle=X509KeyIdentifierClauseType .SubjectKeyIdentifier

and:

asbe.RecipientTokenParameters.InclusionMode = SecurityTokenInclusionMode.Never
Yaron Naveh
  • 23,560
  • 32
  • 103
  • 158
  • They send me the following information - Encryption: Algorithm: AES128-CBC Generated in XML: EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5 Signature: RSA/DSA Algorithm: rsa-sha1 Generated in XML SignatureMethod Algorithm=http://www.w3.org/2000/09/xmldsig#rsa-sha1 – Mr Shoubs Jun 01 '12 at 11:38
  • Thanks, but this wouldn't even run (The provided URI scheme 'https' is invalid; expected 'http'. Parameter name: via). – Mr Shoubs Jun 01 '12 at 11:51
  • I modified my code to use Soap11WSAddressing10 and WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10, but now get "400 Bad Request". – Mr Shoubs Jun 01 '12 at 12:34
  • use httpsTransport instead of httpTransport for ssl. what'ts important is to see the soap that comes out and compare it to the desired one. – Yaron Naveh Jun 01 '12 at 13:44
  • check out what the server returns in the body, or any server side logs. your request is now very similar to the desired one. the main difference is that you have 2 binary security tokens. try to set asbe.RecipientTokenParameters.X509ReferenceStyle=X509KeyIdentifierClauseType .SubjectKeyIdentifier – Yaron Naveh Jun 01 '12 at 15:36
  • EDIT: I've added two lines of code to the answer. this should make your request similar enough. the otehr differences are that you sign the wsa headers, and that you have keyInfo inside the body. the former you could change with a custom encoder and you cannot change the latter. but wait with that until you get some information into the actual server problem – Yaron Naveh Jun 01 '12 at 15:39
  • Your answer sent me along the right path, but now I have another question (http://stackoverflow.com/q/10853606/198048) now that I have been provided with a configuration – Mr Shoubs Jun 01 '12 at 15:57
  • @YaronNaveh - I have somewhat similar challenge and since you are one of the most active and knowledgeable person on WS-Security, soapUI and WCF, could you please take a look at my question when you have some bandwidth: http://stackoverflow.com/q/32703632/247184 – VoodooChild Sep 25 '15 at 08:48