Blog Home  Sign In RSS 2.0 Atom 1.0 CDF  

  def Softwaremaker() :
         return "William Tay", "<Challenging Conventions />"

  knownType_Serialize, about = Softwaremaker()
 

 Friday, July 07, 2006

Blasphemy ...

It is finally published. After many, many, and I mean, many months of paying the process tax for this piece, it is finally LIVE !

I started this piece with the first ever March 2005 CTP of Windows Communication Foundation (WCF, previously - Indigo) and I went through so many port demos and edit document cycles its so unbelievably painful ...

But it is really good to see this in online form and shape.

I started with this idea even though MSFT Corp has explicity stated that it will not support any form of interoperability between WSE 2.0 and WCF, even though it is "theoretically possible to develop Web services using WSE 2.0 in such a way that they can interoperate with WSE 3.0 (and WCF) by using only a reduced set of specifications"

More importantly, the main reason for the motivation to write such a piece is written in the article itself and I quote:

[BEGIN QUOTE]


...WSE 2.0 has seen 3 service pack releases since its official launch in 2004. It implemented the OASIS Web Services Security 1.0 specification which was the widely accepted interoperability standard protocols between secured web services as well as the implementations of WS-Addressing, WS-SecureConversation and WS-Trust. It was integrated very nicely into Visual Studio 2003. Even BizTalk Server 2004 carries with it a WSE 2.0 adapter for securing of Web Services. Thus, it would be fair to assume that there is more than its fair share of implementations in the market today.

 

Depending on timing, budget, complexity and a whole host of other requirements, some of these applications will need to be moved and migrated to WSE3.0 and some to WCF. Aaron Skonnard has provided a great resource in his “Service Station” column on MSDN on a brief overview on the migration of WSE 2.0 applications to WSE 3.0 ones. However, as stated in his article, there are some major changes in the programming model and architecture in WSE 3.0 and migrating them from WSE 2.0 may not be trivial.

Another very important factor to take note is while WinFX, and therefore WCF, is available downstream from Windows Vista to Windows 2003 and Windows XP. That is as far down as it goes. There still exists a huge installed base of Windows 2000 Servers out there running on server and data farms and if you need to implement the advanced Web Services stacks on those servers, WSE is still a very important strategy you cannot ignore.

As noted in the above guidelines, even though Microsoft will not guarantee interoperability between WSE 2.0 and WCF, the good news is that there are a few WSE 2.0 common scenarios, which can allow wire-interoperability with WCF. I will illustrate them in the next section...


[END QUOTE]

 

So, this article will outlined WHAT that reduced set of specifications are and HOW to go about using them.

Many Special Thanks go to Kirill, the Interop PM on WCF, who gave me a couple of tips to get over the port-over humps I had thoughout this piece since last year. And of course, I cannot forget Clemens, who is the catalyst to making this publication happen when he came onboard.

I hope this helps at least someone out there. Enjoy !

