Monday, December 10, 2012

Apache WSS4J 1.6.8 released

Apache WSS4J 1.6.8 has been released. The list of issues fixed is available here. One of the most significant improvements is a fix for using WSS4J with XML Signature on Websphere. A new feature has also been added to WSS4J 1.6.8, namely the ability to define which algorithms are acceptable when processing an inbound request. This functionality has already been integrated into CXF and will be available in the 2.7.1, 2.6.4 and 2.5.7 releases. This essentially means that rather than check the algorithms against the relevant AlgorithmSuite used as part of WS-SecurityPolicy after WSS4J has finished processing the security header, the algorithms will be checked by WSS4J in real-time when processing the header.

A new page has been added to the WSS4J website which describes 'security best practices' when using WSS4J. The points are summarised as follows:
  • Upgrade from WSS4J 1.5.x to WSS4J 1.6.x
  • Upgrade to the latest minor release as soon as possible
  • Use WS-SecurityPolicy to enforce security requirements
  • Use RSA-OAEP for the Key Transport Algorithm
  • Avoid using a cbc Symmetric Encryption Algorithm
  • Use Subject DN regular expressions with chain trust
  • Specify signature algorithm on receiving side

Monday, October 22, 2012

Apache XML Security for Java 1.5.3 released

Apache XML Security for Java 1.5.3 has been released. This release features support for new XML Signature 1.1 KeyInfo extensions. It also fixes a number of bugs including a problem when message sizes are greater than 512 MB. The list of issues fixed is available at the Apache JIRA.

Wednesday, October 3, 2012

XML Signature Wrapping attacks on Web Services

The previous blog post looked at SOAP Action spoofing attacks on Web Services and discussed a recent security advisory in this area in Apache CXF. This vulnerability was uncovered with the help of the WS-Attacker tool referenced here. This paper also covers a different type of attack on WS-Security enabled Web Services, namely XML Signature Wrapping attacks. The WS-Attacker tool also offers some functionality to test Web Service endpoints for vulnerability against these types of attacks. In this post we will look at how to protect against XML Signature Wrapping attacks in Apache CXF.

1) XML Signature wrapping attacks

It is possible to sign a portion of a SOAP Web Service request or response at the message level using XML Signature. The message contains a security header with a Signature Element, that references one or more message parts that have been signed. Typically, the message parts are referenced by an Id, and so to validate the signature the recipient must find the Element in the request that has the corresponding Id. An XML Signature wrapping attack essentially exploits the fact that the Signature Element does not convey any information as to where the referenced Element(s) is(are) in the Document tree.

Consider a scenario where the SOAP Body of a request is signed by a signature placed in the security header of the request. The message recipient checks that the signature is correct and validates trust in the signing credential. Finally, the recipient checks to see that the required Element (in this case the SOAP Body) was actually signed, by comparing the wsu:Id of the SOAP Body to the Reference URI in the Signature.

An XML Signature wrapping attack against this scenario could work as follows. A malicious (man-in-the-middle) user could take a valid request and copy the SOAP body and insert it as part of a header in the request. The malicious user then freely alters the SOAP Body, but preserves the same wsu:Id. The message recipient must search for the Reference URI as part of the signature validation process, and hits the copied SOAP Body Element first. This verifies correctly as it has not been changed. Finally, the recipient checks to see if the Id of the SOAP Body was actually referenced in the signature (which it was, even though the SOAP Body itself was not signed).

Apache WSS4J has a built-in guard against this kind of attack, whereby an ID referenced in an XML Signature cannot appear more than once in a SOAP Envelope. However, there are more sophisticated types of wrapping attacks which can defeat this defence. The crucial thing to realise is that for XML Signature you must check to see that what you are expecting to be signed was actually signed. Apache WSS4J does not perform this kind of check, instead it is left up to the third party application (Apache CXF for the purposes of this article). 

2) Protecting against XML Signature wrapping attacks in Apache CXF

There are two ways to configure WS-Security in Apache CXF, the recommended approach based on WS-SecurityPolicy, and the older and less sophisticated approach of specifying individual security actions to perform.

2.1) WS-SecurityPolicy

The WS-SecurityPolicy approach offers easy protection against signature wrapping attacks via the WS-SecurityPolicy SignedParts and SignedElements policies. The SignedElements policy takes a number of XPath expressions corresponding to the Elements that must be signed, should they be included in the request. The XPath expression must not be a relative expression for the purposes of protection against this attack.

A more common approach is to use the WS-SecurityPolicy "SignedParts" policy. This policy allows the user to specify that the SOAP Body and any number of SOAP Headers must be signed. For example:

<sp:SignedParts>
<sp:Body />
<sp:Header Name="..." Namespace="..."
</sp:SignedParts>

Apache CXF makes sure that the SOAP Body and any specified SOAP header is actually signed, rather that just comparing Id's as outlined in the attack scenario above, this circumventing any XML Signature wrapping attack.

2.2) Older WS-Security approach

The older non-policy based approach to configuring WS-Security does not perform any checking by default of what Elements were signed, and so is vulnerable to XML Signature wrapping attacks out of the box. One way to remedy this since CXF 2.2.8 is to install the CryptoCoverageChecker interceptor. This allows you to define an XPath Expression corresponding to an Element that must be signed (or encrypted). Installing this interceptor defeats an XML Signature Wrapping attack (see the wiki for more details).

However, the CryptoCoverageChecker is somewhat complex to set up for the most common use-cases for signature verification and decryption, as it involves adding XPath expressions and the corresponding prefix/namespace pairs. In Apache CXF 2.4.9, 2.5.5 and 2.6.2, a new subclass of CryptoCoverageChecker has been introduced. The DefaultCryptoCoverageChecker provides an easy way to ensure that the SOAP Body is signed or encrypted, that the Timestamp is signed, and that the WS-Addressing ReplyTo and FaultTo headers are signed (if they are present in the message payload).

The default configuation is that the SOAP Body, (WSU) Timestamp and WS-Addressing ReplyTo and FaultTo headers must be signed (if they exist in the message payload). This provides an out-of-the-box way of preventing XML Signature wrapping attacks. All that is required is that the DefaultCryptoCoverageChecker be added to the in-interceptor chain. I strongly recommend that you consider doing this if you are still using the older configuration for a WS-Security enabled endpoint. For example:

<jaxws:inInterceptors>
    <bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
        <constructor-arg>
            <map>
                <entry key="action" value="Signature Timestamp"/>
                <entry key="signaturePropFile" value="..."/>
                <entry key="passwordCallbackClass"value="..."/>
           </map>
        </constructor-arg>
    </bean>
    <bean class="org.apache.cxf.ws.security.wss4j.DefaultCryptoCoverageChecker"/>
</jaxws:inInterceptors>

Thursday, September 20, 2012

SOAP Action Spoofing Attacks on Web Services

A recent paper by Christian Mainka, Juraj Somorovsky and Jörg Schwenk at the Horst Görtz Institute for IT Security of the Ruhr University Bochum, describes an open-source tool that can be used to perform penetration testing attacks on Web Services. In particular, this tool has uncovered a vulnerability in Apache CXF to a type of SOAP Action spoofing attack, that is the content of a recently disclosed security vulnerability. This vulnerability has been fixed in versions 2.4.9, 2.5.5, and 2.6.2 of CXF.
Each operation in a SOAP web service can be associated with a SOAP Action String, for example in the WSDL binding or via an annotation. The web service client can send the SOAP Action String as a header with the request as a way of letting the web service know what operation is required.

In some cases, Apache CXF uses the received SOAP Action to select the correct operation to invoke, and does not check to see that the message body is correct. This can be exploitable to execute a SOAP Action spoofing attack, where an adversary can execute another operation in the web service by sending the corresponding SOAP Action. This attack only works if the different operation takes the same parameter types, and hence has somewhat limited applicability.

