Monday, January 27, 2014

Apache WSS4J 2.0.0 - part III

This is the third of a series of articles on the new features and changes that will be delivered in Apache WSS4J 2.0.0. The second article grouped together some new features that were too small to warrant a separate article on their own. This article will focus on some changes in the area of caching tokens to detect replay attacks.

1) Replay Attack detection in Apache WSS4J 1.6.x

Please see a previous article I wrote which covers what Replay Attacks are, and how to prevent them in Apache CXF (using WSS4J 1.6.x). Essentially, the goal is to ensure that an eavesdropper cannot copy a WS-Security enabled request, and make another successful invocation on a service. Three different types of Replay Attack detection exist in Apache WSS4J:
  • Signed Timestamps
  • UsernameToken nonces
  • SAML OneTimeUse Assertions (see here).
Apache WSS4J 1.6.5 introduced a ReplayCache interface, which can be used for replay attack detection for each individual use-case. In addition, WSS4J 1.6.5 shipped with a sample TreeMap-based implementation, which was not intended for production use. However, caching was not enabled by default in WSS4J itself, but rather was configured in Apache CXF using an Ehcache based solution. Please refer to the original article for more details.

2) Replay Attack detection in Apache WSS4J 2.0.0

A new major version release of Apache WSS4J allows us to shift the Replay Attack implementation from Apache CXF into WSS4J itself, so that other stacks can benefit. WSS4J 2.0.0 will ship with default support for detecting replay attacks for the following three scenarios, without any required configuration changes. The default ReplayCache implementation is based on Ehcache and uses the following configuration.

2.a) Signed Timestamp replay detection

By default, WSS4J 2.0.0 will cache a combination of a Timestamp Created value and the Signature Value that signs the Timestamp, that will be cached until the Timestamp "expiry" is reached (or until the default cache expiry is hit). The reason that the Timestamp must be signed is to preclude the rejection of two requests that have been created at the exact same time. The caching of signed Timestamps can be configured as follows:
  • ConfigurationConstants.TIMESTAMP_CACHE_INSTANCE ("timestampCacheInstance"): This holds a reference to a ReplayCache instance used to cache Timestamp Created Strings. The default instance that is used is the EHCacheReplayCache.
  • ConfigurationConstants.ENABLE_TIMESTAMP_CACHE ("enableTimestampCache"):  Whether to cache Timestamp Created Strings (these are only cached in conjunction with a message Signature). The default value is "true".
2.b) UsernameToken nonce replay detection

By default, WSS4J 2.0.0 will cache UsernameToken nonces, and reject any duplicate value. This can be configured as follows:
  • ConfigurationConstants.NONCE_CACHE_INSTANCE ("nonceCacheInstance"): This holds a reference to a ReplayCache instance used to cache UsernameToken nonces. The default instance that is used is the EHCacheReplayCache.
  • ConfigurationConstants.ENABLE_NONCE_CACHE ("enableNonceCache"):  Whether to cache UsernameToken nonces. The default value is "true".
2.c) SAML OneTimeUse replay detection

By default, WSS4J 2.0.0 will cache SAML 2.0 token identifiers, if the token has a OneTimeUse Condition, and reject any duplicate tokens. This can be configured as follows:
  • ConfigurationConstants. SAML_ONE_TIME_USE_CACHE_INSTANCE ("samlOneTimeUseCacheInstance"): This holds a reference to a ReplayCache instance used to cache SAML2 Token Identifier Strings (if the token contains a OneTimeUse Condition). The default instance that is used is the EHCacheReplayCache.
  • ConfigurationConstants.ENABLE_SAML_ONE_TIME_USE_CACHE ("enableSamlOneTimeUseCache"):  Whether to cache SAML2 Token Identifiers, if the token contains a "OneTimeUse" Condition. The default value is "true".

Thursday, January 23, 2014

Apache WSS4J 2.0.0 - part II