Friday, July 07, 2006 6:11:57 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Friday, February 03, 2006

    Not quite as complicated as it may sound.

    Web Services Enhancements (WSE) 3.0 allows that re-usability element aspect. Say I am writing a ASMX 2.0 service with an intent to host it in another [internal ?] process via another transport (TCP, SMTP, MSMQ), I can easily do so.

    The *.asmx file that contains

    <%@ WebService Class="SomeSWMNamespace.SomeSWMService"%> is equivalent to WSE 3.0's

    Protected Overrides Sub OnStart(ByVal args() As String)
        Dim address As Uri = New Uri("soap.tcp://swm/someSWMwindowsservice")
        SoapReceivers.Add(New EndpointReference(address), GetType(SomeSWMStockService))
    End Sub

    that is hosted via a Windows Service Process. Of course, the architecture of ASP.NET and IIS specifies the vDir and the physical *.asmx file as the physical endpoint address while you get to specify your own if you host it via another process.

    In other words, the IHTTPHandler class for asmx endpoints and the Winows Service are different processes accessible via different transports (Http and Tcp) but hosting the same codebase. Incidentally, this codebase is a .NET Class Library with all the fanciful attribute decorations:

    <WebServiceBinding(Name:="SomeSWMService", _
       Namespace:="urn:ns.softwaremaker.net-someService", _
       ConformsTo:=WsiProfiles.BasicProfile1_1, EmitConformanceClaims:=True)> ...

    <WebService(Namespace:="urn:ns.softwaremaker.net-someService")> _
    <Policy("SWMTracePolicy")> ...

    Friday, February 03, 2006 10:29:59 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Thursday, January 12, 2006

    With regards to my post here, I thought I expand on one of many enhancements that WS-Security Specifications 1.1 brings.

    "MutualCertificate11Security" assertion is one of the few security turnkey assertions in Web Services Enhancements (WSE) 3.0 and what basically it is is that the client and server are authenticated using X.509 certificates (X509SecurityToken). Message-level security is implemented using X509SecurityToken security tokens. This turnkey security assertion requires WS-Security 1.1

    Once that is configured and implemented properly, it is rather interesting to see what transcends on the wire. Here is a brief snippet:


    [wsse:Security soap:mustUnderstand="1"]
    ...
    [wsse:BinarySecurityToken ValueType="...oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="...wss-soap-message-security-1.0#Base64Binary" wsu:Id="SecurityToken-76ae..."]MIIBvD...[/wsse:BinarySecurityToken]

    [xenc:EncryptedKey Id="SecurityToken-6ec8..." xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"]
    [xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"]
    [ds:DigestMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /]
    [/xenc:EncryptionMethod]
    [KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"]
    [wsse:SecurityTokenReference]
    [wsse:KeyIdentifier ValueType="...oasis-wss-soap-message-security-1.1#ThumbprintSHA1" EncodingType="...oasis-200401-wss-soap-message-security-1.0#Base64Binary"]qRTA40Xfk6w1Os3mgpgy8UgwR/Y=[/wsse:KeyIdentifier]
    [/wsse:SecurityTokenReference]
    [/KeyInfo]
    [xenc:CipherData]
    [xenc:CipherValue]hBfCfVmg...[/xenc:CipherValue]
    [/xenc:CipherData]
    [xenc:ReferenceList]
    ...
    [/xenc:ReferenceList]
    [/xenc:EncryptedKey]

    [Signature Id="Sig-b679..." xmlns="http://www.w3.org/2000/09/xmldsig#"]
      [SignedInfo]
      [ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" /]
      [SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1" /]
      [Reference URI="#Id-5cdc..."]
      ...
      [/Reference]
      [/SignedInfo]
      [SignatureValue]O/PdsVMS4PTIBtrx8eyFNzbTnjc=[/SignatureValue]
      [KeyInfo]
      [wsse:SecurityTokenReference]
      [wsse:Reference URI="#SecurityToken-6ec8..." ValueType="...oasis-wss-soap-message-security-1.1#EncryptedKey" /]
      [/wsse:SecurityTokenReference]
      [/KeyInfo]
    [/Signature]

    [Signature xmlns="http://www.w3.org/2000/09/xmldsig#"]
      [SignedInfo]
      [ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" /]
      [SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" /]
      [Reference URI="#Sig-b679..."]
      ...
      [/Reference]
      [/SignedInfo]
      [SignatureValue]PDm4wS+3hzmXugHL1wcTWZXHcaGKkODVHU48XvVNC6catxiOr25
    xq9AGN8u8CgYo1JlnoEf2tuCUl86krKiUBSnMR/towfAs2doGg6a+vtjIl9F54c/VZtTPgwn
    QdZtJ28E8+ep5MIS2i+9Tamnui6qpX16IS3J1FcMjVBHQpMs=
    [/SignatureValue]
      [KeyInfo]
      [wsse:SecurityTokenReference]
      [wsse:Reference URI="#SecurityToken-76ae..." ValueType="...wss-x509-token-profile-1.0#X509v3" /]
      [/wsse:SecurityTokenReference]
      [/KeyInfo]
    [/Signature]
    ...



    One thing that you will noticed is that there are 2 Digital Signatures generated.

    The first one has a ReferenceID, which hints that it will be subject to encryption/signatures later on, and it is signed by a EncryptedKey type (which I talked about in my earlier post). Because it is encrypted by a symmetric key "#SecurityToken-6ec8", the [SignatureValue] is rather short and this signature basically signs the soap:Body with an URI of "#Id-5cdc..." The [EncryptedKey] value can be decrypted and derived by the server's private key

    The second signature basically signs the first signature (#Sig-b679...) and it signs it with the Client's Private Key that only the corresponding Public Key Pair can decrypt. The Public Key, together with the client's cert is sent over the wire via a [wsse:BinarySecurityToken] (#SecurityToken-76ae...). Because an asymmetric key is utilized here, the [SignatureValue] is relatively longer than the first signature.

    As we can see from here, the first signature signs the soap:Body and the second signature signs the first signature. These are generally known as "Supporting Tokens". These additional tokens may be specified to augment the claims provided by the token associated with the “message signature” provided by the Security Binding. Supporting tokens may be specified at a different scope than the binding assertion which provides support for securing the exchange.

    There are four properties related to supporting token requirements which may be referenced by a Security Binding: [Supporting Tokens], [Signed Supporting Tokens], [Endorsing Supporting Tokens] and [Signed Endorsing Supporting Tokens]. Four assertions are then defined to populate those properties: SupportingTokens, SignedSupportingTokens, EndorsingSupportingTokens, and SignedEndorsingSupportingTokens.

    What I have shown above is known as the [EndorsingSupportingTokens].

    The [SignedEndorsingSupportingTokens] is a combination of [SignedSupportingToken] and [EndorsingSupportingToken] and I will talk about that in a future post.

    Wednesday, January 11, 2006 5:06:42 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Tuesday, January 10, 2006

    I have been back fiddling at the Web Services Enhancements (WSE) 3.0 technology space for the past few weeks and I am now grokking into the plumbings since there are quite a few forums, blogs, posts out there focusing on the higher-level abstract programming model.

    I am very pleased that WSE 3.0 has implemented WS-Security Specifications 1.1 at its very core, so much so that it is the de-facto security standard to be used in most of the Turnkey Security Assertions that comes with the product.

    One of the things that I have always been asking for through my contacts and channels in the OASIS WS-Security Technical Committee is the ability to sign my document snippets with a symmetric key instead. Since XML-Encryption already utilized symmetric key encryption via the [xenc:EncryptedKey] [1] for performance and throughput reasons, there is no reason why XML-Digital Signature cannot do the same. While the improvements in throughput may be slight due to the fact that in digital signatures, messages are already hashed before encryption, it is still a viable option that should be made available.

    In WS-Security 1.0, this is what is commonly seen in the Digital Signature Parts:


    ...
    [wsse:BinarySecurityToken ValueType="...oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="...oasis-200401-wss-soap-message-security-1.0#Base64Binary"
    wsu:Id="SecurityToken-7b5d..."]MIIBxDCCAW...[/wsse: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="#Id-f7e1..."]
      [Transforms]
      [Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /]
      [/Transforms]
      [DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /]
      [DigestValue]avMezj5NhZwNerXidi5oBmjqi/g=[/DigestValue]
      [/Reference]
      ...
      [/SignedInfo]

    [SignatureValue]SJfnqZeDHboWDI2n2gWHqTJO5hXvZOFQw8UtDdajktzR40H+W6D
    prs5CW/l9A5TF3xcFfyryA3hz7c+0vdlZSnaA+cBn2qPxt7/YmwaAx5Ave
    awuach6YPYI123I4I3f58eSMUgPsx6/uuFQFcJltEMw1nWLE6Wb6CPg5OdtXLs=
    [/SignatureValue]
      [KeyInfo]
      [wsse:SecurityTokenReference]
      [wsse:Reference URI="#SecurityToken-7b5d..."
    ValueType="...oasis-200401-wss-x509-token-profile-1.0#X509v3" /]
      [/wsse:SecurityTokenReference]
      [/KeyInfo]
      [/Signature]


    Now in WS-Security 1.1 via WSE 3.0, I can do this:


    [xenc:EncryptedKey Id="SecurityToken-32e4..." xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"]
      ...
      [wsse:SecurityTokenReference]
        [wsse:KeyIdentifier ValueType="...oasis-wss-soap-message-security-1.1#ThumbprintSHA1" EncodingType="...oasis-200401-wss-soap-message-security-1.0#Base64Binary"]qRTA40Xfk6w1Os3mgpgy8UgwR/Y=[/wsse:KeyIdentifier]
      [/wsse:SecurityTokenReference]
      [/KeyInfo]

    [xenc:CipherData] 
    [xenc:CipherValue]n6PnkIWb+QsIeOPehLdtQQKYZn202uGqhN+ShCWyBaCf20rmVcta
    Bw2MhB1fv9pE0hOLpAxMMT5ffk4/hnwZ/ef2XcZediF6ySfpse14TI2TGy
    cp9XErpeYlZNn1wSchHlOEz2gVYfViZoEOIwn8qR7EofLN3U3Mc5Zp2qG2coI=[/xenc:CipherValue]
      [/xenc:CipherData]
      [xenc:ReferenceList]
      [xenc:DataReference URI="#Enc-0914..." /]
      [xenc:DataReference URI="#Enc-3aab..." /]
      [/xenc:ReferenceList]
      [/xenc:EncryptedKey]
      [xenc:EncryptedData Id="Enc-0914..." Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"]
      [xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" /]
      [xenc:CipherData]  [xenc:CipherValue]RLASn...[/xenc:CipherValue]
      [/xenc:CipherData]
      [/xenc:EncryptedData]

    [Signature xmlns="http://www.w3.org/2000/09/xmldsig#"]
      [SignedInfo]
      ...
      [SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1" /]
      [Reference URI="#SecurityToken-d217..."]
      [Transforms]
      [Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" /]
      [/Transforms]
      [DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /]
      [DigestValue]A0K7OVwZN3vP4rIXfbTZYy+f+ck=[/DigestValue]
      [/Reference]
      [Reference URI="#Timestamp-6f12..."]
      ...
      [/Reference]
      [/SignedInfo]
      [SignatureValue]d8KmXpfspmKiEOZ1eBVY7mk05Wo=[/SignatureValue]
      [KeyInfo]
      [wsse:SecurityTokenReference]
      [wsse:Reference URI="#SecurityToken-32e4..."
    ValueType="...oasis-wss-soap-message-security-1.1#EncryptedKey" /]
      [/wsse:SecurityTokenReference]
      [/KeyInfo]
    [/Signature]


    Note the fonts in RED. There is a new URI: http://docs.oasisopen.org/wss/oasiswss-soap-messagesecurity-1.1#EncryptedKey which ties to a ValueType: A token type of an [xenc:EncryptedKey]

    ... and more importantly ...

    the [SignatureValue] contents is slightly shorter now because it is actually encrypted with a symmetric key now. I know I may be picking here BUT hey, even a single byte in reduction means a lot in throughput performance in terms of wire transfer of documents. .

    There are other improvements WS-Security 1.1 brings over its predecessor 1.0, which I will blog more about as I go along.

    [1] Just a note to defuse any confusion if it crops up: Asymmetric (Public-Private) key technologies are still very much used in WS-Security and other document-related security specifications today. I dont think it will be dropped anytime soon unless Quantum Cryptography takes off mainstream in a big way or the subtle effects of this reverberates adversely through the security space. Having said that, Symmetric (Master/Session) key technologies have a huge place in the security specifications world too, just by the fact that it is a 1000x faster than much-secure asymmetric ones. Therefore, both technologies co-exist and work very well together in the document security space. To put it simply, a symmetric key (KeyA) is randomly-generated (key-length can be specified by the application - the longer, the better) and then used to encrypt/decrypt messages (MsgA). Once that is done - KeyA is then subsequently encrypted by an asymmetric key (KeyB) and then transmitted through the message. Only the holder of the Private-Key pair of KeyB will be able to decrypt KeyA which can then decrypt/encrypt MsgA.

    Monday, January 09, 2006 9:41:51 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Monday, October 24, 2005

    In Web Services Enhancements (WSE) 2.0, one could exercise some control over what one xml element/fragments wants to encrypt within a soap:Body. Therefore, if I wanted to encrypt the account string in my credit card type, I could do something like this:

    [At your Service Side]


    Public Class SecuredCreditCard
      <XmlElement(ElementName:="CreditCardType")> _
      Public Type As String
      <XmlElement(ElementName:="CreditCardAccount")> _
      Public Account As SecuredString
    End Class

    Public Class SecuredString
      'Set the Oasis Id that our security reference will point to
      <XmlAttributeAttribute("Id", _
    Namespace:=".../2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")> _
      Public ID As String
      <XmlText()> _
      Public Data As String
    End Class

    [At your Calling side]


    Dim a As localhost.IndexWse = New localhost.IndexWse
    Dim b As localhost.SecuredCreditCard = New localhost.SecuredCreditCard
    Dim z As localhost.SecuredString = New localhost.SecuredString

    Dim c As SoapContext = a.RequestSoapContext

    b.CreditCardType = "VISA"
    z.Id = "uri:demoId.softwaremaker.net" 'or some guid
    z.Value = "123-456-789"
    b.CreditCardAccount = z

    c.Security.Elements.Add(New EncryptedData(tok, "#uri:demoId.softwaremaker.net"))

    Note: To reduce headache-inducing typo bugs, you may want to use some WSE Constants such as
    WSUtility.Prefix
    WSUtility.AttributeNames.Id
    WSUtility.NamespaceURI

    The end result of this is a soap:Body on the wire looks like this:


    <SecureCreditCard>
     <CreditCardType>VISA</CreditCardType>
     <CreditCardAccount d4p1:Id="uri:demoId.softwaremaker.net" xmlns:d4p1=".../2004/01/oasis- 200401-wss-wssecurity-utility-1.0.xsd">
      <xenc:EncryptedData Id="EncryptedContent-3d793117-f020-4236-a0a0-0ed545d9bf1a" Type=".../2001/04/  xmlenc#Content" xmlns:xenc=".../2001/04/xmlenc#">
      <xenc:EncryptionMethod Algorithm=".../2001/04/xmlenc#aes128-cbc" />
      <xenc:CipherData>
      <xenc:CipherValue>FRFCiq...+0W5oS4</xenc:CipherValue>
      </xenc:CipherData>
      </xenc:EncryptedData>
     </CreditCardAccount>
    </SecureCreditCard>

    While I dont know how much of performance benefits this has over one that has the entire SecureCreditCard encrypted (since it is an symmetric-key encryption at its core), I think in terms of latency and throughput, it does offer some benefits especially with a sizable payload (>20-30 kb, for instance ?)

    Windows Communication Foundation (WCF, previously - Indigo) does not currently have that feature build in at the moment (Sept05-CTP or known as the PDC-bits). In other words, in WCF today, you encrypt the entire contents of the soap:Body, lock-stock-barrel. I would still love that WSE feature in there: To be able to exercise finer grain control over what I want to or not to encrypt within a soap:Body.

    Would really like to find out if I am the only odd one out there. Any users using that existing WSE feature out there that would love to see the same in WCF or do you have other better ideas ? Leave a comment or email me via the contact link on the side. Thank you.

    BTW: Whether you encrypt certain elements of the contents or encrypt the entire contents of the soap:Body, both are WS-Security Specifications compliant.
     

    Monday, October 24, 2005 1:00:00 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Saturday, June 04, 2005

    Web Services Enhancements (WSE) 3.0 CTP is released.

    Here it is. The runtime is here. The notes for the CTP are here. The HOLs are here and here. Go geek out !

     

    Saturday, June 04, 2005 7:50:13 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Friday, March 18, 2005

    I know I have not been posting some real technical stuff on my blog for the last few months...and this is the reason why.

    It started off with a Proof-of-Concept I was working on and some thoughts on WS-Security Headers here. Finally, after months of hard work and long review and edit cycles, one of my 'masterpiece' articles has made it to MSDN Web Services Center. From what I understand from MSFT-Singapore, it is the first time a Singapore Flag is flown on MSDN. Gotta like that. Cool...

    Do check it out here and let me know what you think.

    While this architectural setup may come across as 'complicated' and slightly 'unorthodox' in the real world today, I believe we will see more and more setups of this model as we go along with the wide-acceptance of (standards-based) messaging-based systems in the enterprise mainstream. Key-word here is standards-based. Another thing that I believe will happen with Service-Orientation is that this routing/gateway style approach will become the primary extensibility model.

    Indigo will go a long way in making this happen and I am very excited with the impending launch of it this year. Incidentally, the March CTP Bits of Indigo and Avalon is available to MSDN Subscribers and I believe to the general public soon. Keep your eyes out for it.

    What's next ? I will be crossing over to do more Indigo stuff and there are work assignments for me that is revolved around Indigo-WSE-SOAP. I will update here as we (me, Indigo-bits, WSE*-bits) go along.

    Thanks a million to MattP, MarkF and HerveyW for helping me out with this write-up ... and Sorry, Matt for the constant bombardment of emails and queries.

    Friday, March 18, 2005 12:54:11 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Friday, March 04, 2005
    Benjamin Mitchell has written a great article on "Why WSE". On the same note, I have a similar one here.
    Thursday, March 03, 2005 10:43:10 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Monday, February 28, 2005

    I was just alerted by Julie about the availability of WSE 2.0 SP3. I must say, she has got her eyes and ears on the ground. Any new releases in some hidden corner, bet on her to find it first.

    However, I am going to give this a pass. I believe it is just a version with bug fixes and patches and probably, better documentation. Microsoft BizTalk Server 2004 is keeping me fairly busy for the moment so I will just sit tight and wait for WSE 3.0 followed by Indigo

    [AUTHOR UPDATE]: The ReadMe for WSE2SP3 is found here. It is a very targeted fix covering stress, security and perf issues

    Monday, February 28, 2005 2:36:51 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Friday, February 18, 2005

    Benjamin points to a great tool from MSFT Corp Research in Cambridge that acts as a security diagnosis tool for WSE2 policy files...

    Worth trying and looking into even though it is unsupported...Since when is a product or tool that rolls out from Research supported in the commercial production world anyways...

    Another +1 for Microsoft for the raising awareness in security, esp in the realms of XML SOAP Services.

    Friday, February 18, 2005 12:43:51 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Sunday, February 06, 2005

    SDA-Asia has recently published one of my articles online. In this article, I talked about how Web Services Enhancements (WSE) can be used to solve Real-World business problems with some proper thought and design processes.

    This is not as technical an article comparred to the ones I have written before, however, I feel it gives a good overview and insight to what the advanced XML services are and how to make use of some of them to solve some of the business problems of today...and needless to say, WSE 2.0 is THE tool to do that today in .NET

    I have spent a fair amount of time writing up a REAL technical article (on WSE, of course) recently which I hope will get published soon enough. Will update all once it goes live. Enjoy.

    Sunday, February 06, 2005 1:00:31 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Tuesday, January 25, 2005

    William Stacey has outdone himself again. He has blogged on how to create SecurityContextTokens without X509 Certs.

    He has beaten me to it. As I have said in a comment to his blog:

    ...I knew something like that would be very useful and there are tons of requests out there for the use of SCT without X.509 because of cost issues or the server admin doesnt want to install them for whatever reasons.

    I was on my way to implementing it, then I took some time off to look at the specifications for the exchange of entropy values, then I got derailed by some work committments and after that I just got lost...

    It is so good for you to come up with this. It is excellent. I would have to try it and feedback. Many people will thank you for it.

    Julie, if you are reading this, hopefully this will help solve a problem of yours that is way loooong overdue.

    Tuesday, January 25, 2005 11:26:20 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Wednesday, January 19, 2005

    I recently extended a chat program written in Web Services Enhancements (WSE) 2.0 utililizing the TCP transport protocol. I wanted it to run over the internet now. This was prompted by some members of our Singapore Professional DotNet Usergroup who wanted to implement a mini Pub-Sub (aka WS-Eventing) project using the tcp protocol.

    They had indicated that they had some trouble binding the FQDN specified for the URI in the EndpointReference to a local network interface. If this cannot be resolved, the binding will fail.

    At the most basic level, the EndpointReference.Address is both the name of the target and its location. For example, [http://localhost/SomeService] can be used as a name and a transport address. WSE 2.0 comes with an extended model to allow a single named service to be hosted on multiple transport addresses. This can also be useful if we want to apply a single corporate policy on them.

    This is where EndpointReference.Via comes in. It allows you to host a well-known service that can only be accessible via different transports such as the soap.tcp protocol of WSE 2.0 and others.

    For example, my well-known service is hosted at soap.tcp://softwaremaker.net:2088 (or soap.tcp://219.74.47.214:2088, if you dont have a DNS tagged to it). This is the public FQDN address of the service. For the broadband cable and ADSL users of dynamic IPs, this address may be the address of your home network router.

    Now, your WSE 2.0 application has a SOAP Receiver object that allows your application to listen for SOAP requests coming in on WSE2-custom defined transports. Once you define your own address on your own listening machine such as soap.tcp://192.168.2.100:2088/Softwaremaker, you would now have 2 URIs:

    Public Facing: soap.tcp://softwaremaker.net:2088
    Private Internal: soap.tcp://192.168.2.100:2088/Softwaremaker

    The Public Facing well-known URI becomes the EndpointReference.Address while the transport address mechanism becomes the EndpointReference.Via

    In other words, soap.tcp://192.168.2.100:2088/Softwaremaker will listen for any messages that is sent to soap.tcp://softwaremaker.net:2088 (the address element in the WS-Addressing headers). Put it in another way, the custom soap.tcp transport will only accept messages sent to soap.tcp://softwaremaker.net:2088 if they arrive via the internal address:192.168.2.100.

    The Via address is not in the message itself, only the well-known URI is. Based on the network address the message is being received on, the custom soap.tcp transport mechanism will know how use both well-known and private URIs to dispatch the message to the registered and configured-properly SOAP Receiver.

        EndpointReference EPR = new EndpointReference
        (new Address(new Uri("soap.tcp://softwaremaker.net:2088")),

        new Via(new Uri("soap.tcp://192.168.2.100:2088/Softwaremaker")));

        SoapReceivers.Add(EPR, yourOwnSoapReceiver);

    The last step you need to take is to be able to forward all requests going to the well-known URI (soap.tcp://softwaremaker.net:2088) to your local machine with the internal IP 192.168.2.100:2088

    This is not something you can do in WSE 2.0 or in your machine. This has to be done at your broadband or cable router. You just have to forward requests coming in to your Public port:2088 to the Private port:2088 of machine 192.168.2.100 (Note that these ports doesnt have to be the same number at all)

    Of course, the huge assumption is that you have control over the port routing and forwarding of your broadband or cable router (which may be rather tricky if you are within a corporate or organizational boundary) BUT technically, you will be able to carry out a p-2-p SOAP message chat or even do a Pub/Sub model approach with your own implementation of the “Notification” and “Solicit-Response” message-exchange patterns over the internet using the custom soap.tcp protocol of WSE 2.0

    [Author Note] What do ya know ? I just found that that Hervey has got an even better post on the EndpointReference.Via of WSE 2.0 here.

    Wednesday, January 19, 2005 1:47:59 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Thursday, January 13, 2005

    William Stacy has a new blog in MSN Spaces and he blogged about a topic that has spurned from recent activities in the WSE newsgroups.

    It is about the security and the use of username tokens in the real world, specifically when it relates to passwords being stored as hash in the user database.

    William proposes a method here to solve the issue of how to authenticate username tokens embedded in _WS-Security Specs_ security headers.

    In my own opinion, his case represents a very major common representation of how passwords are stored in the database. They are mostly and SHOULD be hased. To add another realm of security, SALT is used. However, I dont really agree that his method may prove to more secure. In fact, I think it gives a somewhat false sense of security (and William, please correct me if I am wrong anywhere).

    1)   By using your verifier as a matching mechanism to gain authentication, then this verifier (SALT Hash and all) effectively becomes a password. If Mallet steals the hash from the user database, nothing prevents him/her from writing a client that sends the hash and thus he would authenticate successfully. This is exactly what the hash scheme is trying to avoid in the first place.

    If used this way, the hash is no safer than storing the passwords in clear text in the database...which ultimately means that the weakest link is still the security of the Username Database which must be protected at all costs.

    In other words, this must be made known clearly so that it doesnt preach a false sense of security that people think that this scheme NOT only protects their cleartext password BUT also their SOAP calls as well.

    This post here explains real well on my thoughts as well.

    2)   SALT should be a completely random value and should be algorithmically introduced to further obfuscate the one-way hash. In your approach, it seems that the SALT is tied very much to your username (am I wrong ?). This doesnt help much because I dont need to guess your publicly-available username, there are only a handful of hashing algorithms out there and you are NOT passing any SALT into your PasswordDeriveBytes constructor. In fact, the only saving grace is the iteration count which basically sets the number of iterations for the operation. Is that enough ? I believe it may serve well for some smaller-scale simpler systems BUT I dont know how it sits well with some of the security policies of bigger enterprises.

    IMHO, I think the current username tokens as defined by WS-Security doesnt fit very well into most EXISTING user databases which store passwords as hashes which may or may not be SALTED. I dont think there is a clean way to do this in WSE without using or representing the hashes as passwords. However, I am still thinking about this issue and will blog more about it later if (not when) I reach enlightenment.

    Your approach, however, does allow passwords to remain as they are in the EXISTING user databases. The only obstacle you require is a change in the schema of that table, which requires management approval and buy-in and usually triggers off many other related procedures, and that in my experience, is sometimes harder than finding the password from a hash.

    [Author Note]: This topic has got nothing to do with the security of username tokens as I have blogged about earlier here. This is all about the authentication of username tokens with the stored credentials in the user databases.

    Wednesday, January 12, 2005 11:09:54 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Wednesday, January 12, 2005

    After installing Web Services Enhancements (WSE) 2.0 SP2, the most natural thing for me to do is to run my previous WSE 2.0 SP1 projects and see if it works with the new assembly.

    Most of it still do run <phew>. A couple of them (specifically the SOAP Routing ones) did NOT run as intended. A further drilldown into the code revealed that the ExtendedSecurity doesnt serialize properly if you are planning to send another set of Security Headers to the next SOAP node...In fact, it doesnt get serialized at all.

    ...Obviously, this next node cannot be the ultimate soap receiver as target service cannot process 2 security headers as specified in the _WS-Security Specs_. You can refer to my previous discussions with HerveyW here and here.

    So, if your next node is another SOAP Router and you need a different set of Security Headers for the next node to process, this is how to do it with the ExtendedSecurity function in SP2:

    You need to add a Security Utility Timestamp into the Security Header in order for the ExtendedSecurity function to serialize a new set of Security Headers properly.

    Dim t As Utility.Timestamp = AnotherSecurityHeaderBlock.Timestamp

    Thereafter, when you call the ExtendedSecurity function and add this new Security Header block, the serialization will take place.

    In SP1, it is NOT necessarily for you to add this timestamp.

    The WSE team has confirmed this as a workaround to this minor bug.

    Wednesday, January 12, 2005 10:38:07 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Saturday, January 08, 2005

    I have recently installed SP2 of Web Services Enhancements (WSE) 2.0 over my previous installed version of SP1.

    From my first views of it, it seems that I would uninstall it and re-install the older copy of SP1 again. This has got nothing to do with SP2 itself BUT the WSE SOAP tracing utility that I used before with SP1 doesnt work with SP2.

    I have been using Mike Taulty's WSE 2.0 Tracing Utility for some time now and I have nothing BUT the best things to say about it. It really helps in my demos that I have done for the past year, including the very successful ones I have done in MS TechED Asia 2004. However, it doesnt work in this new SP2 version of WSE 2.0

    To trace the WSE SOAP trails in SP2, I switched over to Simon Guest's Trace Tool. Although it works well due to the difference in how they captured their traces, I dont really like Simon's WSE 2.0 Trace Tool. Sorry, Simon. Love all your interoperability works and presentations plus all the efforts you have done revolving around interoperability, just not this tool.

    Let me explain briefly what their differences are (performing my own dissection):

    Mike's WSE Tracing Utility, I believe, works based on filters and streams. It needs some configuration to set this utility up so that its own trace filters can intercept the (W3C) SOAP messages. It then outputs and writes the captured traces into its console and present it via log message style. I believe it does so using the System.IO.Stream classes. I dont even have to turn on the diagnostic properties of WSE 2.0. Very ingenious, to say the least.

    Simon's WSE Trace Tool works slightly differently. There is zero configuration on this Trace Tool. Only thing you need to do is to turn on the diagnostic properties of WSE 2.0. It works by reading the diagnostic files that are churned by WSE 2.0. Therefore, it can only output the results after the code has run. It uses either a Timer or a FileSystemWatcher basis to capture any new writes to the diagnostic files. Therefore, it is NOT as real-time as I would like it to be.

    Therefore, from the looks of it, Simon's WSE Trace Tool seems to offer the best chance in terms of integration with the new WSE 2.0 releases. However, it is just NOT as friendly and intuitive as I like it to be.

    Mike's WSE Tracing Utility also offers a quick one-glance understanding of what is the output and input of the traces are. With Simon, it doesnt. I have to figure out and remember the upper pane is the output trace while the lower pane belongs to the input trace.

    And the main thing to me separating those two is that I dont have to turn on the diagnostic properties of WSE 2.0 for Mike's tracing utility. If I turn that on, I have to remember to turn it off once I move it into a production system as the diagnostic files are kept, “logging style”, and it does bloat. What is worse, every write into it appends an entire brand new SOAP message into it and we all know how verbose SOAP can get, with all the new WS SOAP headings and such...and as the file gets bigger, the writes will take longer and it will directly impact on the run-time performance of the entire application.

    It doesnt take much to google'd and newsgroup'd the web and you will find that some of the initial hiccups of WSE 2.0 is with regards to the run-time performance of it as the longer it runs. Turning off the diagnostic properties solves this issue right away.

    Another thing that I dislike about these diagnostic files is that I cannot delete them right away. IIS has a timing lock on them and only when I reset IIS, then I can delete them. Although it is not directly linked to Simon's Trace Tool, I can only delete them from the console after I reset IIS which means a toggling of windows. It is still a disadvantage to Simon's way of capturing the traces. Since Mike uses a stream, there is no file lock to speak of. The only persistant traces are in his console, not in the files, which makes it much more efficient and cleaner.

    Simon's trace tool also has a pesky bug that frustrates me. You have to pick a project folder for him to scan for the trace files. Most times, we have many project folders in a solution directory (for example, SOAP Routing Projects). Therefore, it doesnt work well if I want to capture the trace diagnostics of all projects of a solution. Even if I set the solution folder to be the project folder, it doesnt seem to scan and pick out all the trace files found in all the project folders of the the root folder. It seems, to me, to only display the trace files found in the last-scanned project folder. . This has a big impact on the aesthetics, especially when I am doing WSE 2.0 demos to a large audience, which I do, quite a fair bit.

    Mike's trace utility, again, got into my good books for this. Because his is based on a stream approach, all “configured-properly” projects of the same solution will be written to the console and displayed very nicely and logically so that anyone can view and understand it right away.

    Lastly, there is something about Mike's trace utility that generates the trace outputs as the WSE 2.0 code runs on the fly that always...and I mean always, gets the WOW out of the audience and that to me, is the single most important factor that makes me swear by his trace utility anytime, anyday...

    So, Mike, if you are reading this, this is a call for your action to fix the issues so it can work with WSE 2.0 SP2 as thousands of people like me are waiting and will Thank you for it. Even more so, many more people in the audiences will Thank you for it too as well because it does help them understand WSE 2.0 and all its related WS SOAP headings a little bit better.

    [Author Note: Mike has graciously fixed the Trace Utility so that it works with WSE 2.0 SP2 now. It can be downloaded from his blog here.]

    Friday, January 07, 2005 10:42:21 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Saturday, December 11, 2004

    With reference to my earlier post here, I had explained how we can encrypt the Usernametoken element <wsse:UsernameToken> if we choose to use the PasswordOption.SendPlainText enumeration, for real-world reasons such as

    • Windows Authentication
    • Passwords are stored as Hash in the UserDB

    Other elements in the <wsse:Security> Header element can be encrypted too, although great care and design must be taken as it may reduce the extensibility of SOAP Headers through routing intermediaries. One of them is the <Signature> element.

    As I had explained in another post here, digital signatures can and may be verified for authentication and trust by any SOAP node. If the <Signature> element is encrypted, we may be preventing any SOAP intermediary from authenticating and verifying the digital signature. Unlike digital signatures, <xenc:EncryptedData> elements are encrypted for a specific receiver in mind and therefore, only that one party SHOULD be able to decipher it with a corresponding Private key or shared secret. SOAP intermediaries, trusted or not, SHOULD NOT be able to decrypt or view the the encrypted content(s) and therefore cannot authenticate and verify the signature.

    However, if one should decide that their dispatching mechanism is based on a non-intermediary route or if the <Signature> element may not be meant for the ultimate SOAP receiver and therefore can be removed by the SOAP intermediary, this can be done easily as well with WSE 2.0.

    The key is to create a MessageSignature on its own and assign it an ID. Here is the code snippet on how to implement it:


    Dim a As New MessageSignature(yourSignatureToken)
    Dim g As Guid = g.NewGuid
    a.Signature.Id = g.ToString

    '...

    Context.Tokens.Add(yourSignatureToken)
    Context.Tokens.Add(yourEncryptionToken)
    Context.Elements.Add(a)
    Context.Elements.Add(New EncryptedData(yourEncryptionToken, "#" & a.Signature.Id))

    And the wonderful result that comes out from the oven: (geez...I need a life )


    <wsse:Security soap:mustUnderstand="1">
    <wsse:BinarySecurityToken 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="SecurityToken-e8f64eea-1d63-4db2-943c-9bfb5dfccbfc">MIIBxDC...du2fPMER8ajJfl</wsse:BinarySecurityToken>
    <wsse:UsernameToken wsu:Id="SecurityToken-3370d9ae-deb9-4a01-9b9c-c8dd072568fa">
    <wsse:Username>ABC</wsse:Username>
    <wsse:Nonce>Amx9amrLXR02etJLsNwdwA==</wsse:Nonce>
    <wsu:Created>2004-12-11T07:38:33Z</wsu:Created>
    </wsse:UsernameToken>
    <xenc:ReferenceList xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
    <xenc:DataReference URI="#EncryptedContent-0e6936bf-67a5-48a5-ba8a-d9ba6141e75f" />
    </xenc:ReferenceList>
    <Signature Id="2c091bb3-bcdc-4da1-97c5-dcd60dac7312" xmlns="http://www.w3.org/2000/09/xmldsig#">
    <xenc:EncryptedData Id="EncryptedContent-0e6936bf-67a5-48a5-ba8a-d9ba6141e75f" Type="
    http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
    <xenc:EncryptionMethod Algorithm="
    http://www.w3.org/2001/04/xmlenc#aes128-cbc" />
    <KeyInfo xmlns="
    http://www.w3.org/2000/09/xmldsig#">
    <wsse:SecurityTokenReference>
    <wsse:Reference URI="#SecurityToken-3370d9ae-deb9-4a01-9b9c-c8dd072568fa" ValueType="
    http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken" />
    </wsse:SecurityTokenReference>
    </KeyInfo>
    <xenc:CipherData>  <xenc:CipherValue>rFfJS87yAdFFkW1dVbot...tJ+9U8+CU5qsI=</xenc:CipherValue>
    </xenc:CipherData>
    </xenc:EncryptedData>
    </Signature>

    </wsse:Security>


    Voila! The Red bold font will show that the Signature Element is now encrypted.

    Saturday, December 11, 2004 8:14:03 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  • To slightly expand on my post and Hervey's a little bit further, there was mention on the use of Enveloped Signatures in the SOAP Headers. Enveloped Signature (as defined by XML-Digital Signature) is a signature over the XML content that contains the signature as an element. The content provides the root XML document element. Obviously, enveloped signatures must take care not to include their own value in the calculation of the SignatureValue. In other words, Enveloped Signature would sign the contents of the SOAP headers WITHOUT the signature. This is the only way a Security header can be signed without creating a circular reference dependency.

    To do the above, you are enforcing the prevention of intermediaries from modifying the SOAP Headers.

    However, as taken from the _WS-Security Specs_


    Because of the mutability of some SOAP headers, producers SHOULD NOT use the Enveloped Signature Transform defined in XML Signature. Instead, messages SHOULD explicitly include the elements to be signed. Similarly, producers SHOULD NOT use the Enveloping Signature defined in XML Signature [XMLSIG]

    WS-Security doesnt *believe* in the Enveloped Signatures because it stands on the belief that SOAP Headers are mutable. Since SOAP Headers can change and the likelihood is there that a SOAP intermediary can change the headers, an Enveloped Signature would not be as extensible and work as well.

    I am a strong believer of that. If a normal signature is used instead of an enveloped one, then an intermediary can safely add more tokens and more signatures to a Security header targeted at another node on the message path...and that is why there is WS-Security. Security cannot just be based on End-to-End scenarios or else SSL / HTTPS will suffice.

    I also further believe that an intermediary should be able to extend Security headers which are meant for other target nodes. Since a SOAP node can only process a single Security Header (because of re-ordering constraints of SOAP Headers), this option may not be as far-fetched or ridiculous as it may sound.

    Of course, anyone can still choose to implement Enveloped Signatures over their SOAP Headers if they are just implementing End-to-End scenarios and enforcing non-tampering measures over any desired or un-desired intermediaries. However, extensibility may not be an option here should intermediaries be required to offload certain processing functionality off the ultimate receiver or even add more tokens and signatures along the way.

    Saturday, December 11, 2004 2:57:32 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Thursday, December 09, 2004

    I have been noticing an increasing number of emails and newgroup threads asking for the security of Usernametokens as specified by _WS-Security Specs_ on OASIS. Most people would like to use it because it is the only alternative they have and there are no other options for using X.509 PKI Digital Certificates. Here is my personal take on it.

    I think some of the security concerns are slightly misplaced here. Firstly, I dont think WS-I or OASIS would include Usernametokens inside the WS-Security Specifications if they doubt its security. As I would like to say, --- Implementation is key.

    A Username token does NOT use any simpler or less-standard security algorithm than any other tokens. In fact, it uses the same hashing algorithm, symmetric algorithm such as the 128-key Cipher Block Chain (cbc) Advanced Encryption Standard, etc as any other token. Many people, also, do not realize that the same symmetric algorithm is used to encrypt the SOAP message body when an asymmetric X509SecurityToken is used as well. The asymmetric key algorithm is only used to encrypt the secret key that is doing the actual symmetric encryption processing. This is done for the purpose of reducing cipher bloat and increasing processing speed. The paranoia in me, however, would go for a higher-bit key implementation, which is possible.

    Remember that your secret can be stolen and kept for years and tried to be broken with much higher-end and cheaper deciphering machines in the future. OK, OK, that is my paraniod self talking.

    I believe when statements are made against the security of Usernametokens, they are made against the passwords of the Usernametokens. Therefore, the statement: "Usernametokens, on their own they are only as secure as the passwords"

    Usernametokens are as secure as your passwords. That means that if you have a good security policy on how your company treats passwords, ie...

    1. Minimum password length
    2. Implementation of alphanumeric and other different characters and symbols in password
    3. Password change frequency (in months instead of years )
    4. Elimination of Weak Passwords such as using names and such
    5. ...

    you should NOT be so fearful of using a Usernametoken in your Web Service implementation.

    On the other hand, if you don't treat or administer your passwords with good password policies, then you cannot expect Usernametokens to give your message as secure a protection as you would like.

    I would also recommend using the PasswordOption.SendNone, if possible. The hash of the password and other elements are used to produce the cipher. NO password is sent over using this enumerated option. Of course, the only caveat is except through a dictionary attack, which of course, can be made so much more difficult (or almost impossible) by having a good password policy administration system.

    If you have to send your Usernametoken over in PasswordOption.SendPlainText for whatever reasons (using Windows, LDAP Authentication or you may have hashed versions of your passwords stored in your UserDB), you SHOULD encrypt the UsernameToken with a X.509 digital certificate. Read my post here for my own implementation of it.

    Another thing to take note is one that relates to the real world and why I believe Usernametokens have its place here. It is easiest to implement and common in any business environments. Therefore, it can be plugged into any existing IT systems with relatively lesser effort. Also, X509 digital certs are usually used to authenticate machines and / or companies, it would be more expensive and unrealistic to expect every user in a 100+ user organization to have a digital cert and a private / public key pair. Therefore, I strongly believe that Usernametokens are more appt to authenticate the users themselves in the real world and will continue to be one of the most popular way to authenticate users in the near biometric-less future. However, if you are using authentication between machines, you should opt for X509 digital certs instead.


    [Author note] I believe WSE 2.0 SP2 has taken some lengths to make sure that Usernametokens which transmits a clear text password are now encrypted.

    • For security reasons, it is strongly recommended to encrypt Username tokens, especially when they contain password information. The SecurityTokenServiceClient class now automatically encrypts any UsernameToken security tokens included in outgoing SOAP requests. Similarly, the SecurityTokenService class automatically encrypts any UsernameToken security tokens included in outgoing SOAP responses.
    Thursday, December 09, 2004 1:57:26 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Saturday, December 04, 2004
    Friday, December 03, 2004 10:51:46 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Monday, November 29, 2004
    Andrés G Vettori has done it again...
    Monday, November 29, 2004 8:25:11 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Saturday, November 27, 2004
    Can or Should a SOAP node process multiple security headers ? Should Trust be End-to-End or Node-to-Node ?
    Saturday, November 27, 2004 10:18:35 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Tuesday, November 23, 2004

    Word from the man Hervey himself. Find it here.

    WSE2.0 SP2 Pre-release Full product and the Runtime

    Contents from the ReadMe:

    Core product changes:

    • A new compatibility section is used to select the wire format on the sending
      side. The mode attribute tells WSE runtime to generate a message which will be
      compatibable to a particular release of WSE. By default, the mode is WSE2RTM. It can be WSE2RTM, WSE2SP1 WSE2SP2 and so on. On the receiving end, a particular version of WSE runtime will be able to accept all types of wire format in all its previous releases. In a request-response message exchange, a server will generate a response message which is compatible with the request message. The server will, by default, still use the compatibility section to generate its response if it cannot determine the compatibility mode based on the request message.
    • A new implementation of the Kerberos token based on SSPI interfaces is included in this release. The new token is named KerberosToken2. Please see the reference documentation for more details.
    • The TokenIssuer element in the KerberosToken security token assertion is
      no longer supported on the receiving end.
    • The SecurityTokenManager no longer throws exception in LoadTokenFromXml() when token.IsCurrent returns false. WSE security input filter will continue checking that and throw exception if token.IsCurrent returns false.
    • The inclusion of unencrypted Username tokens in a message may represent a security vulnerability. The SecurityTokenServiceClient class will now automatically encrypt any Username tokens included in a request. Similarly, the SecurityTokenService class will automatically encrypt any username tokens included in a response.

      The following methods have been added to the token issuing framework:

      protected virtual void SecurityTokenServiceClient.EnforceRequestUsernameTokenEncryption().
      Called from EnforceRequestPolicy(), this method enforces the requirement that any Username tokens in an RST message must be encrypted. The issuerToken is used as the encrypting token. This method will throw an exception if it cannot encrypt the UsernameTokens in an RST message.
      Override this method to suppress this behavior.

      protected virtual void SecurityTokenService.VerifyRequestUsernameTokenEncryption().
      Called from VerifyRequestPolicy(), this method verifies that tokens in an RST message are encrypted. This method will throw an exception if it encounters an unencrypted UsernameToken in an RST message.
      Override this method to suppress this test.

      protected virtual void SecurityTokenService.EnforceResponseUsernameTokenEncryption().
      Called from EnforceResponsePolicy(), this method enforces the requirement that any Username tokens in an RSTR message must be encrypted. The ResponseEncryptingToken is used as the encrypting token. This method will throw an exception if it cannot encrypt the UsernameTokens in an RSTR message.
      Override this method to suppress this behavior.

      protected virtual void SecurityTokenServiceClient.VerifyResponseUsernameTokenEncryption().
      Called from VerifyResponsePolicy(), this method verifies that tokens in an RSTR message are encrypted. This method will throw an exception if it encounters an unencrypted UsernameToken in an RSTR message.
      Override this method to suppress this test.

    • A new method, protected virtual void SecurityTokenServiceClient.ClearRequestSoapContext(), has been added. This method was added to fix a bug in which successive requests for a SecurityContextToken, made through a single instance of SecurityContextTokenClient, would fail. The problem was caused by a failure to clear security elements and tokens from the soap context after a request was made. In the event that a sub-class of SecurityTokenServiceClient requires that security elements or tokens in the soap context be preserved from one request to another, the new behavior may be suppressed by overriding the ClearRequestSoapContext method.
    • SoapService will now send back an empty SoapEnvelope back if the soap method it is invoking returns null for a request/response scenario.
    • EncryptedData.Decrypt will only support decryption to one and only one xml element. It throws a security fault otherwise.
    • In the SoapHttpOutputChannel.Send method, if the response has an unsupported content type, such as text/html, the response stream will be read and stored in the exception text.
    • Two new properties, SimpleDisplayName and FriendlyDisplayName, have been added to the X509Certificate class.
    • The default Label used in DerivedKeyToken has changed from "WS-SecureConversation" to "WS-SecureConversationWS-SecureConversation".
    • If an incoming message contains multiple security tokens with envelope signature inside those tokens, the server was returning a security fault. This is now fixed.
    • If WSE SOAP messaging stack is used over HTTP/HTTPS transport, a simple WSE805 exception was thrown when the response content type was not supported. Now if the response stream is readable, WSE runtime will read from response stream and throw a WSE805 exception with a more detailed error information read from the response stream.
    • WSE configuration section will now allow whitespace or comments as child nodes for the following configuration elements: diagnostics/trace, diagnostics/policyTrace, diagnostics/detailedErrors, referralCache/cache, security/x509, security/limits.
    • When a security context token was deserialized, WSE runtime will retrieve a token from its cache based on its globally unique Identifier. The token retrieved from the cache sometimes have a different Id than the token received from the incoming message. If that happens, WSE runtime would previously fail to verify a signature or decrypt the message. It is now fixed as it will assign the Id of the token from the incoming message to the token retrieved from the cache.
    • The built-in SecurityContextToken service would previously cache a newly issued security context token instance before those properties defined in the IIssuedToken interface are set. Now it is fixed so that those properties are set before the newly issued token is cached.
    • WSE runtime would previouly always generate a relative token reference in calculating message signature. When the token is not sent with the message, the receiver will return a security fault. It is now fixed so that an absolute token reference will be generated in the case when the security token is not in the message.
    • A server fault was thrown previously when a server tries to verify a signature or decrypt a message based on a username token which uses plaintext password option or no password option and does not have nonce and/or created element. The exception is now changed to be a client fault.
    • SoapService instances configured to automatically issue SecurityContextToken (SCT) security tokens no longer re-use the same instance of the SCT issuer. With this service pack, a new instance is created per request. This instance is accessible via the SoapService.AutoIssueSCTService property. If the old behavior
      is required, there are two work-arounds:

      1. override the SoapService.AutoIssueSCTService property to return a singleton instance of a SecurityContextTokenService, or

      2. create a wrapper SecurityContextTokenService that delegates to a singleton instance and register it through configuration.

    Visual Studio tool integration changes:

    • The default value for http Routing handler type is updated.
    • WSE setting tool can support VS C++ project.
    • WSE setting tool would always prompt users for confirmation when the Cancel button was clicked. Now it is fixed so that the tool will prompt user only when some changes are made by users.
    • The Security Settings Wizard can support creating Policy files for remote service.

    WseWsdl2 tool changes:

    • The WseWsdl2 tool now properly generates proxy classes when an Web service uses a Guid type.
    • If an input schema contains a type definition which is derived from another complex type, the proxy class would generate a class definition for that derived type with incorrect namespace. This is now fixed.
    Tuesday, November 23, 2004 10:07:07 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  • I came across this blog last week, detailing a problem he is facing with WSE 2.0

    Now I that realize who he is (Hello Fai ), I peep into his project to see how I could help. Fai, incidentally, is the Academic DE for MSFT Malaysia and I met him in MS Tech.ED 2004 Asia in Msia.

    Since I cannot comment on this blog (since theSpoke doesnt allow it and I dont intend to keep another account), I will comment on his problem here.

    I reproduce Fai's blog snippets here.


    SoapSender & SoapReceiver

    I've been mucking around with WSE 2.0 Messaging, now moving on to SoapSender and SoapReceiver. I noticed a potential problem when I have a class that extends the SoapReceiver class, and within the Receive() method, it also sends out a SoapEnvelope via the SoapSender.Send() method. The problem only arises when I use a real transport protocol, i.e., TCP, but not when I'm using the in-proc transport. I've tried all sort of ways, including transfering the SoapSender code away from the Receive() method to a method in another class. But it still doesn't work.

    The behavior of my current Receive() method almost seems like it is acting like a SOAP router. This is because it receives a SoapEnvelope, sends out another SoapEnvelope albeit doing some computation and returning a totally different SoapEnvelope.
     
    Then I discovered the IsIntermediary property of the Pipeline class from this blog. According to the WSE 2.0 Class Reference, this property gets or sets a value indicating whether the pipeline is running within a SOAP router. Fair enough, and I implemented the following code:

       // send response SOAP message
       SoapEnvelope env = new SoapEnvelope();
       env.Context.Addressing.Action = e.Context.Addressing.Action;
       env.Context.Addressing.Destination = e.Context.Addressing.ReplyTo;
       env.SetBodyObject(resp);
       Pipeline pipe = new Pipeline();
       pipe.IsIntermediary = false;
       pipe.ProcessOutputMessage(env);
      
       SoapSender responseSender = new SoapSender(env.Context.Addressing.Destination);
       responseSender.Pipeline = pipe;
       responseSender.Destination = env.Context.Addressing.Destination;
       responseSender.Send(env);
     
    I've also tried move the MathResponseReceiver class to a separate project so that it can be started separately. Still to no avail. According to another blog I read, WSE 2.0 is smart enough to know if there are two receivers classes within a single application domain, and both are communicating with each other using an actual network protocol like TCP or HTTP, it will detect that and switch it in-process instead.
     
    But still it doesn't work! I appreciate if anyone out there could help me fix this. Could it be a bug in WSE 2.0?

     
    Steve talks about pipelines and routing in his blog above. However, I dont think the pipeline.IsIntermediary helps you in this case because you really never did subject your message through a routing pipeline. Therefore, it doesnt address or solve your problem at all.
     
    The problem (after looking through your codes and running SOAP Trace Diagnostics) and you are going to hate me for this, is just a programmatic syntax error

    env.Context.Addressing.Destination = e.Context.Addressing.ReplyTo.Address.Value;

    What you missed out was actually pass in the address property of the ReplyTo class. This address property (which is inherited from an EPR) will get you the address of the destination.

    So, your final code snippet should simply look like this (without the pipelines class):

    SoapSender responseSender = new SoapSender(e.Context.Addressing.ReplyTo.Address.Value);
    SoapEnvelope env = new SoapEnvelope();
    env.Context.Addressing.Action = e.Context.Addressing.Action;
    env.SetBodyObject(resp);
    responseSender.Send(env);

    I hope this helps. Try it and let me know here if it works.

    Tuesday, November 23, 2004 6:23:16 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Saturday, November 20, 2004
    I came across some questions pertaining to how the asymmetric keys of X.509 PKI Digital Certificates are being transmiited during SOAP Message exchanges for both XML-Encryption and XML-Digital Signature. There seems to be some sort of slight confusion here so I will explain in a more user-friendly fashion here.
    Saturday, November 20, 2004 8:19:49 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  • Please take note that X.509 Digital Certs generated this way are for testing and development purposes only.
    Friday, November 19, 2004 11:42:40 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Thursday, November 04, 2004

    With reference to my previous posted here on Real World UsernameToken Authentication Scenarios with WSE 2.0

    I have received some very good responses and feedback based on that and the questions tend to continue:

    Some of the feedback I have received asked about the Encryption of the UsernameToken in the ResponseStream in the example given above. Here is a sample question:

    Encrypting the username token using the public key of the server ensures
    that the password is encrypted in the request to the server. What happens
    when the response from the server is sent to the client ? I have looked at the
    the trace the output tace at the client has no password in clear text. But
    the input trace on the client has a clear text password. Why ?

    The username credentials returned will follow that of the request method. So, if you send a SendPlainText mode of the PasswordOption in a request [even though you encrypt the UsernameToken afterwards], the UsernameToken in the response will be sent back in PlainText as well. This happens, of course, if you added the mutable UsernameToken back into the response stream
     
    'Add Mutable Token into the Token Collection of the Response
    ResponseSoapContext.Current.Security.Tokens.Add(RetrievedUsernameTokenFromRequestStream)

    We cannot re-do the process we did earlier in the RequestStream by encrypting the UsernameToken again. If you remember, that was done because we had to do some Hash-Digest comparision with the Hash value stored in the user db against the Hash value generated from the Password sent in the RequestStream. Thus, the Password send have to be in PlainText mode. However, we will encrypt the UsernameToken so that it doesnt get seen on the wire. We encrypt it with the Recipient's PublicKey for the Recipient's perusal. At least, an encrypted token CAN be decrypted, a Hashed one CANNOT.
     
    However, we cannot do the same in the reverse ResponseStream. This is because we cannot encrypt the Recipient's SecurityToken with the Recipient's key. The Recipient machine would not know how to decrypt it.

    ResponseSoapContext.Security.Elements.Add(New EncryptedData(eTok, "#" & eTok.Id))

    doesnt make any sense and would be invalid and the Recipient would respond with a SOAP Client error:
     
        ApplicationException: WSE507: The order of security elements and security tokens
        will cause a processing failure on the receiving end, and they must be reordered
        to create a valid message.
     
    To hack around this constraint in WSE 2.0, the best alternative I could think of and tried is to intercept the process and force the UsernameToken to be sent back with a SendHashed or better, with a SendNone Option. This can be done by typeCasting the SecurityToken that is retrieved from the earlier RequestStream to that of a UsernameToken. Then retrieve all the necessary credentials of the casted UsernameToken (eg. Username, Password) and send that details into a new instantiated UsernameToken. Then, add this newly created mutable UsernameToken into the ResponseSoapContext Stream.

    'Retrieve the Signing Token from the Request Message

    Dim eTok As SecurityToken = GetBodySigningToken(RequestStream)

    'Retrieve the Encrypting X509Security Token from the Request Message

    Dim sTok As X509SecurityToken = GetBodyEncryptingToken(RequestStream)

    'CAST the SecurityToken into a UsernameToken type

    eTok = CType(eTok, UsernameToken)

    'Force the process to send back a Hashed or NO Password

    Dim ut As UsernameToken = New UsernameToken _CType(eTok, UsernameToken).Username, CType(eTok, UsernameToken).Password, PasswordOption.SendHashed)

    'Retrieve the same Cert from the Local Machine store and Check if it supports Digital Signing

    Dim sX509KeyID As String = Convert.ToBase64String(sTok.Certificate.GetKeyIdentifier)
    sTok = Helpers.GetSigningX509Cert(sX509KeyID)

    'Add Mutable Token into the Token Collection of the Response

    ResponseSoapContext.Security.Tokens.Add(ut)
    ResponseSoapContext.Security.Tokens.Add(sTok)

    'Add the Message Signature into the message

    Resp.Security.Elements.Add(New MessageSignature(sTok))

    'Add the Encrypted data into the message

    Resp.Security.Elements.Add(New EncryptedData(ut))

    From the ResponseStream generated, you will be able to look at the UsernameToken sent back now to the Recipient. However, the Password will be Hashed or there may be NO Password at all (if you configured to be sent back with a PasswordNone Option). Below is the trace snippet sent back from the Server to the Recipient.
     
            <wsse:UsernameToken...>
              <wsse:Username>TestAccount</wsse:Username>
              <wsse:Password Type=...>wc9Xl04zDgbbd0NIrOuHuRcsRVs=</wsse:Password>
              <wsse:Nonce>qr7saTsm5H/YNSjIl3w2kA==</wsse:Nonce>
              <wsu:Created>2004-08-05T09:38:53Z</wsu:Created>
            </wsse:UsernameToken>

    Of course, if the Service Consumer has their X.509 Digital Certs as well, we can always embed a binarySecurityToken representation of the client's Public Key into the SOAP Request stream and then, in the Service Response Stream, encrypt the Consumer's UsernameToken with his own Public Key taken from the binarySecurityToken representation and dispatches it. However, this is not an elegant solution as

    1. Most Service Consumers do not have their own X.509 Digital Certs and therefore, we have to cater for those who dont. This means extra processing power and code is needed to parse the SOAP Message to check for the binarySecurityToken and extra logic is required to hash it back using the above method if the binarySecurityToken is not found.
    2. Message Payload will increase with any type of encryption as compared to hash digest and with the attachment of the binarySecurityToken as well.

    Do let me know if this works for any of you or, if you have better suggestions.

    Thursday, November 04, 2004 6:06:28 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  • It sure is great to see many people beginning to experiment and use Web Services Enhancements (WSE) 2.0. Many people I speak to and come across today are still trying to grasp the security features of WSE.

    I had blogged about this earlier in my old weblog host here. However, I will just summed it up for interested parties in this post.

    ...While the Documentation of WSE 2.0 teaches on how to authenticate a usernameToken from a client request against a database query [I print it here for your benefit]:

    Protected Overrides Function AuthenticateToken(userName As UsernameToken) As String

    'BLAH BLAH BLAH
    'You are supposed to be reading from a returned Database query based on the UsernameToken.userName property.
    'Then you are supposed to return the Password that is returned from the DB Query here

    End Function

    However, it doesnt touch on one of the best practices of Security of storing passwords into a database which is to hash userpasswords and then store it in the DB. So the question is how do we compare then ?

    Bearing in mind the constraints of

    1. Passwords must be sent from the client in PlainText Form so the service can hash it and compare against the database
    2. Passwords cannot be sent in Hash Digest form as the service would have NO idea on how to re-engineer the actual password from the Hash Digest

    I suggest a couple of alternatives to solve this problem....Most of what you choose will depend on very much how much control you have over the client

    1. SSL it [The ugliest, expensive and least scalable way...but requires the least coding work]
    2. Send the username, password in ClearText Via the usernameToken. However, encrypt this entire usernameToken before sending it over. The pipelines of WSE will handle the decryption for you. Once it reaches your service application, you will know what the ClearText password is. Hash it and then do a straight comparison of the Hash Digest against the one returned from the Database. This method assumes that the server has the Private Key portion of an asymmetric token such as a X509 Digital Certificate or even the service has a X509 Digital Certificate to begin with and it also assumes the knowledge of the Hash Algorithm method employed by the user DB.

    While the documentation may be poor, the extensibility of the UsernameTokenManager is great ! I will reproduce snippets of option [2] for your benefit

    [Calling Client]

    Dim a As localhost.IndexWse = New localhost.IndexWse

    'Send PlainText Password across so that the Service can hash Digest
    'this value for comparison later
    Dim ut As UsernameToken = New UsernameToken _
    ("TestAccount", "TestPassword", PasswordOption.SendPlainText)

    'Include the usernameToken in the message so the Server can verify that
    'this usernameToken actually came from you
    a.RequestSoapContext.Security.Tokens.Add(ut)

    'Blah - Find the Service Public Key of its X509 Cert so only the Service
    'can decrypt and read this Token
    Dim store As X509CertificateStore = _
    X509CertificateStore.CurrentUserStore(X509CertificateStore.OtherPeople)
    store.OpenRead()

    Dim cert As X509Certificate = store.FindCertificateByKeyIdentifier _
    (Convert.FromBase64String("bBwPfItvKp3b6TNDq+14qs58VJQ="))(0)

    Dim tok As X509SecurityToken = New X509SecurityToken(cert)

    'Sign and Encrypt everything in the message. Beware of the Payload !
    a.RequestSoapContext.Security.Elements.Add(New MessageSignature(ut))
    a.RequestSoapContext.Security.Elements.Add(New EncryptedData(tok, "#" & ut.Id))
    a.RequestSoapContext.Security.Elements.Add(New EncryptedData(tok))

    'VOILA
    MessageBox.Show(a.HelloWorld)

    [Service Side]

    Public Class CustomUsernameTokenManager
    Inherits UsernameTokenManager

    Protected Overrides Function AuthenticateToken(ByVal token As UsernameToken) As String

    Dim pw As String = token.Password

    'Employ the same Hash function on the password that you deployed saving the passwords
    'into the User DB
    Dim hpw as string = userDBHash(pw)

    'Compare the hpw result with the one returned from the oledbReader from the Database
    'with the username as the Reference
    'If it matches, return the same password from the Token
    Return token.Password
    'Else
    Return "A Password that is impossible to GUESS"

    End Function 'AuthenticateToken
    End Class 'CustomUsernameTokenManager

    If you check your diagnostics and the SOAP Message Tracing Files, you will notice that the entire usernameToken is encrypted and nothing is sent over in ClearText even tho the passwordOption is set to SendPlainText.

    Thursday, November 04, 2004 5:46:54 AM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions

  •  Friday, October 29, 2004
    Friday, October 29, 2004 3:01:10 PM (Malay Peninsula Standard Time, UTC+08:00)  #    Disclaimer 
  • Blog reactions