This attack also only applies for web services that use unique SOAP Actions per service operation which is not the default in CXF. Also note that WS-Policy validation is done against the operation being invoked and thus the incoming message must meet those policy requirements as well, also limiting applicability.

Friday, August 3, 2012

Apache WSS4J 1.6.7 released

Apache WSS4J 1.6.7 has been released. The release notes are available here. The main features of the release are:
  • A critical fix for a concurrency bug in the MemoryReplayCache
  • Subject DN Certificate Constraint support (as blogged previously).
  • A number of relatively minor fixes identified by interop testing with WCF.
  • A fix that prevented the 1.6.6 release from being deployed in an OSGi container.

Thursday, August 2, 2012

Subject DN Certificate Constraint support in Apache WSS4J and CXF

Apache WSS4J 1.6.7 features support for specifying constraints on the subject DN of the certificate used for signature validation. This functionality will also be available in the forthcoming Apache CXF 2.6.2, 2.5.5 and 2.4.9 releases.

After a successful signature validation using a certificate referenced in the KeyInfo structure of an XML Signature, the next step is to establish trust in the certificate. The term "direct trust" applies to when the certificate is contained directly in the signature keystore. In this case, certificate constraints are not required as we "directly trust" the certificate. The term "chain trust" refers to when the issuing certificate of the certificate used for signature validation is contained in the signature truststore, and the certificate path of the received certificate is verified.

There is a potential security issue when "chain trust" is applicable. Although the certificate used for signature validation might be "trusted" in a general sense (via a trusted issuing certificate), you may not wish to accept every certificate issued by the trusted certificate. This is particularly relevant if any certificate in your signature truststore is (or can potentially be) used to issue a wide range of certificates.

This is where the concept of constraints on the subject DN of a trusted certificate comes in. The idea is that the user can specify a list of regular expressions, one of which (note not all) must be applicable to the subject DN of a (trusted) certificate used for signature verification. These constraints are not used when the certificate is contained in the keystore (direct trust). If no cert constraints are defined, and a successful trust validation is done using "chain trust", a warning message is logged indicating that a potential security risk exists in signature validaition.

Subject DN Cert Constraints can be configured in WSS4J by specifying a WSHandlerConstants tag, see the WSS4J configuration page for more information. To see this functionality in action take a look at the corresponding WSS4J Unit Test, which uses a cert constraint of ".*CN=Colm.*O=Apache.*". Certificate constraint support can also be enabled in CXF via the endpoint property tag "ws-security.subject.cert.constraints". See the CXF WS-SecurityPolicy for more information.

Tuesday, June 19, 2012

SAML Web SSO profile support in Apache CXF

Apache CXF has an impressive range of security features for JAX-RS endpoints. It also has excellent documentation in this space, see for example the JAX-RS documentation for OAuth, SAML Assertions and XML Encryption/Signature.  Apache CXF 2.6.1 enhances the JAX-RS security story further by featuring support for the SAML 2.0 Web SSO profile.

The basic standard scenario for Web SSO involves a client browser accessing a secured (JAX-RS) endpoint. The endpoint constructs a SAML AuthnRequest and includes it in redirecting the browser to a Identity Provider (IDP) for authentication (via a dialog). The IDP constructs a SAML Response, and redirects the browser to a Request Assertion Consumer Service (RACS) URI contained in the AuthnRequest.  The RACS validates the SAML Response and redirects the browser yet again to the original secured endpoint. The endpoint stores the session in a cookie (hence single sign-on) and access is granted to the resource. The following steps detail how to implement this scenario in Apache CXF using the new "cxf-rt-rs-security-sso-saml" module.

1) JAX-RS binding filters

The SAML 2.0 bindings specification defines HTTP redirect and HTTP POST bindings which can be used to "redirect" the client browser, e.g. from the secured endpoint to the IDP. Apache CXF 2.6.1 provides a separate JAX-RS filter to support these bindings. Therefore, the first step in securing a JAX-RS endpoint is to decide which of these two bindings to use. The SamlRedirectBindingFilter class providers support for the HTTP redirect binding, and the SamlPostBindingFilter provides support for the HTTP POST binding. Both of these filters share the following configuration properties.

1.1) Required Configuration Properties

Each filter implementation must be configured with the URL of the IDP, as well as the URL of the RACS. It must also be configured with a SPStateManager implementation to keep track of the Authenticated sessions. CXF ships with an EhCache based implementation:
  • SPStateManager stateProvider - An object which keeps track of authenticated sessions.
  • String idpServiceAddress - The URL of the IDP.
  • String assertionConsumerServiceAddress - The URL of the RACS. This can be a relative or absolute URL.
1.2) Signature Configuration Properties 

The following configuration properties are only required if you wish to sign the AuthnRequest:
  • boolean signRequest - Whether to sign the AuthnRequest or not. The default is false.
  • String signatureUsername - The keystore alias to use to sign the AuthnRequest.
  • Crypto signatureCrypto - A WSS4J Crypto object if the SAML AuthnRequest is to be signed.
  • String signaturePropertiesFile - This points to a properties file that can be used to load a Crypto instance if the SAML AuthnRequest is to be signed. 
  • CallbackHandler callbackHandler - A CallbackHandler object to retrieve the private key password used to sign the request.
  • String callbackHandlerClass - A class name that is loaded for use as the CallbackHandler object. 
Either the "signatureCrypto" or "signaturePropertiesFile" properties must be set if "signRequest" is set to true. Similarly, either "callbackHandler" or "callbackHandlerClass" must be configured.

1.3) Optional Configuration Properties

Here are some optional configuration properties that can be set:
  • long stateTimeToLive - The default value (in milliseconds) that a session is valid for. The default value is 2 minutes. 
  • String issuerId - The Issuer Id value to be included in the AuthnRequest. It defaults to the Base URI.
  • AuthnRequestBuilder authnRequestBuilder - An object that constructs the AuthnRequest. It defaults to DefaultAuthnRequestBuilder.
There are some additional optional configuration properties relating to domains and web application contexts that will be covered in more detail on the CXF wiki.

1.4) Sample Spring configuration

Here is a sample spring configuration extract to support the redirect binding filter which signs AuthnRequests:

<bean id="stateManager" class="org.apache.cxf.rs.security.saml.sso.state.EHCacheSPStateManager"/>

<bean id="ssoSignedRedirectURI"  class="org.apache.cxf.rs.security.saml.sso.SamlRedirectBindingFilter">
        <property name="idpServiceAddress" value="https://.../idp-sig/"/>
        <property name="assertionConsumerServiceAddress"
                  value="/racs/sso"/>
        <property name="stateProvider" ref="stateManager"/>
        <property name="addEndpointAddressToContext" value="true"/>
        <property name="callbackHandlerClass" value="....SSOCallbackHandler"/>
        <property name="signatureUsername" value="myservicekey"/>
        <property name="signaturePropertiesFile" value="serviceKeystore.properties"/>
        <property name="signRequest" value="true"/>
</bean>

<jaxrs:server address="/app1">
       <jaxrs:serviceBeans><ref bean="..."/></jaxrs:serviceBeans>
       <jaxrs:providers><ref bean="ssoRedirectURI"/></jaxrs:providers>
</jaxrs:server>

2) The Request Assertion Consumer Service

The JAX-RS filters described above take care of creating a SAML AuthnRequest, optionally signing it, and redirecting the client browser to the IDP. The next step is to define a RequestAssertionConsumerService (RACS) which will intercept the SAML Response from the IDP. The RACS processes the SAML Response, and validates it in a number of ways:
  • The SAMLProtocolResponseValidator validates the Response against the specifications and checks the signature of the Response (if it exists), as well as doing the same for any child Assertion of the Response. It validates the status code of the Response as well. 
  • The SAMLSSOResponseValidator validates the Response according to the Web SSO profile. 
If validation is successful the RACS redirects to the service provider endpoint.

2.1) Configuration properties shared with the filters