This is the second of a series of articles on the new features and changes that will be delivered in Apache WSS4J 2.0.0. The first article gave an overview of the new features, detailed the new project structure, and covered a migration guide for existing users. This blog post groups together the new features that are too small to warrant an article on their own.

1) Kerberos Signature/Encryption support

Support was added in WSS4J 1.6.2 to obtain a Kerberos ticket from a KDC (Key Distribution Center) and convert it to a BinarySecurityToken to be inserted into the security header of a SOAP request. On the receiving side, support was added to validate the received Kerberos ticket accordingly. In WSS4J 1.6.3, support was added to use the secret key associated with a Kerberos Token to secure (sign and encrypt) the request. However, this functionality came with the limitation that there was no out-of-the-box way to extract the Symmetric Key on the receiving side, to decrypt the request or validate the Signature.

Instead, a KerberosTokenDecoder interface was provided, which defined methods for setting the AP-REQ token and current Subject, and a method to then get a session key. To support signature and encryption with Kerberos on an inbound request, the user had to implement this interface and set it on the KerberosTokenValidator. This process, along with a sample KerberosTokenDecoder implementation which relied on low-level Java APIs, was described in a previous blog post.

In WSS4J 2.0.0, a default implementation of the KerberosTokenDecoder interface is provided that can process Kerberos secret keys correctly, using functionality from Apache Directory. Therefore support for using Kerberos tokens to sign and encrypt SOAP messages is now provided out-of-the-box in WSS4J 2.0.0.

2) Action enhancements

When not using WSS4J with a WS-SecurityPolicy aware stack such as Apache CXF, outbound security is configured via "Actions". The list of supported actions is defined on the WSS4J configuration page, e.g. "UsernameToken", "Signature", "Encrypt", etc. There are some enhancements to "Actions" in WSS4J 2.0.0.

a) Custom Token Action

A new "CustomToken" Action is defined in WSS4J 2.0.0. If this action is defined, a token (DOM Element) will be retrieved from a CallbackHandler via WSPasswordCallback.Usage.CUSTOM_TOKEN and written out as is in the security header. This provides for an easy way to write out tokens that have been retrieved out of band.

b) Action tokens

A significant new feature in WSS4J 2.0.0 for actions is the ability to associate an Action with a corresponding token. In WSS4J 1.6.x, actions are always configured from configuration that is shared between actions. So for example, a Signature action takes its key and algorithm information from the corresponding configuration tags. However, this is problematic if you want to execute two Signature actions, as it's not possible using this approach to use (e.g.) two different Signature algorithms.

In WSS4J 2.0.0, the WSHandler class is configured with a list of HandlerAction Objects, which associate an Action with a SecurityActionToken. Default implementations of the SecurityActionToken interface are provided for signature, encryption etc., and are populated from the standard configuration tags. However, to add some custom configuration for a given Action, you can implement the SecurityActionToken interface to provide configuration specific to that Action.

3) Optional Signature and Encryption parts

In WSS4J 1.6.x, signature and encryption parts are determined respectively by the "signatureParts" and "encryptionParts" configuration tags. However, if a part is specified that does not exist in the request, then an exception is thrown. In WSS4J 2.0.0, two new configuration tags are defined called "optionalSignatureParts" and "optionalEncryptionParts". These specify the parts to sign and encrypt, but no exception is thrown if the parts cannot be located. The tags can be used in an analgous way to the WS-SecurityPolicy SignedParts and EncryptedParts policies, which only require that an Element be Signed/Encrypted if it appears in the request.

4) More sophisticated Basic Security Profile enforcement

Apache WSS4J 1.6.x provided support for enforcing the Basic Security Profile 1.1 (BSP) restrictions. However, one issue with the implementation was that it was not possible to ignore a particular set of rules defined in the specification, enforcement was "all or nothing". In WSS4J 2.0.0, it is possible to disable all Basic Security Profile rules as per WSS4J 1.6.x. However, it is now possible to specify individual rules to ignore. The RequestData class has a setIgnoredBSPRules method, that takes a list of BSPRule Objects as an argument. The BSPRule class contains a complete list of Basic Security Profile rules that are enforced in WSS4J.

