Monday, February 17, 2014

Apache WSS4J 2.0.0 - part VI

This is the sixth of a series of articles on the new features and changes that will be delivered in Apache WSS4J 2.0.0. The fifth article looked at support for signing and encrypting message attachments via the SOAP with Attachments (SWA) Profile 1.1 specification, as well as the associated WS-SecurityPolicy expressions to sign and encrypt attachments. This post looks at the WS-SecurityPolicy model in WSS4J 2.0.0 and how it is used by the streaming code to perform real-time policy validation of an incoming message.

1) WS-SecurityPolicy model in WSS4J 2.0.0

The user of a web services stack such as Apache CXF or Apache Axis can use
WS-SecurityPolicy to define security requirements for service requests/responses. All that is required in addition to this is some user-specific configuration such as usernames, keystores, etc. However, WSS4J (1.6.x) had no awareness of whether WS-SecurityPolicy was used to define the security requirements or not. It was up to the web service stack in question to parse the security policy, build a model, and use the model to configure WSS4J appropriately. Then it was also up to the web services stack to go through the security results produced by WSS4J on processing a message, to see if the results conform to the policy or not.

WSS4J 2.0.0 includes a WS-SecurityPolicy model as part of the new module "wss4j-policy" module. This means that all web services stacks that rely on WSS4J to perform WS-Security no longer need their own model. Instead, they can register the Apache Neethi AssertionBuilder implementations in the WSS4J module to be able to handle WS-SecurityPolicy policies.

2) Real time streaming policy validation

The DOM-based WS-Security implementation in WSS4J 2.0.0 is still not WS-SecurityPolicy aware, in other words the web services stack must still parse the model to set up the configuration for WSS4J, and parse the results list to validate the results against the model. However, a significant new feature of WSS4J 2.0.0 is that the new streaming WS-Security implementation has the ability to perform "real-time" validation of a request against the set of applicable WS-SecurityPolicy policies. This means that bogus requests can be rejected quicker that the older DOM-based code, which may help to avoid DoS based scenarios. In the next few blog posts in this series, I'll be looking at the new streaming WS-Security implementation in more detail.

Monday, February 10, 2014

Apache WSS4J 2.0.0 - part V

This is the fifth of a series of articles on the new features and changes that will be delivered in Apache WSS4J 2.0.0. The fourth article looked at the ability to encrypt passwords in Crypto properties files. This post looks at support for signing and encrypting message attachments via the SOAP with Attachments (SWA) Profile 1.1 specification, as well as the associated WS-SecurityPolicy expressions to sign and encrypt attachments. Note that there is no support in WSS4J 1.6.x for signing or encrypting message attachments.

1) Configuring WSS4J to secure message attachments

There are two ways of using WSS4J, via an "action"-driven approach where WSS4J must be explicitly configured to perform all of the desired functionality, and via a WS-SecurityPolicy-based approach, where the web services stack sets up the WSS4J configuration internally based on a security policy. Let's look at how to secure message attachments for both of these approaches:

a) Securing message attachments via the "action" approach

With the "action" approach to using WSS4J, the user specifies the parts to sign or encrypt via the following configuration tags:
  • ConfigurationConstants.SIGNATURE_PARTS ("signatureParts")
  • ConfigurationConstants.ENCRYPTION_PARTS ("encryptionParts")
The value of these tags is a String in a special format that looks something like "{Content}{http://example.org/paymentv2}CreditCard". In this example, the element to be secured has the name "CreditCard" and namespace "http://example.org/paymentv2". "Content" only applies to Encryption, and means that the Content should be encrypted (as opposed to the full "Element").

In WSS4J 2.0.0, it is possible to sign/encrypt all of the attachments by specifying the following as part of signatureParts/encryptionParts: "{}cid:Attachments;". It is not possible to only sign/encrypt individual attachments, it is all or nothing. Here is an Apache CXF client configuration file with an example of this.

b) Securing message attachments via WS-SecurityPolicy

An easier way to use WSS4J is in conjunction with a web services stack such as Apache CXF and a WS-SecurityPolicy-based policy. It is possible to sign/encrypt all attachments via the policies:
  • <sp:SignedParts><sp:Attachments /></sp:SignedParts>
  • <sp:EncryptedParts><sp:Attachments /></sp:EncryptedParts>