The RequestAssertionConsumerService that ships with CXF shares a number of configuration properties with the filters, mainly relating to state and signature configuration:
  • SPStateManager stateProvider - An object which keeps track of authenticated sessions. This is required.
  • long stateTimeToLive - The default value (in milliseconds) that a session is valid for. The default value is 2 minutes.
  • Crypto signatureCrypto - A WSS4J Crypto object to use to validate a signed Response.
  • String signaturePropertiesFile - This points to a properties file that can be used to load a Crypto instance for signature validation.
  • CallbackHandler callbackHandler - A CallbackHandler object to retrieve the private key password used to decrypt an encrypted request.
  • String callbackHandlerClass - A class name that is loaded for use as the CallbackHandler object.  
Only the "stateProvider" property is required. Either the "signatureCrypto" or "signaturePropertiesFile" properties must be set if you wish to support verifying signed Responses, or signed Assertions contained in a Response. Similarly, either "callbackHandler" or "callbackHandlerClass" must be configured if you wish to support decrypting encrypted Assertions. 

2.2) Additional Optional Configuration properties

The RACS supports the following additional (optional) configuration properties:
  • boolean supportDeflateEncoding - Whether Deflate encoding is used to inflate a token received via the Redirect binding. The default is true.
  • boolean supportBase64Encoding - Whether the token is Base64 decoded or not. The default is true.
  • boolean enforceAssertionsSigned - Whether the Assertions contained in a Response must be signed or not. The default is true.
  • boolean enforceKnownIssuer - Whether the Issuer of the Response (and child Assertions) is "known" to the RACS. This value is compared against the IDP URL configured on the filter. The default value is true.
  • TokenReplayCache<String> replayCache - A TokenReplayCache implementation to store Assertion ID's for the POST binding to guard against replay attacks. The default uses an implementation based on EhCache.
2.4) Sample Spring Configuration

Here is a sample spring configuration extract to set up a RACS, that could be used with the filter configuration in section 1.4:

 <bean id="consumerService" class="org.apache.cxf.rs.security.saml.sso.RequestAssertionConsumerService">
        <property name="stateProvider" ref="stateManager"/>
        <property name="signaturePropertiesFile" value="serviceKeystore.properties"/>
        <property name="enforceKnownIssuer" value="false"/>
        <property name="callbackHandlerClass" value="...SSOCallbackHandler"/>
</bean>

3) The Identity Provider (IDP)

The remaining piece of the puzzle is the Identity Provider (IDP) which receives the SAML AuthnRequest from the service provider, processes it accordingly, and then interacts with the client browser to authenticate the client. It then creates a SAML Response and redirects the client browser to the RACS defined in the AuthnRequest. Apache CXF does not (yet) ship with an IDP, although this may change in the near future. However, there are a number of open-source IDPs that can be used with a CXF JAX-RS endpoint that supports SAML Web SSO. These include Shibboleth, PicketLink, OpenAM, JOSSO, etc. I have tested against all of these products. Report any interop issues to the CXF JIRA.

4) Ongoing Development

SAML Web SSO profile support is still being actively developed. A number of bugs have been fixed that do not yet appear in a released version of CXF. For example, support for decrypting encrypted Assertions in a SAML Response, and some bugs relating to signed Assertions (CXF-4352 and CXF-4365).

Thursday, June 14, 2012

Simplified Apache CXF STS configuration

The Apache CXF STS configuration options have been covered in detail in previous posts on this blog. Following some suggestions by Glen Mazza, a new simplified way of configuring the STS will be available in Apache CXF 2.6.2. This new configuration is essentially a simpler and more intuitive way of catering for the most common STS scenarios. The older configuration style is still fully supported.

An example of how to configure the CXF STS using the old configuration is available here. It involves a mixture of the STS Provider API that lives in the WS-Security module in CXF, and the concrete STS functionality that is available in the STS services module in CXF. The SecurityTokenServiceProvider in the CXF API is instantiated with implementations of the various Operations (Issue/Validate/etc.) that are available in the CXF STS. However, the flexibility of this approach leads to a slightly verbose configuration style, which is perhaps overly complicated for the most common use-cases.

An example of the simpler configuration approach is available here. Rather than use the SecurityTokenServiceProvider in the CXF API, it uses a sub-class in the CXF STS (DefaultSecurityTokenServiceProvider). This implementation supports the issue and validate bindings by default. It also supports the ability to issue and validate SAML Tokens, and to validate UsernameTokens and X.509 Tokens. Therefore, for any of these use-cases there is no need to use the old-style configuration, which involves explicitly instantiating each TokenProvider or TokenValidator instance and setting them on an IssueOperation/ValidateOperation instance.  However, if you want to use the renew or cancel bindings, or do anything with SecurityContextTokens, it's necessary to use the old configuration.

The DefaultSecurityTokenServiceProvider can be configured with the following (optional) properties:
  • boolean encryptIssuedToken - Whether to encrypt the issued token or not. The default is false.
  • List<ServiceMBean> services - A list of service endpoints to support. See here for more information.
  • boolean returnReferences - Whether to return references to an issued token or not. The default is true.
  • TokenStore tokenStore - The TokenStore caching implementation to use. See here for more information.
  • ClaimsManager claimsManager - The ClaimsManager to use if you want to be able to handle claims. See here for more information.

Thursday, June 7, 2012

New security vulnerabilities in Apache CXF

Two new security vulnerabilities have been announced in Apache CXF. Those of you using WS-SecurityPolicy should read the announcements carefully to make sure that you are not affected. If these vulnerabilities apply to your deployment then you should upgrade to a more recent version of CXF that contains fixes for these vulnerabilities. The issues in question are:
  • CVE-2012-2378 - Apache CXF does not pick up some child policies of
    WS-SecurityPolicy 1.1 SupportingToken policy assertions on the client
    side.
  • CVE-2012-2379 - Apache CXF does not verify that elements were
    signed or encrypted by a particular Supporting Token.

     

Wednesday, June 6, 2012

Transforming Claims and Tokens in the CXF STS

The Security Token Service (STS) shipped with Apache CXF 2.6.0 contains some advanced functionality relating to handling claims, as well as transforming both claims and security tokens.

1) ClaimsValue support

The following article describes in detail how Claims are handled by the STS. The client includes a Claims element in the request to the STS, which typically contains one or more ClaimType URIs, that describe the types of claims that are to be included in the issued token. For example, the following element indicates that the client wants the STS to embed the role of the authenticated client in the issued token:

<t:Claims Dialect="http://.../identity">
    <ic:ClaimType Uri="http://.../claims/role"/>
</t:Claims>

The RequestParser object parses the client request and converts a received Claims element into a RequestClaimCollection object. The RequestClaimCollection is just a list of RequestClaim objects, along with a dialect URI. The RequestClaim object holds the claimType URI as well as a boolean indicating whether the claim is optional or not. Since the 2.6.0 (and 2.5.3) release, the RequestClaim object now also holds a claimValue String. This means that the STS now supports processing a Claims element with ClaimValue elements rather than ClaimType elements, e.g.:

<t:Claims Dialect="http://.../identity">
    <ic:ClaimValue Uri="http://.../claims/role">
        <ic:Value>admin</ic:Value>
    </ic:ClaimValue>
</t:Claims>

2) Custom Claims Parsing

Prior to CXF 2.5.3 and 2.6.0, it was not possible to change how the RequestParser parses a received Claims child element into a RequestClaim object. In CXF 2.5.3 and 2.6.0 this behaviour is configurable. The ClaimsParser interface defines a method to parse a Claims child element, as well as return the supported dialect URI that the implementation can handle. CXF ships with a default implementation that handles the "http://schemas.xmlsoap.org/ws/2005/05/identity" URI, and can parse both ClaimType and ClaimValue elements.