Note that when BSP Compliance was switched off on the outbound side in WSS4J 1.6.x, it had the effect that an InclusiveNamespaces PrefixList was not generated as a CanonicalizationMethod child of a Signature Element (as required by the BSP specification). In WSS4J 2.0.0, this is now controlled by a separate configuration tag "addInclusivePrefixes", which defaults to true. 

5) Configurable SAML SubjectConfirmation validation

WSS4J enforces the SubjectConfirmation requirements of an inbound SAML Token. For sender-vouches, a Signature must be present that covers both the SOAP Body and the SAML Assertion. For holder-of-key, a Signature must be present that signs some part of the SOAP request using the key information contained in the SAML Subject. In WSS4J 2.0.0, a configuration tag is defined that allows the user to switch off this validation if required. The configuration tag is defined as ConfigurationConstants.VALIDATE_SAML_SUBJECT_CONFIRMATION ("validateSamlSubjectConfirmation"), which defaults to true.

Thursday, January 9, 2014

SAML "OneTimeUse" support in Apache CXF 2.7.8

Apache WSS4J 1.6.13 contains a number of features to support working with SAML 2.0 tokens with a "OneTimeUse" Condition. Firstly, it is now possible to create a SAML 2.0 token with this attribute via the ConditionsBean. Secondly, support has been added to cache any token Identifier which has a "OneTimeUse" Condition. The idea is that any SAML 2.0 token with a "OneTimeUse" Condition cannot be used again (or replayed). Hence, this is another form of defence against replay attacks, similar to existing support to cache signed Timestamps and UsernameToken nonces.

This functionality in WSS4J has been integrated into Apache CXF. Two new configuration tags have been added to control caching SAML 2.0 tokens with "OneTimeUse" Conditions:
  • ws-security.enable.saml.cache -  Whether to cache SAML2 Token Identifiers, if the token contains a "OneTimeUse" Condition. The default value is "true" for message recipients, and "false" for message initiators.
  • ws-security.saml.cache.instance - This holds a reference to a ReplayCache instance used to cache SAML2 Token Identifiers, when the token has a "OneTimeUse" Condition. The default instance that is used is the EHCacheReplayCache.
Note that caching only applies when either a WS-SecurityPolicy "SamlToken" policy is in effect, or else that a SAML action (signed or unsigned) has been configured for the non-security-policy case. In either of these scenarios, a message recipient will automatically enforce OneTimeUse, unless it has been configured not to via the "enable" configuration tag defined above.

The client functionality in Apache CXF that gets a security token from an STS (SecurityTokenService) when the service has an "IssuedToken" policy has also been updated to take a "OneTimeUse" Condition into account. If the issued token from the STS has a "OneTimeUse" Condition, then the token is not cached on the message exchange. What this means is that if the client makes another service invocation, it will get a new token from the STS, as the "OneTimeUse" Condition of the previous token means that it can't be reused.



Wednesday, January 8, 2014

Apache WSS4J 2.0.0 - part I

Apache WSS4J is an open-source Java implementation of the security standards for web services. The project was founded in 2004 and is widely used, including by the web service stacks Apache CXF and Apache Axis. Apache WSS4J 1.6.0 was released in April 2011, and featured a wide range of improvements such as support for SAML 2.0 assertions. This blog post is the first in a series of articles on the new features and changes that will be arriving in the imminent WSS4J 2.0.0 release. In this article, we will provide an overview of the new features, the changed project structure, as well as a migration guide for existing users.

1) Overview of new features

Apache WSS4J 2.0.0 delivers the following major new features, along with a substantial set of minor features:
  • Support for a streaming (StAX) based WS-Security implementation that covers all of the main specifications. This is both faster and uses far less memory than the DOM-based alternative.
  • A WS-SecurityPolicy model that can be shared between both DOM + StAX implementations.
  • Support for "real-time" WS-SecurityPolicy validation for the StAX implementation.
  • Support for the SOAP with Attachments (SWA) Profile 1.1 specification.
  • Support for caching based on EhCache.
  • Support for encrypting passwords in Crypto properties files using Jasypt
