1

Description: I have a .NET 4.5 WCF client and I neeed to consume a Java-based web service using SOAP. The client has to authenticate using a client certificate at the transport level. The message body has to be signed using a separate signing certificate. I've implemented a CustomBinding object trying all combinations of binding objects that make sense for my case... still no luck. Here is the post I got the idea for the CustomBinding from.

This is the code that generates a SOAP request (the CustomCredentials implementation is provided from Jawad, see the link with his post at the bottom) that is closest to the working request I got from the web service provider:

public static MyClient CreateProxy()
{
    EndpointAddress epa = new EndpointAddress(new Uri("https://www.webservice-url/Server20/ID"), EndpointIdentity.CreateDnsIdentity("Certificate_Issuer_Name"), new AddressHeaderCollection());
    MyClient proxy = new MyClient(GetCustomBinding(), epa);
    proxy.Endpoint.EndpointBehaviors.Remove(typeof(ClientCredentials));            

    CustomCredentials myCredentials = new CustomCredentials(GetClientAuthenticationCert(), GetSigningCertificate());
    proxy.Endpoint.EndpointBehaviors.Add(myCredentials);
    proxy.Endpoint.Contract.ProtectionLevel = ProtectionLevel.Sign;

    return proxy;
}

private static Binding GetCustomBinding()
{
    TransportSecurityBindingElement tsElement = SecurityBindingElement.CreateCertificateOverTransportBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
    tsElement.SetKeyDerivation(false);
    tsElement.AllowInsecureTransport = true;
    X509SecurityTokenParameters tokenParams = new X509SecurityTokenParameters(X509KeyIdentifierClauseType.IssuerSerial, SecurityTokenInclusionMode.AlwaysToRecipient);
    tokenParams.ReferenceStyle = SecurityTokenReferenceStyle.Internal;
    tsElement.EndpointSupportingTokenParameters.SignedEncrypted.Add(tokenParams);
    tsElement.EnableUnsecuredResponse = true;
    tsElement.IncludeTimestamp = true;

    TextMessageEncodingBindingElement tmElement = new TextMessageEncodingBindingElement(MessageVersion.Soap11WSAddressing10, System.Text.Encoding.UTF8);

    HttpsTransportBindingElement httpsElement = new HttpsTransportBindingElement();
    httpsElement.RequireClientCertificate = true;

    CustomBinding customBinding = new CustomBinding();
    customBinding.Elements.Add(tsElement);
    customBinding.Elements.Add(tmElement);
    customBinding.Elements.Add(httpsElement);

    return customBinding;
}

The generated SOAP request looks like this:

<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">http://bsi.bund.de/eID/useID</a:Action>
    <a:MessageID>urn:uuid:288e93bd-b004-42e7-b49c-00f1a315cd29</a:MessageID>
    <a:ReplyTo><a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
    </a:ReplyTo>
    <VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDP/Eczn0ACQAA</VsDebuggerCausalityData>
    <a:To s:mustUnderstand="1" u:Id="_1">https://test.governikus-eid.de:8444/eID-Server-20/eID</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="_0">
            <u:Created>2014-08-25T13:48:07.634Z</u:Created>
            <u:Expires>2014-08-25T13:53:07.634Z</u:Expires>
        </u:Timestamp>
        <o:BinarySecurityToken><!--Removed--></o:BinarySecurityToken>
        <o:BinarySecurityToken><!--Removed--></o:BinarySecurityToken>
        <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
            <SignedInfo>
            <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></CanonicalizationMethod>
            <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></SignatureMethod>
            <Reference URI="#_0">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
                <DigestValue>BMfUzgz9+cG6FgNeljlm4T9v5Y0=</DigestValue>
            </Reference>
            <Reference URI="#_1">
                <Transforms>
                    <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></Transform>
                </Transforms>
                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></DigestMethod>
                <DigestValue>TM59Or2Dn8j6oddZ/HE7viskDVg=</DigestValue>
            </Reference>
            </SignedInfo>
                <SignatureValue>bQAoFq3VNK2GCxM9iM0ZLlvFZxxMLaH7E5Ch12X...</SignatureValue>
                <KeyInfo>
                    <o:SecurityTokenReference>
                        <o:Reference URI="#uuid-4432a63d-068b-4627-bbb3-2bc94d016357-1"></o:Reference>
                    </o:SecurityTokenReference>
                </KeyInfo>
        </Signature>
    </o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <useIDRequest xmlns="http://bsi.bund.de/eID/">
        <UseOperations>
            <GivenNames>REQUIRED</GivenNames>
            <FamilyNames>REQUIRED</FamilyNames>
            <Nationality>REQUIRED</Nationality>
        </UseOperations>
        <AgeVerificationRequest>
            <Age>18</Age>
        </AgeVerificationRequest>
        <PlaceVerificationRequest></PlaceVerificationRequest>
    </useIDRequest>