The RequestParser is passed a list of ClaimsParser objects, and iterates through the list to find a ClaimsParser implementation that can handle the given dialect. It uses the first ClaimsParser implementation that matches the supported dialect to generate a RequestClaim object. Therefore, to support a custom or non-standard Claims dialect, it is necessary to implement one or more ClaimsParser implementations to handle that dialect. These ClaimsParser objects must then be set on the ClaimsManager.

3) Token and Claims Transformation

The following blog article describes how token transformation works in the STS prior to CXF 2.5.3 and 2.6.0. Token transformation occurs when the user calls the WS-Trust Validate binding to validate a given token. If the token is valid, and if the user specifies a TokenType that differs from the type of the given token, the STS will attempt to transform the validated token into a token of the requested type. If the token is being issued in a different realm to that of the validated token, the principal associated with the validated token may also need to be transformed. This can be done by specifying an IdentityMapper object on the STSPropertiesMBean object used to configure the STS. This interface is used to map identities across realms. It has a single method:
  • Principal mapPrincipal(String sourceRealm, Principal sourcePrincipal, String targetRealm) - Map a principal from a source realm to a target realm
If the source realm is not null (the realm of the validated token as returned in TokenValidatorResponse), and if it does not equal the target realm (as set by the RealmParser), then the identity mapper is used to map the principal to the target realm and this is stored in TokenProviderParameters for use in token generation.

3.1) Transformation via Relationships

The logic for token transformation as described above is abstracted in CXF 2.5.3 and 2.6.0 to add the ability to perform more powerful and custom token and claim transformations. Two new properties are added to the STSPropertiesMBean object:
  • List<Relationship> getRelationships() - Get the list of Relationship objects to use.
  • RelationshipResolver getRelationshipResolver() - Get the RelationshipResolver object to use.
The Relationship class holds the parameters that will be required to define
a one-way relationship between a source and target realm. It consists of five properties:
  • String sourceRealm - The source realm of this relationship.
  • String targetRealm - The target realm of this relationship.
  • IdentityMapper identityMapper - The IdentityMapper to use to map a principal from the source realm to the target realm.
  • ClaimsMapper claimsMapper - The ClaimsMapper to use to map claims from the source realm to the target realm.
  • String type - The relationship type. Two types of relationships are supported: FederatedIdentity and FederatedClaims.
The RelationshipResolver is instantiated with a list of Relationship objects and contains the following method:
  • Relationship resolveRelationship(String sourceRealm, String targetRealm) - Retrieve the Relationship object that maps from the given source realm to the given target realm. 
3.2) Principal Transformation using Relationships

The logic described above for transforming principals when doing token transformation is still valid, but is deprecated in favour of using Relationships. When the token is being issued in a different realm to that of the validated token, the STS will first try to retrieve a RelationshipResolver object from the STSPropertiesMBean. If it exists, it will query it to retrieve a Relationship object that can map claims and principals from the source realm to the target realm. If it finds a match it will store this object on the token provider parameters, so the TokenProvider implementation can use this RelationshipResolver to perform some internal or custom mapping when generating the transformed token.

If the type of the Relationship object matches the FederatedIdentity type, then the STS will try to retrieve an IdentityMapper object to map the principal from the Relationship object. Failing this it will try to query the STSPropertiesMBean object for a generic IdentityMapper object if one is configured. This IdentityMapper object will be used to map the principal to the target realm. 

3.4) Claims Transformation using Relationships

If the type of the Relationship object retrieved above is "FederatedClaims", then the principal is not mapped, as claims are transformed at the time when the claims are required to create a token, e.g. in ClaimsAttributeStatementProvider.



Monday, May 28, 2012

Apache WSS4J 1.6.6 released

Apache WSS4J 1.6.6 has been released and is available for download. WSS4J 1.6.6 contains an upgrade to use XML Security 1.5.2, the features of which are covered in a previous blog entry. Some significant fixes in the new release include:
  • Support for a configurable clock skew setting when processing the "NotBefore" timestamp associated with a SAML Token. 
  • Extending the maximum Time-To-Live setting associated with validating a Timestamp from the old value of 25 days.
  • Support for populating SubjectConfirmationData attributes of a SAML Assertion.
  • Support for a wider range of AuthenticationMethod values for SAML 1.1 Assertions.

Wednesday, May 16, 2012

Apache XML Security for Java 1.4.7 and 1.5.2 released

There are two new releases for the Apache XML Security for Java project, which are now available for download. The main feature of the 1.5.2 release is that the default canonicalization algorithm for encryption has changed from inclusive with comments to a new canonicalization algorithm that preserves the physical representation of the element being encrypted. This change fixes a problem where an element might be decrypted to the wrong namespace. The release notes are available here.

The 1.4.7 release fixes a problem with a missing KeyInfo Element when multiple elements are encrypted, as well as a number of other issues. The release notes are available here.

Friday, April 27, 2012

Batch processing in the Apache CXF STS

A previous blog entry covered the ability to renew SAML Tokens in the Security Token Service (STS) in Apache CXF 2.6.0. In this post, we will look at another major new feature in the STS in CXF 2.6.0, namely the addition of batch processing. Batch processing gives the ability to issue, validate, renew or cancel multiple tokens at the same time.

1) Batch Processing in the STS Provider framework

The STS implementation in CXF is based on the STS Provider framework in the security runtime, which is essentially an API that can be used to create your own STS implementation. The SEI (Service Endpoint Implementation) contains the following method that can be used for batch processing:
  • RequestSecurityTokenResponseCollectionType requestCollection(RequestSecurityTokenCollectionType requestCollection)
This method can be used to execute batch processing for any of the core operations (issue/validate/renew/cancel). To do this it is necessary to implement the RequestCollectionOperation interface, and to install it in the STS Provider.

2) Batch Processing in the STS implementation

The STS ships with an implementation of the RequestCollectionOperation interface described above that can be used to perform batch processing. The TokenRequestCollectionOperation is essentially a wrapper for the other operations, and does no processing itself. It iterates through the request collection that was received, and checks that each request has the same RequestType. If not then an exception is thrown. It then dispatches each request to the appropriate operation. To support bulk processing for each individual operation, it is necessary to set the appropriate implementation for that operation on the TokenRequestCollectionOperation, otherwise an exception will be thrown.

3) Batch Processing example

Take a look at the following test to see how batch processing works in practice. In this test, the client requests two tokens via the (batch) issue binding, a SAML 1.1 and a SAML 2.0 token. The client then validates both tokens at the same time using the batch validate binding. The STSClient class used by the WS-Security runtime in CXF does not currently support bulk processing. Therefore, the test uses a custom STSClient implementation for this purpose.

The WSDL the STS uses two separate bindings for issue and validate, to cater for the fact that two separate SOAP Actions must be used for bulk issue and validate for the same operation. The STS configuration is available here. Note that the TokenRequestCollectionOperation is composed with the TokenIssueOperation and TokenValidateOperation, to be able to bulk issue and validate security tokens:
<bean class="org.apache.cxf.sts.operation.TokenRequestCollectionOperation" 
  id="transportRequestCollectionDelegate">
  <property name="issueSingleOperation" ref="transportIssueDelegate">
  <property name="validateOperation" ref="transportValidateDelegate>
</bean>


Wednesday, April 25, 2012

Security Token Caching in Apache CXF 2.6 - part II

This post is the second in a two-part series on how security tokens are cached in Apache CXF 2.6. Part I covered how UsernameToken nonces and Timestamps are cached to prevent replay attacks, using a default caching implementation based on EhCache. In this post I will cover how security tokens are cached in the CXF WS-Security runtime and also in the STS.

1) CXF WS-Security runtime token caching

CXF caches tokens in the security runtime in the following circumstances:
  • When the IssuedTokenInterceptorProvider is invoked to obtain an Issued token from an STS.
  • When the STSTokenValidator is used to validate a received UsernameToken, BinarySecurityToken or SAML Assertion to an STS.
  • When the SecureConversation protocol is used.
  • When the WS-Trust SPNEGO protocol is used.
  • When tokens are obtained from a Kerberos KDC.