These new features will be covered in more detail in future articles.

2) Project Structure

The source for Apache WSS4J 2.0.0 can be perused here. Support for building WSS4J using Apache Ant has been dropped, Apache Maven must be used to build the project. Support for JDK 1.5 has also been dropped. Unlike previous releases, WSS4J 2.0.0 now contains multiple Maven modules, the most important of which are as follows:
  • bindings: Contains code generated from security schemas
  • policy: Contains a (shared) WS-SecurityPolicy model
  • ws-security-common: Shared code between the DOM + StAX implementations
  • ws-security-dom: The DOM implementation.
  • ws-security-stax: The StAX implementation.
  • ws-security-policy-stax: The WS-SecurityPolicy validation layer for the StAX code.
Note that the old "org.apache.ws.security" package is no longer used as part of this refactoring, instead each module uses "org.apache.wss4j.X". The WS-SecurityPolicy model in the "policy" module replaces different models used in web service stacks such as Apache CXF + Axis, thus simplifying the code in the security components of these projects. The "ws-security-policy-stax" module gives us the ability to validate WS-SecurityPolicy against an inbound request in "real-time". This is opposed to the DOM implementation, which only validates WS-SecurityPolicy against the request after security processing has completed.

3) Migration Guide

Care has been taken to limit the impact of changes in WSS4J 2.0.0 on existing user configuration. However there are some inevitable incompatibilities, facilitated by the major version upgrade. I will details some of these changes in this section, and then expand on them on the website in more detail closer to release. These changes only affect the DOM in-memory implementation, as the StAX implementation is new in this release.

3.1) Signature Verification Crypto

In WSS4J 1.6.x, it was only possible to specify a Crypto implementation for both Signature Creation + Verification. In WSS4J 2.0.0, there is now a separate Signature Verification Crypto instance, that can be configured via the following configuration tags:
  • "signatureVerificationPropFile" - The path of the crypto property file to use for Signature verification.
  • "signatureVerificationPropRefId" - The key that holds a reference to the object holding complete information about the signature verification Crypto implementation.
3.2) WSPasswordCallback package change

In WSS4J, you need to define a CallbackHandler to supply a password to a WSPasswordCallback Object when dealing with UsernameTokens, or to unlock private keys for Signature creation, etc. In WSS4J 2.0.0, the functionality is exactly the same, except that the package of the WSPasswordCallback Object has changed from "org.apache.ws.security" to "org.apache.wss4j.common.ext". Any CallbackHandler implementation will need to be updated to use the new package.

3.3) SAML creation changes

A CallbackHandler implementation is required to create a SAML Assertion, by populating various beans. Similar to the WSPasswordCallback package change, there are also some package changes for SAML. The base package for the SAMLCallback class, and of the various "bean" classes, has changed from "org.apache.ws.security.saml.ext" to "org.apache.wss4j.common.saml".

In addition, the "samlPropFile" and "samlPropRefId" configuration tags have been removed. These tags pointed to a properties file/object, which could be used to define the issuer of the Assertion, as well as the Crypto configuration used to sign the Assertion. In WSS4J 2.0.0, it is the responsibility of the CallbackHandler to configure the SAMLCallback Object appropriately. The SAMLCallback Object has the following new properties, which can be configured to sign an Assertion:
  • boolean signAssertion
  • String issuerKeyName
  • String issuerKeyPassword
  • Crypto issuerCrypto
  • boolean sendKeyValue
  • String canonicalizationAlgorithm
  • String signatureAlgorithm
3.4) Caching changes

WSS4J 2.0.0 uses three EhCache-based caches by default for the following scenarios, to prevent replay attacks:
  • UsernameToken nonces
  • Signed Timestamps
  • SAML 2.0 OneTimeUse Assertions
If you are seeing a error about "replay attacks" after upgrade, then you may need to disable a particular cache. More on this in a future article.