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").