In each of these use-cases, the retrieved token is cached to prevent repeated remote calls to obtain the desired security token. There is no built-in support as yet to cache tokens in the WS-Security layer to prevent repeat validation. Of course this could be easily done by wrapping the existing validators with a custom caching solution.

1.1) SecurityTokens

CXF defines a SecurityToken class which encapsulates all relevant information about a successful authentication event in the security runtime (as defined above). In particular, it contains the following items (amongst others):
  • A String identifier of the token. This could be a SAML Assertion Id, the Identifier element of a SecurityContextToken, or the wsu:Id of a UsernameToken, etc.
  • The DOM Element that represents that security token.
  • Attached and Unattached reference elements for that token that might have been retrieved from an STS.
  • A byte[] secret associated with the token.
  • An expiration date after which the token is not valid.
  • A String TokenType that categorizes the token.
  • An X.509 Certificate associated with the token.
  • The principal associated with the token.
  • A hashcode that represents the security token (normally the hashcode of the underlying WSS4J object).
  • An identifier of another SecurityToken that represents a transformed version of this token.
 1.2) TokenStores

CXF defines a TokenStore interface for caching SecurityTokens in the WS-Security runtime module. Prior to CXF 2.6, a simple default HashMap based approach was used to cache security tokens. In CXF 2.6, Ehcache is used to provide a suitable default TokenStore implementation to cache security tokens. Tokens are stored until the expiry date of the token if it exists, provided it does not exceed the maximum storage time of 12 hours. If it exceeds this, or if there is no expiry date provided in the security token, it is cached for the default storage time of 1 hour. If the token is expired then it is not cached. This default storage time is configurable. Note that while Ehcache is a compile time dependency of the WS-Security module in CXF, it can be safely excluded in which case CXF will fall back to use the simple HashMap based cache, unless the user specifically wants to implement an alternative TokenStore implementation and configure this instead.

Apache CXF 2.6 provides support for configuring caching via the following JAX-WS properties:
  • "org.apache.cxf.ws.security.tokenstore.TokenStore" - The TokenStore instance to use to cache security tokens. By default this uses the EHCacheTokenStore if Ehcache is available. Otherwise it uses the MemoryTokenStore.
  • "ws-security.cache.config.file" - Set this property to point to a configuration file for the underlying caching implementation. By default the cxf-ehcache.xml file in the CXF rt-ws-security module is used.
2) CXF STS token caching

Token caching in the CXF STS has been previously (briefly) covered in the STS documentation. Prior to CXF 2.6, the STS shipped an interface called "STSTokenStore" that contained some additional functionality related to storing SecurityTokens specific to the STS. In CXF 2.6, this interface has been removed, and instead the same TokenStore interface is used as in the security runtime. A TokenStore instance can be set on any of the STS operations (see AbstractOperation), and it will be used for caching in the token providers, validators, etc. The STS ships with two TokenStore implementations, a DefaultInMemoryTokenStore which just wraps the EHCacheTokenStore discussed above, and an implementation based on HazelCast.

Token caching works in different ways depending on where it is used. Both token providers (SAML and SecurityContextTokens) that ship with the STS cache a successfully generated token. When a SAML or SecurityContextToken (or UsernameToken) is received by the STS for validation, it will first check to see whether the token is stored in the cache. If it is then validation is skipped. If it is not, then the TokenValidator will re-validate the token, and store it in the cache if validation is successful. A slight caveat to this behaviour for SAML Tokens is that token validation is only skipped if the token that is stored in the cache originally was signed, as this signature value is used to check to see if the two SAML Tokens are equal. The TokenCanceller implementation for cancelling SecurityContextTokens in the STS removes the token from the cache, if the token is stored in the cache and proof-of-possession passes.

Finally, two significant changes in CXF 2.6.0 concerning caching in the STS relate to the length of time tokens are valid for. Prior to CXF 2.6.0, SecurityContextTokens and SAML Tokens issued by the STS were valid for a default (configurable) value of 5 minutes. In CXF 2.6.0, both tokens are now issued for a default value of 30 minutes, and are stored in the cache for this length of time as a result.

Monday, April 23, 2012

Note on CVE-2011-1096

A new attack on the XML Encryption standard has recently emerged and is described by the security advisory CVE-2011-1096:
Tibor Jager, Juraj Somorovsky, Meiko Jensen, and Jorg Schwenk
described an attack technique against W3C XML Encryption Standard,
when the block ciphers were used in cipher-block chaining (CBC)
mode of operation. A remote attacker, aware of a cryptographic
weakness of the CBC mode could use this flaw to conduct
chosen-ciphertext attacks, leading to the recovery of the entire
plaintext of a particular cryptogram by examining of the differences
between SOAP responses, sent from JBossWS, J2EE Web Services server.
There is no (immediate) security "fix" for this issue, as it is an attack on the standard itself. However, the attack can be prevented by using a symmetric algorithm such as AES-128 or AES-256 with GCM. Support for GCM algorithms is available in Apache Santuario 1.5.0 and Apache WSS4J 1.6.5 (see here).

One problem with using a GCM algorithm via WS-SecurityPolicy is that no AlgorithmSuite policy is defined in the WS-SecurityPolicy 1.3 specification that uses GCM. Until the WS-SecurityPolicy specification is updated to support GCM, Apache CXF has defined its own AlgorithmSuite policies to use GCM algorithms. These AlgorithmSuites are called "Basic128GCM", "Basic192GCM" and "Basic256GCM" in the namespace "http://cxf.apache.org/custom/security-policy", and are exactly the same as the corresponding standard "Basic(128|192|256)" policies, except that GCM is used instead of CBC. For example, to use the AES-128 Algorithm with GCM mode, one would use a policy like:

<sp:AlgorithmSuite>
    <wsp:Policy>
        <sp-cxf:Basic128GCM xmlns:sp-cxf="http://cxf.apache.org/custom/security-policy"/>
    </wsp:Policy>
</sp:AlgorithmSuite>

CXF contains a number of system tests that show how to use these new AlgorithmSuites. The WSDL containing the embedded policies is here, and the test itself is here. This functionality is available from Apache CXF 2.4.7, 2.5.3, and 2.6.0.

In addition to this, the CXF JAX-RS XML Security functionality has been updated so that GCM algorithms can be used for encryption and decryption via the BouncyCastle JCE provider. A test is available here. For more information on the CXF JAX-RS XML Security functionality, checkout Sergey's blog or the CXF wiki page.

Friday, April 20, 2012

Renewing SAML Tokens in the Apache CXF STS

Apache CXF 2.6.0 sees a number of improvements to the functionality of the SecurityTokenService (STS). These include relatively minor tasks such as supporting SymmetricKeys for Entropy and BinarySecret Elements, supporting SecurityTokenReferences in UseKey Elements, and supporting KeyInfo/KeyValue Elements in UseKey Elements. However, the STS also includes two major new features. The first of these new features, the ability to renew (SAML) tokens, is covered in this blog entry.

1) The TokenRenewer interface

Security tokens are renewed in the STS via the TokenRenewer interface. It has the following methods:
  • void setVerifyProofOfPossession(boolean verifyProofOfPossession) - A boolean switch to enable or disable the proof of possession requirement.
  • void setAllowRenewalAfterExpiry(boolean allowRenewalAfterExpiry) - A switch to enable or disable the ability to renew tokens after they have expired.
  • boolean canHandleToken(ReceivedToken renewTarget) - Whether this TokenRenewer implementation can renew the given token.
  • boolean canHandleToken(ReceivedToken renewTarget, String realm) - Whether this TokenRenewer implementation can renew the given token in the given realm.
  • TokenRenewerResponse renewToken(TokenRenewerParameters tokenParameters) - Renew the token using the given parameters
