Bruce Schneier is reporting that SHA-1 has been broken. Interesting.
SoftwareMaker (William T) has a long entry on multiple security headers. Here's how we thought about the problem for WSE2:
In general, you cannot have 2 security headers that target the same node, even if they have different s:Actor values; i.e., one has s:Actor missing and one has s:Actor of next. This is because headers can be re-ordered in messages leading to problems verifying signatures or decrypting elements. This is a simple extension of the highlighted text that is quoted from the WS-Security specification:
"Message security information targeted for different recipients MUST appear in different header blocks. This is due to potential processing order issues (e.g. due to possible header re-ordering)."
The extension being that security information targeted for the same recipient MUST appear in the same header block: the re-ordering problem also applies when any 2 security headers target the same node. This is the reason, IMHO, that intermediaries should be allowed to add new elements to an existing wsse:Security header, provided that they do it correctly. I therefore believe that the text in the OASIS specification is incorrect and that the text from the original specification is more likely correct: it makes little sense for an intermediary to be able to add security information to a header that is targeted at that intermediary.
I also don't agree with this:
"John is definitely right in saying that I shouldnt be touching the security Headers meant for any other actor. It could be signed anyways."
Signatures go inside wsse:Security headers, not outside them. To sign the wsse:Security header and place the resulting signature in that same header is an operation that creates a cyclic dependency: you cannot sign the header until the signature is in it, but you can't generate the signature until you have the complete header. The rules regarding removal of processed soap headers don't apply to the contents of an individual header like wsse:Security.
Note that encrypting complete headers as SoftwareMaker appears to have done:
"The CanProcessHeader method will definitely fail as it cannot find the actorless security header referenced security token without decrypting it"
is also not a good thing to do. It is potentially confusing to soap processors to have operations associated with one header uncover new headers that need to be processed at the same node. #Content encryption may also cause schema validation problems by changing the inner content of a header. Indeed, OASIS WS-Security is expected to add a new construct in the near future to allow for this case: EncryptedHeader.
Security tokens have several properties that provide information about their lifetime:
In the case of SecurityContextTokens and KerberosTokens in WSE 2.0, the RequiresRenewal property is overridden from its default and uses a renewal window value to return true from this property when the token is still current but about to expire.
The policy engine in WSE 2.0 uses this property to determine when to automatically request a new SecurityContextToken or to create a new KerberosToken to avoid messages failing at the receiver. If you use either of these tokens directly in code without policy and you application is long-running, you should use this property to determine when to renew the token.
OASIS WSS was voted on by the membership last week. The latest on the public mailing list is that the issues around the single No vote have been resolved and the specification will move forward to become a standard.
Excellent news.
The OASIS WSS Technical Committee is voting all this week to submit their specification as a standard. I was told the vote was public, but have not been able to find a URL that shows the current situation. Polling closes on Sunday and we'll know the result Monday morning.
There have been a few changes to the OASIS WSS specification since we last reworked its implementation in the WSE 2.0 build for the recent WS-Trust / WS-SecureConversation workshop.
Despite the link on the OASIS WSS home page, the most current document (at the time of writing) is under the "documents" link at the top of the page.
The major changes are to the namespace for WSS and the replacement of all uses of QNames with URI's for well-known values. For example
I personally think the move to URI's from QNames is a good one: serializing, deserializing, parsing and comparing QNames is much more complex and error prone than a URI.
Of course, there are some knock-on effects with this change, some of the affected attributes in the WSS specification have direct equivalents in the WS-Trust, WS-SecureConversation and WS-SecurityPolicy specifications and those have not yet been revised in line with the WSS change.
Overall, we're feeling that we need to make these changes to the WSE 2.0 release to best protect customers chances of interoperability when the OASIS WSS specification goes final (hopefully soon!). Despite the fact that WSE is all about delivering implementations of the latest specifications, even we sometimes wish there was a little less churn...
...Hello OASIS WSS.
It wasn't widely advertised, but the WSE 2.0 Tech Preview was able to speak two dialects of Security - one was the pre-OASIS version of the WS-Security specification and the other was an early draft of the OASIS WSS specification.
For the final 2.0 release we are dropping support for the pre-OASIS version and moving forward with only the OASIS version. I think this is the right decision to help drive interoperability between different implementations: if you are planning to interop a WSE 2.0-based web service with another vendors product, now is the time to make sure they are on the same train.
WSE supports signing with a UsernameToken, but not encrypting with it. Since there's a key derivation mechanism it may seem a little odd that we don't support encryption with it.
Before we start, remember that the UsernameToken is mutated every time it is used in a message: the Created timestamp and the Nonce are regenerated. This is different than all the other token types in WSE and some that aren't in it (e.g. XrML and SAML). It has two implications: first, the token is not thread-safe and second it may not be possible to recover the original state of the token, and hence the key, that was used for any particular message.
Now take a common scenario: a client signs a message with a UsernameToken and encrypts the <soap:Body> using the servers X.509 certificate (not that unreasonable for a service). The server wants to sign the response with it's X.509 certificate and encrypt the <soap:Body> with the UsernameToken.
If you've examined the message format that WSE uses for encryption, you'll have seen that we like to use a <ds:KeyInfo> to identify the encrypting token. There are quite a few possibilities for clauses within the <ds:KeyInfo> to identify the token that was used, including things like <ds:KeyName> and <wsse:SecurityTokenReference> containing either a <wsse:KeyIdentifier> or a <wsse:Reference>.
For UsernameTokens, there is no obvious clause that is suitable:
Now, even if one of the above did hold, the fact that UsernameTokens mutate becomes a problem - we can't be sure that the token at the client hasn't changed - another message might have been sent in between. This would lead to using the wrong key to decrypt.
Including the token in the response message is also problematic. The client will attempt to deserialize the token and authenticate it. SecurityTokenManagers in WSE do not distinguish between requests and responses and behave the same in both cases: the token manager will attempt either a password lookup or Windows authentication of the token. Password lookup doesn't make a great deal of sense at a client; Windows authentication requires a plaintext password and a secure channel - why use the UsernameToken to encrypt the response if you already have a secure channel?
For WSE 1.0 and 2.0 Tech Preview, we simply didn't identify a practical, authoritative, interoperable model. Since interoperability is one of the top priorities for WSE, we chose to hold off doing something WSE specific and get additional guidance. With the widening use of WS-Trust and WS-SecureConversation and the fact that everyone seems to like the UsernameToken as a bootstrap, we're again looking hard at this problem for the 2.0 final release.
This seems to be one of the top problem areas for people working with WSE, particularly at the server. The best way to get things right is to use the X.509 Certificate tool that is part of the WSE 2.0 Tech Preview. This tool allows you to select the certificate that you want to use and then set the appropriate access permissions on it's private key file.
For IIS/ASP.NET on either Windows 2000 or Windows XP, you need to grant the ASPNET user read permissions to the key. For IIS on Windows Server 2003, assuming the default setup, you need to give NetworkService read permission. If you are running your web services on Windows Server 2003 in a separate application pool with a specific identity, use that identity instead of NetworkService.
If you're still working with WSE 1.0SP1 that's OK - the WSE 2.0 Tech Preview will install side-by-side with 1.0SP1 and you can use the tool. Just watch out for Visual Studio switching your references to the 2.0 version of Microsoft.Web.Services.dll.
We keep getting asked about how key generation works for the UsernameToken in WSE. The algorithm that is used for WSE 2.0 is documented in the WS-Trust specification:
P_SHA1 (password, label + nonce + created)
Where:
WSE 2.0 Tech Preview generates key material using this algorithm that is then used to key the HMACSHA1 algorithm used to sign the message. By default, we generate 16 bytes of key material. This is another area where we may introduce more application control for the 2.0 release.
Also of note for those attempting to reproduce this process is a bug in the Tech Preview where the label is taken as ASCII bytes instead of UTF-8.
Now a caveat: UsernameToken has never been the subject of an interoperability test and so we cannot say whether other implementations that have this capability use the same algorithm.
And a few words of caution: I want to urge people to be cautious in their use of the UsernameToken. The model we want to encourage for 2.0 release is that this token is immediately exchanged for a different token, either a customer-specific identity token or a SecurityContextToken (SCT) that then uses derived key tokens for signing and encrypting.
And finally, yes, I know that the Tech Preview doesn't let you use a UsernameToken as part of a WS-Trust RST/RSTR sequence. More on the reasons for that in another post...