</s:Body>
</s:Envelope>

And here is how the SOAP request should look like:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#" 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" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <S:Header>
        <wsse:Security S:mustUnderstand="1">
            <wsu:Timestamp xmlns:ns15="http://www.w3.org/2003/05/soap-envelope" xmlns:ns16="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" wsu:Id="_3">
                <wsu:Created>2014-08-22T09:22:48Z</wsu:Created>
                <wsu:Expires>2014-08-22T09:27:48Z</wsu:Expires>
            </wsu:Timestamp>
            <ds:Signature xmlns:ns15="http://www.w3.org/2003/05/soap-envelope" xmlns:ns16="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" Id="_1">
                <ds:SignedInfo>
                    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                        <exc14n:InclusiveNamespaces PrefixList="wsse S"/>
                    </ds:CanonicalizationMethod>
                    <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                    <ds:Reference URI="#_5002">
                        <ds:Transforms>
                            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                                <exc14n:InclusiveNamespaces PrefixList="S"/>
                            </ds:Transform>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>xhfeoN1hwzzG6xj53QP4Y/waCm4=</ds:DigestValue>
                    </ds:Reference>
                    <ds:Reference URI="#_3">
                        <ds:Transforms>
                            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                                <exc14n:InclusiveNamespaces PrefixList="wsu wsse S"/>
                            </ds:Transform>
                        </ds:Transforms>
                        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <ds:DigestValue>eNvJUyyQU/GRCS1V0tdoNzy8IHY=</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>KpzOsC/5r3UjKcOHx2l...</ds:SignatureValue>
                <ds:KeyInfo>
                <wsse:SecurityTokenReference>
                    <ds:X509Data>
                        <ds:X509IssuerSerial>
                            <ds:X509IssuerName>C=DE,ST=bremen,L=bremen,O=bos,OU=test,CN=demo_epa</ds:X509IssuerName>
                            <ds:X509SerialNumber>124466</ds:X509SerialNumber>
                        </ds:X509IssuerSerial>
                    </ds:X509Data>
                </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            </ds:Signature>
        </wsse:Security>
    </S:Header>
    <S:Body wsu:Id="_5002">
        <ns4:useIDRequest xmlns:ns2="urn:oasis:names:tc:dss:1.0:core:schema" xmlns:ns3="http://www.w3.org/2000/09/xmldsig#" xmlns:ns4="http://bsi.bund.de/eID/" xmlns:ns5="http://www.w3.org/2001/04/xmlenc#\
        " xmlns:ns6="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ns7="urn:oasis:names:tc:SAML\:1.0:assertion">
        <ns4:UseOperations>
            <ns4:GivenNames>REQUIRED</ns4:GivenNames>
            <ns4:FamilyNames>REQUIRED</ns4:FamilyNames>
        </ns4:UseOperations>
        </ns4:useIDRequest>
    </S:Body>
</S:Envelope>

The main difference I see is that I don't have X509Data in the SecurityTokenReference tag, but only a reference.

So, what am I doing wrong? Is the missing X509Data tag in the request the key to the problem? If yes, how can I add this information there?

Community
  • 1
  • 1
vvasilev
  • 11
  • 3

0 Answers0