A client can request that the STS renew a security token by invoking the "renew" operation and supplying a token under the "RenewTarget" Element. Assuming that the client request is authenticated and well-formed, the STS will first iterate through a list of TokenValidator implementations to see if they can "handle" the received token. If they can, then the implementation is used to validate the received security token. If no TokenValidator is found that can handle the RenewTarget that was received, then an exception is thrown. Note that this means that for token renewal, it is necessary to configure both a TokenValidator and TokenRenewer implementation that can handle the given token.

After the successful validation of a token, the state of the token is checked. If the state is not valid or expired, then an exception is thrown. The STS then iterates through the configured list of TokenRenewer implementations to see which can renew the given (validated) token. The token is then renewed and returned to the client.

The TokenRenewerParameters class is nothing more than a collection of configuration properties to use in renewing the token, which are populated by the STS operations using information collated from the request, or static configuration, etc. The TokenRenewerResponse class holds the results from the (successful) token renewal, including the DOM representation of the renewed token, the token Id, the new lifetime of the renewed token, and references to the renewed token. 

2) The SAMLTokenRenewer

The SAMLTokenRenewer can renew valid or expired SAML 1.1 and SAML 2.0 tokens. The following properties can be configured on the SAMLTokenRenewer directly:
  • boolean signToken - Whether to sign the renewed token or not. The default is true.
  • ConditionsProvider conditionsProvider - An object used to add a Conditions statement to the token.
  • Map<String, SAMLRealm> realmMap - A map of realms to SAMLRealm objects. See here for an explanation of realms in the SAMLTokenProvider.
  • long maxExpiry - how long a token is allowed to be expired (in seconds) before renewal. The default is 30 minutes.
The SAMLTokenRenewer first checks that the token it extracts from the TokenRenewerParameters is in an expired or valid state, if not it throws an exception. It then retrieves the cached token that corresponds to the token to be renewed. A cache must be configured to use the SAMLTokenRenewer, and the token to be renewed must be in the cache before renewal takes place, for reasons that will become clear in the next section.

2.1) Token validation

Before the received SAML token can be renewed, a number of validation steps (that are specific to renewing SAML tokens) takes place. Two boolean properties are retrieved from the properties of the cached token:
  • org.apache.cxf.sts.token.renewing.allow - Whether the token is allowed to be renewed or not.
  • org.apache.cxf.sts.token.renewing.allow.after.expiry - Whether the token is allowed to be renewed or not after it has expired.
These two properties are set in the SAMLTokenProvider based on a received "<wst:Renewing/>" element when the user is requesting a SAML token via the issue binding. If a user omits a "<wst:Renewing/>" element, or sends "<wst:Renewing/>" or "<wst:Renewing Allow="true"/>", then the token is allowed to be renewed. However, only if the user sends <wst:Renewing OK=True"/>", will the token be allowed to be renewed after expiry. This explains why a TokenStore is required for token renewal, as without access to these two properties it is impossible for the SAMLTokenRenewer to figure out whether the issuer of the token intended for the token to be renewed (after expiry) or not.

If the state of the token is expired, and if the token is allowed to be renewed after expiry, a final check is done against the boolean set via the "setAllowRenewalAfterExpiry" method of TokenRenewer. If this is set to false (the default), then an exception is thrown. So to support token renewal after expiry, you must explicitly define this behaviour on the TokenRenewer implementation. Finally, a check is done on how long ago the SAML Token expired. If it is greater than the value configured in the "maxExpiry" property (30 minutes by default), then an exception is thrown.

The next validation step is to check proof of possession, if this is enabled (true by default). The Subject KeyInfo of the Assertion must contain a PublicKey or X509Certificate that corresponds to either the client certificate if TLS is used, or to the private key that was used to sign some part of the request. Finally, if an "AppliesTo" URI is sent as part of the request, the SAMLTokenRenewer checks that the received Assertion contains at least one AudienceRestrictionURI that matches that address, otherwise it throws an Exception.

2.2) Renewing the SAML Assertion

After the validation steps outlined above have passed, the token is renewed in the following way:
  • A new ID is generated for the token.
  • A new "IssueInstant" is set on the token.
  • A new Conditions Element replaces the old Conditions Element of the token, using the configured ConditionsProvider.
  • The Assertion is (re)-signed if the "signToken" property is true.
The old token is removed from the cache, and the new token is added. Finally, the token is set on the TokenRenewerResponse, along with the token Id, and Lifetime.

3) SAML Token Renewal in action

Finally, let's take a look at a system test in CXF that shows how to renew a SAML Token issued by an STS. The wsdl of the service provider defines a number of endpoints which use the transport binding, with a (endorsing) supporting token requirement which has an IssuedToken policy that requires a SAML token. In other words, the client must request a SAML token from an STS and send it to the service provider over TLS, and optionally use the secret associated with the SAML token to sign the message Timestamp (if an EndorsingSupportingToken policy is specified in the wsdl).

The STS spring configuration is available here. The SAMLTokenRenewer is configured with proof-of-possession enabled, and tokens are allowed to be renewed after they have expired. Let's look at the test code and client configuration. All of the tests follow the same pattern. The client requests a SAML Token from the STS (as per the IssuedToken policy), with a TTL (time-to-live) value of 8 seconds. The client then uses this issued token to make a successful request to the service provider. The test code then sleeps for 8 seconds to expire the token, and tries to invoke on the service provider again. The IssuedTokenInterceptorProvider in the WS-Security runtime in CXF recognises that the token has expired, and sends it to the STS for renewal. The returned (renewed) token is then sent to the service provider.

Wednesday, April 18, 2012

Security Token Caching in Apache CXF 2.6 - part I

This post is the first of a two-part series on how security tokens are cached in Apache CXF 2.6.0, which has just been released. In this particular post I will examine how Apache CXF provides detection against replay attacks on the WS-Security protocol. Apache WSS4J 1.6.5 provides support for detecting and preventing replay attacks.

1) Replay attacks on the WS-Security protocol

A replay attack in this context is when an adversary intercepts a WS-Security enabled message and sends it again to the original intended target of the message. As the message is a direct copy of the original (presumably valid) message, the normal security processing steps should pass without error. Therefore, some additional steps are required on both the initiator and recipient side to protect against these attacks.

2) Message initiator requirements

The initiator should take either or both of the following steps:
  • If the initiator is including a UsernameToken in the message, the initiator should include a nonce in the UsernameToken. A nonce is a random String that can serve as an identifier for the message. The recipient can then cache this value for a certain time period and reject any subsequent message containing this nonce.
  • The initiator should include a Timestamp in the security header of the message. This step alone provides a certain protection against a replay attack if it includes an Expires element, which the recipient should reject if it contains a value prior to the time the message was received at. The Created value of the Timestamp can also serve as the basis of a unique identifier to store in a replay cache.
3) Message recipient requirements

A service provider that uses WS-SecurityPolicy can enforce the message requirements defined above on the client by doing the following:
  • Use a <sp:HashPassword/> OR a <sp13:Nonce/> policy in the UsernameToken policy.
  • Add a <sp:IncludeTimestamp/> to the binding policy.
In addition to this, the recipient must provide a cache to store the UsernameToken nonce values and Timestamp Created values. Note that Timestamp Created values do not provide enough "uniqueness" on their own, as the recipient could receive two valid messages from different clients that were created at the same millisecond in time. Therefore, WSS4J combines the Timestamp Created value with a message Signature value to form a unique identifier. If no message signature is included in the message, then no replay caching is done for Timestamps. However, note that CXF already enforces that a Timestamp must be signed for the Symmetric and Asymmetric WS-SecurityPolicy bindings.

4) Replay caching support in WSS4J

Apache WSS4J 1.6.5 provides support for detecting and preventing replay attacks by introducing the ReplayCache interface. A seperate ReplayCache instance is used to cache UsernameToken nonces and Timestamp Created / Signature Value Strings. WSS4J ships with a sample HashSet based implementation, which is not intended for production use. The default caching time for this implementation is 5 minutes - Timestamps are cached until their expiry time (if it exists), otherwise for 5 minutes.

