2

I have a WCF custom binding that uses the TransportSecurityBindingElement security element, but am having continual issues with the time accuracy on both the client and the (third party) server.

How can I remove the seconds to make timestamp only accurate to the minute (I'm told that the server will accept this).

Alternatives idea's I've had is to update the system time before every request, however this assumes (incorrectly) that the server time is accurate. I've also tried to remove the timestamp altogether (it might not be required), but I get an System.InvalidOperationException saying Signing without primary signature requires timestamp.

.Net Code to build security element:

    Dim msgSecVer As System.ServiceModel.MessageSecurityVersion = ServiceModel.MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10

    Dim tsbe As TransportSecurityBindingElement = SecurityBindingElement.CreateCertificateOverTransportBindingElement(msgSecVer)
    tsbe.EnableUnsecuredResponse = True
    tsbe.SetKeyDerivation(False)
    tsbe.AllowInsecureTransport = True
    tsbe.IncludeTimestamp = True

    'adding clock skew doesn't seem to make any difference?
    Dim clockSkew As TimeSpan = TimeSpan.FromMinutes(1)
    tsbe.LocalClientSettings.MaxClockSkew = clockSkew
    tsbe.LocalServiceSettings.MaxClockSkew = clockSkew

    Return tsbe

Message header, note (possibly excess) accuracy of timestamp:

POST http://wwwqa.xxxx.com/services/
Content-Type: text/xml; charset=utf-8
VsDebuggerCausalityData: xxxx
SOAPAction: ""
Host: wwwqa.xxxx.com
Content-Length: 2400
Expect: 100-continue
Connection: Keep-Alive

<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">
    <s:Header>
        <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>2013-12-04T10:53:13.568Z</u:Created>
                <u:Expires>2013-12-04T10:58:13.568Z</u:Expires>
            </u:Timestamp>
            <o:BinarySecurityToken u:Id="uuid-bc441202-xxxx-xxxx-a176-02f2a61a6002-1" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">....xxxx....</o:BinarySecurityToken>
            <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="#_0">
                        <Transforms>
                            <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                        </Transforms>
                        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                        <DigestValue>xxxx</DigestValue>
                    </Reference>
                </SignedInfo>
                <SignatureValue>xxxx</SignatureValue>
                <KeyInfo>
                    <o:SecurityTokenReference><o:Reference URI="#uuid-bc441202-xxxx-xxxx-a176-02f2a61a6002-1"/></o:SecurityTokenReference>
                </KeyInfo>
            </Signature>
        </o:Security>
    </s:Header>
Mr Shoubs
  • 14,629
  • 17
  • 68
  • 107
  • 1
    Have you checked this? http://msdn.microsoft.com/en-us/library/aa738468.aspx – mostruash Jan 17 '14 at 11:37
  • I hadn't, but now I have added the clock Skew, but it doesn't seem to make any difference to the sent messages timestamp. (I can't see it made any difference, did I do something wrong? (Updated Code in question). – Mr Shoubs Jan 17 '14 at 12:20
  • Where is it failing when the time is incorrect, and where is your `InvalidOperationException` thrown when you remove the timestamp? – Zache Jan 17 '14 at 12:24
  • 2
    If the service is 3rd party and you have no control over it, clock skew won't work. Both client and server must agree on a common skew clock. BTW default value is 5 minutes. So server must have set it to a lower value on purpose as a means to prevent replay attacks. – mostruash Jan 17 '14 at 12:32
  • @Zache, it's failing when the service is called (for timestamp), the service has the error, and the InvalidOp is raised when I go to call the serivce (.net errors before messages is sent). – Mr Shoubs Jan 17 '14 at 12:51
  • @mostruash, I suspected as much, thanks for the clarification. – Mr Shoubs Jan 17 '14 at 12:52

2 Answers2

2

The only way I see to get it done is to move to a Transport-only security in your client and then add the security header yourself in a custom encoder. Generating the security header includes:

  1. Generating the timestamp and pushing it in to the SOAP (easy).
  2. Generating the signature (hard). See here and the GetSignature commented our method here. Then push it to the SOAP.

To manipulate the SOAP implement the encoder and in the the WriteMessage method where you have access to the message load it to XmlDocument and manipulate it (e.g. add the headers).

Yaron Naveh
  • 23,560
  • 32
  • 103
  • 158
-1

If you're running your WCF host with IIS, you could add a custom-written Module - a .NET DLL - that intercepts the message in IIS, reads, parses and removes the seconds, then passes the message on to your WCF service.

As I recall, the module program picks up and reads the HTTPContext, allowing you to alter the message any way you like, even adding entirely new fields to the header and body sections.

But this approach only works if you're using IIS to front or manage your web service.

Here's a link to it: http://www.iis.net/learn/get-started/introduction-to-iis/iis-modules-overview#Querying

Jeroen
  • 1,168
  • 1
  • 12
  • 24
Brian
  • 3,653
  • 1
  • 22
  • 33