In addition, the "<sp:Attachments>" policy for SignedParts only has two optional child policies called "sp13:ContentSignatureTransform" and "sp13:AttachmentCompleteSignatureTransform", which dictate whether the attachment headers are included or not in the Signature.

2) Supplying the message attachments to WSS4J

Part 1 above only covers how to configure WSS4J to sign/encrypt message attachments. It is also necessary to actually supply the message attachment streams to WSS4J. This is done in WSS4J via a CallbackHandler approach. An AttachmentRequestCallback Object is used to retrieve either a particular Attachment (on the receiving side), or all attachments (on the sending side). The user must implement a CallbackHandler that sets a list of Attachments matching this request on the Callback. Correspondingly, there is also a AttachmentResponseCallback, which represents the secured/processed Attachment.

The good news is that if you are using Apache CXF then all of this is taken care of automatically by a CallbackHandler that retrieves and sets CXF message attachments. Therefore if you are using CXF then you can sign/encrypt message attachments just by passing the configuration detailed in part 1 of this post. Finally, there are some system tests available in CXF that show how both the "action" and "policy" based approaches work to secure attachments. The test code is here and the resource/configuration files are here.

Wednesday, February 5, 2014

Apache WSS4J 2.0.0 - part IV

This is the fourth of a series of articles on the new features and changes that will be delivered in Apache WSS4J 2.0.0. The third article looked at some changes in the area of caching tokens to detect replay attacks. This post looks at a new feature of WSS4J 2.0.0, which is the ability to encrypt passwords in Crypto properties files.

1) Crypto properties

Apache WSS4J uses the Crypto interface to get keys and certificates for encryption/decryption and for signature creation/verification. WSS4J currently ships with three implementations:
  • Merlin: The standard implementation, based around two JDK keystores for key/cert retrieval, and trust verification.
  • CertificateStore: Holds an array of X509 Certificates. Can only be used for encryption and signature verification.
  • MerlinDevice: Based on Merlin, allows loading of keystores using a null InputStream - for example on a smart-card device.
Typically, a Crypto implementation is loaded and configured via a Crypto properties file. This tells WSS4J what Crypto implementation to load, as well as implementation-specific properties such as a keystore location, password, default alias to use, etc. A typical example of the contents of a Crypto properties file for Signature creation is as follows:

org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlin
org.apache.wss4j.crypto.merlin.keystore.type=jks
org.apache.wss4j.crypto.merlin.keystore.password=security
org.apache.wss4j.crypto.merlin.keystore.alias=wss40
org.apache.wss4j.crypto.merlin.keystore.file=keys/wss40.jks

Note that in WSS4J 2.0.0 the "org.apache.ws.security.crypto" prefix used previously is now "org.apache.wss4j.crypto", however both prefixes are accepted by the code.

2) Encrypting passwords in a Crypto properties file

Note in the example above that the password used to load the keystore is in cleartext. One of the new features of Apache WSS4J 2.0.0 is the ability to instead store a (BASE-64 encoded) encrypted version of the keystore password in the Crypto properties file. A new PasswordEncryptor interface is defined to allow for the encryption/decryption of passwords. A default implementation is now provided based on Jasypt called JasyptPasswordEncryptor, which uses "PBEWithMD5AndTripleDES".

The way this works is as follows. The WSPasswordCallback class has an additional "usage" called WSPasswordCallback.PASSWORD_ENCRYPTOR_PASSWORD, which is used to return the password used with a PasswordEncryptor implementation to decrypt encrypted passwords stored in Crypto properties files. When WSS4J is loading a Crypto implementation via a properties file, and it encounters a password encrypted in the format "ENC(encoded encrypted password)", it queries a CallbackHandler for the (master) password to decrypt the encrypted password
using the WSPasswordCallback usage tag given above.

It is possible to pass a custom PasswordEncryptor implementation to WSS4J via the new configuration tag ConfigurationConstants.PASSWORD_ENCRYPTOR_INSTANCE ("passwordEncryptorInstance").

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.