The ReplayCache implementations to use can be configured via RequestData. No ReplayCache implementation is used by default for backwards compatibility reasons - to enable it you must implement the ReplayCache interface, and set the appropriate methods on RequestData. 

5) Replay caching support in CXF.

Apache CXF 2.6 uses Ehcache to provide a suitable ReplayCache implementation to detect replay attacks. The default cache time for the Ehcache implementation is 60 minutes. No configuration is required for out-of-the-box support for replay attack detection on the message recipient side. Caching is not enabled by default on the inbound initiator side for efficiency reasons. Note that this functionality is available in Apache CXF 2.4.7 and 2.5.3, but is not enabled by default at all for backwards-compatibility reasons. Ehcache is an optional provided dependency for these releases, meaning that you will have to include it as a dependency and enable caching to get replay caching to work. If caching is enabled and Ehcache is not available, then CXF will fall back to using the default HashSet based implementation that ships with WSS4J. Note that this is not intended for production use and will entail performance penalties.

Apache CXF 2.6 provides support for configuring replay caching via the following JAX-WS properties:
  • "ws-security.enable.nonce.cache" - The default value is "true" for message recipients, and "false" for message initiators. Set it to true to cache for both cases.
  • "ws-security.enable.timestamp.cache" - This uses the same logic as above.
  • "ws-security.nonce.cache.instance" - This holds a reference to a ReplayCache instance used to cache UsernameToken nonces. The default instance that is used is the EHCacheReplayCache.
  • "ws-security.timestamp.cache.instance" - This uses the same logic as above.
  • "ws-security.cache.config.file" - Set this property to point to a configuration file for the underlying caching implementation. By default the cxf-ehcache.xml file in the CXF rt-ws-security module is used.

Wednesday, March 21, 2012

UsernameToken Derived Key support in Apache CXF

Support for UsernameToken derived keys has been added to Apache CXF and will be available in the forthcoming 2.4.7 and 2.5.3 releases. UsernameTokens are usually used for authentication, where an initiator places a username and password (plaintext or digested) in the security header of a Soap request. However, it is also possible to exploit the fact that the initiator and recipient share a common secret (the password), by deriving a key from the UsernameToken to perform message level encryption or signature. This functionality provides an alternative to the usual certificate-based approach involved in message level security.

The WS-Security UsernameToken 1.1 profile describes how to derive keys from a UsernameToken. The UsernameToken does not include a password in this case, but includes Username, Salt and (an optional) Iteration elements. The Salt is a 128 bit value, where the high-order 8 bits have the value 01 when it is used for signature, and 02 when used for encryption. This implies that a key derived from a UsernameToken can be used for either signature or encryption, but not both. 

1) Running the UsernameToken derived key system tests in Apache CXF 

The best way to understand how to use this functionality is to take a look at the system tests. To run the UsernameToken derived key system tests in CXF, make sure that the JDK has unlimited security policies installed, and then checkout the CXF trunk via:
svn co https://svn.apache.org/repos/asf/cxf/trunk/
Go into the "trunk" directory, and compile and install CXF via "mvn -Pfastinstall" (this will avoid running tests). Finally go into the WS-Security system tests in "systests/ws-security". The UsernameTokenDerivedTest contains a number of tests that show how to use keys derived from Username Tokens to secure a message exchange. The service and client endpoints are spring-loaded. If you want to see the message exchanges, open src/test/resources/logging.properties, and change the level from WARNING to INFO, and the ConsoleHandler level from SEVERE to INFO. Finally, run the tests via:

        mvn test -Dtest=UsernameTokenDerivedTest

2) WS-SecurityPolicy configuration

The wsdl that defines the service endpoints contains WS-SecurityPolicy expressions that define the security requirements of the endpoints. The following security policies are used for the tests:
  • DoubleItSymmetricProtectionPolicy: This uses a Symmetric binding, where the protection token is a UsernameToken. In other words, a key is derived from the UsernameToken according to the spec, and is used to encrypt or sign the message request.
  • DoubleItSymmetricProtectionDKPolicy: This is the same as above, except that instead of using the UsernameToken derived key directly, another derived key is used instead.
  • DoubleItSymmetricProtectionEncPolicy: This is the same policy as above, except that it is used for encryption and not signature. It does not include a Timestamp requirement, as this would require that the Timestamp be signed.
  • DoubleItTransportEndorsingPolicy: This uses a Transport binding, where a UsernameToken is included as an EndorsingSupportingToken. In other words, the key derived from the UsernameToken is used to sign the Timestamp.
  • DoubleItSymmetricSignedEndorsingPolicy: This uses a Symmetric binding, where a UsernameToken is included as a SignedEndorsingSupportingToken. 
  • DoubleItSymmetricEndorsingEncryptedPolicy: This uses a Symmetric binding, where a UsernameToken is included as a EndorsingEncryptedSupportingToken.
  • DoubleItSymmetricSignedEndorsingEncryptedPolicy: This uses a Symmetric binding, where a UsernameToken is included as a SignedEndorsingEncryptedSupportingToken. 
UsernameToken derived keys are not currently supported with the Asymmetric binding.

Monday, March 5, 2012

Apache WSS4J 1.6.5 released

Apache WSS4J 1.6.5 has been released. The list of issues that were fixed in this release is available here. This is quite a significant release as it contains an upgrade to use Apache Santuario (XML Security for Java) 1.5. This release is intended to be the last major development release on the 1.6.x branch. There are exciting plans for WSS4J 2.0 which I will describe shortly. Here is a summary of some of the main features of this release: 

1) Apache Santuario (XML Security for Java) 1.5.1 upgrade

WSS4J has upgraded the Santuario dependency from 1.4.6 to 1.5.1 and hence picks up the following relevant new features:
  • Support for GCM algorithms has been added via a third-party JCE provider (e.g. BouncyCastle). I will describe this in more detail in a future blog post.
  • Support for Key Transport Algorithms with strong digests is available.
  • More secure validation of incoming signed requests is performed.
  • Better protection against signature wrapping attacks is available.
For more information on the new features associated with Santuario 1.5.0 see here. WSS4J picks up Santuario 1.5.1 which fixes a number of important issues in the 1.5.0 release. 

2) Improvements in validating SAML Assertions

WSS4J contains the following improvements related to validating SAML Assertions:
  • Validation of SAML Condition NotBefore/NotOnOrAfter dates.
  • Validate the received Assertion against the schema/specs.
A bug has also been fixed when creating a SAML Token where the NotOnOrAfter Condition is not set correctly in some cases.  

3) Improvements relating to certificate revocation

There are a number of fixes relating to certificate revocation:
  • Revocation is not performed if the certificate is contained in the keystore.
  • Revocation is now supported before encryption on the sending side.

Friday, March 2, 2012

Apache Santuario (XML Security for Java) 1.5.1 released

Apache Santuario (XML Security for Java) 1.5.1 has been released and is available for download. The release notes are available here. This release fixes two important bugs - a bug in XMLSignatureInput when using a BufferedInputStream, as well as a bug which caused 1.5.0 to continue to require Xalan. It also contains some performance improvements for encryption and decryption.

Wednesday, February 22, 2012

WS-Trust SPNego support in Apache CXF

Support for SPNego using WS-Trust has been added to Apache CXF and will be available in the forthcoming 2.4.7 and 2.5.3 releases. This new functionality allows a CXF client to integrate with WCF 4.0, as WCF 4.0 uses message level NTLM/Kerberos based on SPNego using WS-Trust. See the following blog for an in-depth explanation of how to do exactly this. Support for obtaining and validating SPNEGO tokens was added to Apache WSS4J in the 1.6.4 release. WSS4J 1.6.5 will feature support for making the Spnego Client and Service Action classes pluggable, so that the user can specify a custom means of obtaining the ticket.

Using WS-Trust for SPNego is described in the following application note. The client contacts a KDC and obtains a SP Negotiation token, which it sends to the service provider via WS-Trust. If the negotiation is incomplete, the service provider can respond to the client to continue the negotiation. Once the negotiation is complete, a WS-Trust RequestedProofToken is created which contains a secret key that has been encrypted with the negotiated key, and this is returned to the client along with an Authenticator and a SecurityContextToken. The client can decrypt the EncryptedKey, and use this key with a symmetric encryption or signature algorithm to secure a request.

Note that the focus is on making sure that a CXF client can interoperate with WCF, and hence the STS support for SPNego is only intended as a means of testing the client code. In particular, the STS does not return an Authenticator, which is required by the spec. One additional limitation is that the STS client does not currently support continued negotation.

1) Running the WS-Trust SPNego system tests in Apache CXF 

To run the WS-Trust SPNego system tests in CXF, it is first necessary to set up a KDC correctly. Follow the instructions given in section 1 in a previous blog post which describes how to run the Kerberos system tests in CXF. Next, make sure that the JDK has unlimited security policies installed, and then checkout the CXF trunk via:
svn co https://svn.apache.org/repos/asf/cxf/trunk/
Go into the "trunk" directory, and compile and install CXF via "mvn -Pfastinstall" (this will avoid running tests). Finally go into the WS-Security system tests in "systests/ws-security". The SpnegoTokenTest contains two tests, which are @Ignore'd by default. Open SpnegoTokenTest.java and comment out the "@org.junit.Ignore" entries for both tests. If you want to see the message exchanges, open src/test/resources/logging.properties, and change the level from WARNING to INFO, and the ConsoleHandler level from SEVERE to INFO. Finally, run the tests via:

        mvn test -Dtest=SpnegoTokenTest -Djava.security.auth.login.config=src/test/resources/kerberos.jaas

1.1) WS-SecurityPolicy configuration

The wsdl that defines the service endpoints contains WS-SecurityPolicy expressions that define the security requirements of the endpoints. The following security policies are used for the tests:
  • DoubleItSpnegoSymmetricProtectionPolicy: This uses a Symmetric binding, where the protection token is a SpnegoContextToken.
  • DoubleItSpnegoSymmetricProtectionDerivedPolicy: This uses a Symmetric binding, where the protection token is key derived from a SpnegoContextToken.
1.2) Kerberos LoginModule configuration

Both the CXF client and service endpoint use JAAS to authenticate to the KDC. The JAAS file used as part of the system test is passed to the tests via the System property "java.security.auth.login.config". The client (alice) uses the following login module:
alice {
    com.sun.security.auth.module.Krb5LoginModule required
    refreshKrb5Config=true useKeyTab=true keyTab="/etc/alice.keytab"
    principal="alice";
};
and the service endpoint (bob) uses:
bob {
    com.sun.security.auth.module.Krb5LoginModule required
    refreshKrb5Config=true useKeyTab=true storeKey=true
    keyTab="/etc/bob.keytab" principal="bob/service.ws.apache.org";
};
1.3) Client and Service endpoint configuration

Both the service and client endpoints are spring-loaded. The contain the following JAX-WS properties, which are defined in SecurityConstants:
  •  "ws-security.kerberos.jaas.context" - This refers to the JAAS context given in the configuration file above. The clients use a value of "alice", and the service endpoints use "bob".
  • "ws-security.kerberos.spn"- This is only configured on the client side, and specifies the Kerberos Service Provider Name ("bob@service.ws.apache.org").
Finally, there is one additional JAX-WS property that can be defined on the client, if you want to plug in a custom WSS4J SpnegoClientAction implementation:
  • "ws-security.spnego.client.action" - The SpnegoClientAction implementation to use for SPNEGO. This allows the user to plug in a different implementation to obtain a service ticket. See here for more details on how to use this property.

Tuesday, January 24, 2012

Apache Santuario (XML Security for Java) 1.5.0 released

Apache Santuario (XML Security for Java) 1.5.0 has been released. It can be downloaded here. Please read the release notes (collated from my previous blog entries) if you are planning to upgrade.

Friday, January 13, 2012

Apache Santuario (XML Security for Java) 1.5.0 RC2

I posted a RC1 for Apache Santuario (XML Security for Java) almost a month ago now. Since then, a large number of changes have been made to address some inconsistencies in RC1 as well to add some new functionality. The RC2 release is available here. Please download it and post any issues that are found to the mailing list. The changes compared to the RC1 release (documented here) are as follows:

1) Support for RSA-OAEP key transport algorithms with strong digests

The 1.4.x releases only support using SHA-1 with the RSA-OAEP key transport algorithm for encryption and decryption. The 1.5.0 RC2 release supports stronger digests using the ds:DigestMethod child of xenc:EncrytionMethod. In addition, it fully supports the xenc11:MGF Algorithm as documented in the XML Encryption 1.1 specification.

To test this functionality, all of the XML Encryption 1.1 Key Wrapping test-cases have been implemented, both for encryption and decryption. These tests also serve to better test the support for GCM algorithms in the 1.5.0 release. Support for 192 bit AES-GCM was added as part of this work. 

2) Major changes to how Elements are resolved

The release notes for RC1 described how the IdResolver no longer searches the current Document for an Element matching the requested Id in certain "known" namespaces, and instead how it was the responsibility of the user to register Elements by Id in the IdResolver (or via setIdAttributeNS if using the JSR-105 API), if they are required as part of the signature validation process.

In RC2, the static cache of Id->Elements that was maintained in the IdResolver has been removed. Instead, the ResourceResolver implementations that are responsible for resolving same-Document URI references resolve Elements by querying Document.getElementById(). The IdResolver has been deprecated, so that it is no longer possible to register an Element by Id, and the "get" methods simply delegate to the DOM call above.

So what does this mean for the user? The user is now responsible for registering any same-Document Elements by Id, which must be resolved as part of the signature creation/validation process. This can be done in two ways:
  1. Using the DOM APIs: Element.setIdAttribute*
  2. Using the JSR-105 API: DOMCryptoContext.setIdAttributeNS
3) Better protection against Signature Wrapping Attacks

A Signature Wrapping attack can occur when a malicious entity duplicates some signed Element in a document, and then modifies the content of the duplicated Element, but keeps the same Id. If the signature validation process only finds the initial Element, then signature validation will pass, and the user might be fooled into thinking that the modified Element has been signed, as it has the same Id as the original validated Element.

The implication of this attack is that it is vital that the user checks that the Elements that were signed correspond to the Elements that he/she expects to be signed. In other words, the Elements that were signed should be located in a specific "known" place in the Document. The best way of facilitating this check is to make sure that the signature validation process returns the Elements that it validated. The JSR-105 API supports this via the "javax.xml.crypto.dsig.cacheReference" boolean property, that can be set on the context.

However, the older XMLSignature, which pre-dates the JSR-105 API, did not include this functionality. This has been fixed in the RC2 release, e.g.:

XMLSignature signature = ...
// Perform validation and then...
SignedInfo signedInfo = signature.getSignedInfo();
for (int i = 0; i < signedInfo.getLength(); i++) {
    Reference reference = signedInfo.item(i);
    ReferenceData refData = reference.getReferenceData();
    ....
}

ReferenceData is a new interface that duplicates the way the JSR-105 API returns references. Three different implementations have been provided depending on whether the dereferenced Element is a NodeSet, Element or OctetStream.

Finally, some new functionality has been added when secure validation is enabled, to ensure that when an Element is de-referenced via Document.getElementById() (as described above), no other Element in the tree has an Attribute that is also registered as an Id with the same value. This is done via a tree search, and guarantees that the Element retrieved via the getElementById call is unique in the Document (something that is not guaranteed by the contract of getElementById). However note that another Element could still exist in the tree with a matching Id in another namespace.