Wednesday, August 26, 2009

[ERROR] Referenced security token could not be retrieved (Reference "#CertId-238146")

Exception :

[WARN] Multiple elements with the same 'Id' attribute value!
[ERROR] Referenced security token could not be retrieved (Reference "#CertId-23
146")
org.apache.axis2.AxisFault: Referenced security token could not be retrieved (R
ference "#CertId-238146")
at org.apache.rampart.handler.RampartReceiver.setFaultCodeAndThrowAxisF
ult(RampartReceiver.java:166)
at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.ja
a:95)
at org.apache.axis2.engine.Phase.invoke(Phase.java:317)
at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:264)
Root Cause :
This can be due to many reasons - in the request where multiple elements having the same id.

One scenario this happens is when you have security policy like following - with Rampart 1.4.

<sp:SupportingTokens
xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:X509Token
sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/Always">
<wsp:Policy>
<sp:RequireThumbprintReference />
<sp:WssX509V3Token10 />
</wsp:Policy>
</sp:X509Token>
</wsp:Policy>
</sp:SupportingTokens>
In this case Rampart 1.4 includes multiple BinarySecurityToken(s) with duplicate wsu:Id.

Solution :
Rampart 1.4 inherits the issue from wss4j-1.5.4.jar - replacing it with wss4j-1.5.8.jar will fix this.

Tuesday, August 25, 2009

java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/NONE/OAEPPADDING

Exception :

java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/NONE/OAEPPADDING
at javax.crypto.Cipher.getInstance(DashoA12275)
at org.apache.ws.security.util.WSSecurityUtil.getCipherInstance(WSSecurityUtil.java:703)
at org.apache.ws.security.processor.EncryptedKeyProcessor.handleEncryptedKey(EncryptedKeyProcessor.java:145)
at org.apache.ws.security.processor.EncryptedKeyProcessor.handleEncryptedKey(EncryptedKeyProcessor.java:114)
Root Cause :
Bouncycastle jar may still in the classpath - but it's not picked as a crypto provider.

Solution 1:
Download the Bouncycastle jar corresponding to your JDK from here and copy it to [JAVA_HOME]\jre\lib\ext\

Set following in [JAVA_HOME]\jre\lib\security\java.security under;

#
# List of providers and their preference orders (see above):
#

security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider

Solution 2:
In code add Bouncycastle as a provider.


import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

Security.addProvider(new BouncyCastleProvider());
Related :
org.apache.ws.security.WSSecurityException: An unsupported signature or encryption algorithm was used

org.apache.ws.security.WSSecurityException: An unsupported signature or encryption algorithm was used

Exception :

[java] Caused by: org.apache.ws.security.WSSecurityException:
An unsupported signature or encryption algorithm was used (unsupported key transport encryption algorithm:
No such algorithm: http://ww.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p)
[java] at org.apache.ws.security.util.WSSecurityUtil.getCipherInstance(WSSecurityUtil.java:689)
[java] at org.apache.ws.security.message.WSSecEncryptedKey.prepareInternal(WSSecEncryptedKey.java:195)
[java] at org.apache.ws.security.message.WSSecEncrypt.prepare(WSSecEncrypt.java:260)
[java] at org.apache.rampart.builder.AsymmetricBindingBuilder.doSignBeforeEncrypt(AsymmetricBindingBuilder.java:510)
Root Cause :
Bouncycastle jar not found in the classpath.

Solution :
Download the Bouncycastle jar corresponding to your JDK from here and add it to the classpath.

How to add a secured and a non secured end point to the same service?

Here we want to let requests having no security headers to come to our service, and we handle it at the application logic by sending a customized response.

If Rampart supports policy alternatives then this can be done easily. But Rampart does not.

Anyway - there is way we could still do it - by applying different policies to different bindings.

1.Add two different policies to the WSDL. For non-secured end point we use an empty policy as shown below.

<wsp:Policy
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
wsu:Id="NonSecure">
<wsp:ExactlyOne>
<wsp:All />
</wsp:ExactlyOne>
</wsp:Policy>
2. Hand edit the WSDL and add a new binding element - which references the #NonSecure policy.

<wsdl:binding name="echoSoap12BindingNonsecured" type="ns:echoPortType">
<wsp:PolicyReference URI="#NonSecure" />
....
</wsdl:binding>
3. Hand edit the WSDL and add a new wsdl:port element - which references echoSoap12BindingNonsecured.

<wsdl:port name="echoHttpSoap12EndpointNonSecured" binding="ns:echoSoap12BindingNonsecured">
<soap12:address location="http://localhost:8080/axis2/services/echo.echoHttpSoap12EndpointNonSecured/" />
</wsdl:port>
4. You can find the modified wsdl from here.

5.Now edit your services.xml with appropriate wsp:PolicyAttachment(s).

6.Modify the services.xml to useOrignalWSDL.

7.You can find the complete services.xml from here.

8.To invoke the secured end point use the EPR http://localhost:8080/axis2/services/echo.echoHttpSoap12Endpoint

9.To invoke the non-secured end point use the EPR http://localhost:8080/axis2/services/echo.echoHttpSoap12EndpointNonSecured

If you are not handling this type of a scenario properly at the application logic - then this is not a recommended approach.

Monday, August 24, 2009

How to run Rampart samples with Apache Tomcat?

Ruchith explains here how to setup and run standard Apache Rampart samples in an Axis2 instance hosted in Apache Rampart.

How to configure Rampart in Axis2?

1.Download Axis2 distribution and extract locally.

2.Download Rampart distribution and extract locally.

3.Copy all the jars from [RAMPART_HOME]\lib to [AXIS2_HOME]\lib

4.Copy rahas.mar and rampart.mar files from [RAMPART_HOME]\modules to [AXIS2_HOME]\repository\modules

5. Now - engage rampart/rahas modules globally or at the service level. To engage globally use axis2.xml - at the service level use services.xml of the corresponding service.
<module ref="rampart" />
<module ref="rahas" />

How Token referencing works in WS-Security?

Token referencing means how one token finds the other.

For example digital signature and encryption operations require that a key be specified. For various reasons,the element containing the key in question may be located elsewhere in the message or completely outside the message.

Let's first see an example where the key in question located inside the element it self.

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
MIICPjCCAacCBEngcUswDQYJKoZIhvcNAQEEBQAwZjELMAkGA1UEBhMCTEsxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1NlYXR0bGUxDTALBgNVBAoTBFdTTzIxDTALBgNVBAsTBE5vbmUxEjA
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
If you take the KeyInfo element out from the above example you'll see - the public key corresponding to the Signature being included inside the Signature element it self.

Let's take another example.

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyInfo>
<wsse:SecurityTokenReference
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:KeyIdentifier
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1">
NC+OYE+VLHQQCmJL3DVRkUyxrr0=
</wsse:KeyIdentifier>
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
Have a look at wsse:SecurityTokenReference element.

Here it contains the thumbprint [http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1] value of the certificate being used to sign.

In this case - to validate the signature, you need to have the correponding certificate in your key store, at the receipient end.

The wsse:SecurityTokenReference element provides an open content model for referencing key bearing elements because not all of them support a common reference pattern. Similarly, some have closed schemas and define their own reference mechanisms. The open content model allows appropriate reference mechanisms to be used.

If a wsse:SecurityTokenReference is used outside of the security header processing block the meaning of the response and/or processing rules of the resulting references MUST be specified by the the specific profile.

Let's take another example.

<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyInfo>
<wsse:SecurityTokenReference
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Reference
URI="#CertId-33F15B961A92D5966C12511059451031"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
Here, have a look at wsse:Reference and it's attribute URI. Also notice that the value of URI starts with a '#' - that means, this refers to a token that should be found within the message it self.

In other words - the message should have an element with the wsu:Id CertId-33F15B961A92D5966C12511059451031 [ommiting #].

In our case - the token reffered is included in the message it self as a BinarySecurityToken.

<wsse:BinarySecurityToken
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"
wsu:Id="CertId-33F15B961A92D5966C12511059451031">
MIIC0TCCAbkCBEp6Up4wDQYJKoZIhvcNAQEEBQAwLTELMAkGAUEBhMCTEsxDTALBgNVBAsMBHdzbzIxDzANBgNVBAMMBmNsaWVudDAeFw0wOTA4MDYwMzQ4NDZaFw0xMjA4MDUwMzQ4NDZaMC0xCzAJBgNVBAYTAkxLMQ0wCwYDVQQLDAR3c28yMQ8wDQYDVQQDDAZjbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCAMXusC<wsse:BinarySecurityToken>
Let's get in to theory a bit.

The following list provides a list of the specific reference mechanisms defined in WSS: SOAP Message Security in preferred order (i.e., most specific to least specific):

• Direct References – This allows references to included tokens using URI fragments and external tokens using full URIs.
• Key Identifiers – This allows tokens to be referenced using an opaque value that represents the token (defined by token type/profile).
• Key Names – This allows tokens to be referenced using a string that matches an identity assertion within the security token. This is a subset match and may result in multiple security tokens that match the specified name.
• Embedded References - This allows tokens to be embedded (as opposed to a pointer to a token that resides elsewhere).

In the samples provided before; the second example is for "Key Identifiers" and the third is for "Direct References".

Now, let's see an example of Embedded References.

<wsse:SecurityTokenReference>
<wsse:Embedded wsu:Id="tok1">
<saml:Assertion xmlns:saml="...">
...
<saml:Assertion>
</wsse:Embedded>
</wsse:SecurityTokenReference>
Following is an example of Key Names.

<ds:KeyInfo Id="..." xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:KeyName>CN=Hiroshi Maruyama, C=JP</ds:KeyName>
</ds:KeyInfo>
It is strongly RECOMMENDED to use wsse:KeyIdentifier elements. However, if Key Names are used, then it is strongly RECOMMENDED that ds:KeyName elements conform to the attribute names in section 2.3 of RFC 2253 (this is recommended by XML Signature for ds:X509SubjectName, for interoperability.

Sunday, August 23, 2009

What are policy subjects and where goes security policy assertions?

The entities with which policies are associated are called policy subjects.

For example, you can associate a policy with an endpoint, in which case the endpoint is the policy subject. It is possible to associate multiple policies with any given policy subject. The WS-Policy framework supports the following kinds of policy subject.

•Service policy subject.

•Endpoint policy subject.

•Operation policy subject.

•Message policy subject.

Service policy subject
Associates a policy with a service, insert either a element or a element as a sub-element of the following WSDL 1.1 element(s):

wsdl:service — apply the policy to all of the ports (endpoints) offered by this service.

Endpoint policy subject
Associates a policy with an endpoint, insert either a element or a element as a sub-element of any of the following WSDL 1.1 elements:

wsdl:portType — apply the policy to all of the ports (endpoints) that use this port type.

wsdl:binding — apply the policy to all of the ports that use this binding.

wsdl:port — apply the policy to this endpoint only.

wsdl:service can have multiple wsdl:port(s) and a given wsdl:port has reference to a single wsdl:binding, while wsdl:binding has reference to a wsdl:portType.

Operation policy subject
Associate a policy with an operation, insert either a element or a element as a sub-element of any of the following WSDL 1.1 elements:

wsdl:portType/wsdl:operation

•wsdl:binding/wsdl:operation

Message policy subject
Associate a policy with a message, insert either a element or a element as a sub-element of any of the following WSDL 1.1 elements:

wsdl:message

wsdl:portType/wsdl:operation/wsdl:input

wsdl:portType/wsdl:operation/wsdl:output

wsdl:portType/wsdl:operation/wsdl:fault

wsdl:binding/wsdl:operation/wsdl:input

wsdl:binding/wsdl:operation/wsdl:output

wsdl:binding/wsdl:operation/wsdl:fault

Following are the policy assertions and their corresponding policy subjects as per the WS-Security Policy.

Endpoint Policy Subject Assertions

1) Security Binding Assertions
TransportBinding Assertion
SymmetricBinding Assertion
AsymmetricBinding Assertion

2) Token Assertions
SupportingTokens Assertion
SignedSupportingTokens Assertion
EndorsingSupportingTokens Assertion
SignedEndorsingSupportingTokens Assertion

3) WSS: SOAP Message Security 1.0 Assertions
Wss10 Assertion

4) WSS: SOAP Message Security 1.1 Assertions
Wss11 Assertion

5) Trust 1.0 Assertions
Trust10 Assertion

Operation Policy Subject Assertions

1) Supporting Token Assertions
SupportingTokens Assertion
SignedSupportingTokens Assertion
EndorsingSupportingTokens Assertion
SignedEndorsingSupportingTokens Assertion

Message Policy Subject Assertions

1) Supporting Token Assertions
SupportingTokens Assertion
SignedSupportingTokens Assertion
EndorsingSupportingTokens Assertion
SignedEndorsingSupportingTokens Assertion

2) Protection Assertions
SignedParts Assertion
SignedElements Assertion
EncryptedParts Assertion
EncryptedElements Assertion
RequiredElements Assertion

How password Callback Handlers work in Rampart?

In this article Nandana nicely explains the usage of password callback handlers in Rampart.

How to do proxy authenticaion at runtime - in Axis2 client or stub?


HttpTransportProperties.ProxyProperties proxyProperties = new HttpTransportProperties().new ProxyProperties();
proxyProperties.setProxyHostName("axis2");
proxyProperties.setProxyPort(9762);
proxyproperties.setDomain("axis2/anon");
proxyproperties.setPassWord("passwd");
proxyproperties.setUserName("usernm");
//in order to makesure that we use HTTP 1.0
options.setProperty(MessageContextConstants.HTTP_PROTOCOL_VERSION,HTTPConstants.HEADER_PROTOCOL_10);
options.setProperty(org.apache.axis2.transport.http.HTTPConstants.PROXY,proxyProperties);

Saturday, August 22, 2009

What are the Rampart handlers in inflow and what do they do?

org.apache.rampart.handler.RampartReceiver

1. The first point of impact with the Axis2 Security layer

2. Validates the transports - that is if policy requires TransportBinding with HTTPS - then incoming transport should be on HTTPS, also if TransportBinding requires client auth - then the initiator should present a X.509 certificate with the request.

3. If no security header present in the request - this will throw a RampartException for missing security header.

4. Processes the security header

5. Elements inside security header are processed according to the order they found in side the request - or the security header.

6. Each element defined under security header will have a processor [org.apache.ws.security.processor.Processor] associate with it corresponding to the token type.

7. Processing of the entire security header builds up a Vector. Each element in the Vector represents the result of a security action. The elements are ordered according to the sequence of the security actions in the wsse:Signature header. The Vector may be empty if no security processing was performed.

8. Now - validates the incoming message against the defined security policy.[You may also check this out...]

9. Marks the security header block as processed.

org.apache.rampart.handler.WSDoAllReceiver

1. There are two ways Rampart supports security processing - one is policy based security processing as per WS-Security Policy, the other is parameter based security processing.

2. Parameter based security processing is deprecated in Rampart, hence the WSDoAllReceiver handler which supports parameter based security processing is also deprecated.

org.apache.rampart.handler.PostDispatchVerificationHandler

1. Handler to verify the message security after dispatch.

2. Checks whether security is required and it's being processed.

How does the nonce and the timestamp get generated for hashed passwords in UsernameToken?

We need not to worry about the digest calculation in our application code - we simply need to set the password type to #PasswordDigest [or set the policy correctly as explained here] and supply the password in clear text from the password callback handler.

Inside wss4j code; will take the password in clear text and do the digest verification.

How to ask for a hashed password in security policy?

Under WS-Security Policy we can specify the requirement for a UsernameToken as following.

<sp:SupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient"/>
</wsp:Policy>
</sp:SupportingTokens>
In this case UsernameToken will be included in the request [SOAP message] as below.

<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-2">
<wsse:Username>alice</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bobPW</wsse:Password>
</wsse:UsernameToken>
Here the password will be included in clear text. But if we want the password to be included as a digest value[...#PasswordDigest]then the security policy should look like...

<sp:SupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsp:Policy>
<sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:HashPassword/>
</wsp:Policy>
</sp:UsernameToken>
</wsp:Policy>
</sp:SupportingTokens>

Friday, August 21, 2009

How identity delegation works with ActAs in WS-Trust 1.4?

In this post, I explain about the "ActAs" element which is a new addition to the WS-Trust specification since its version 1.4.

How to enable NTLM authentication in Axis2 client?


HttpTransportProperties.NTLMAuthentication ntlmAuthentication = new HttpTransportProperties().new NTLMAuthentication();
ntlmAuthentication.setUsername("axis2");
ntlmAuthentication.setPassword("axis2");
ntlmAuthentication.setHost("axis2");
ntlmAuthentication.setPort(9443);
ntlmAuthentication.setRealm("someRealm");
options.setProperty(org.apache.axis2.transport.http.HTTPConstants.NTLM_AUTHENTICATION,ntlmAuthentication);

Thursday, August 20, 2009

How SOAP message encryption works?

In this post, I am explaining how the SOAP message encryption works as defined in the WS Security Specification.

Wednesday, August 19, 2009

What is Assymetric Binding?

In this blog post, Thilina explains the Assymetric Binding defined in WS Security Policy Specification and also provides a working example with Axis2/Rampart.

Can we avoid duplicating crypto info added to RampartConfig in different services.xml files?

When we have Signature and/or Encryption in a security policy - we need to add following crypto info into the RampartConfig.

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>service</ramp:user>
<ramp:encryptionUser>client</ramp:encryptionUser>
<ramp:passwordCallbackClass>sample03.PWCBHandler</ramp:passwordCallbackClass>
<ramp:signatureCrypto>
<ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type">JKS</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.file">service.jks</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">apache</ramp:property>
</ramp:crypto>
</ramp:signatureCrypto>
<ramp:encryptionCypto>
<ramp:crypto provider="org.apache.ws.security.components.crypto.Merlin">
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.type">JKS</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.file">service.jks</ramp:property>
<ramp:property name="org.apache.ws.security.crypto.merlin.keystore.password">apache</ramp:property>
</ramp:crypto>
</ramp:encryptionCypto>
</ramp:RampartConfig>
In most of the cases above settings are static for more than one service.

In such a case - you can avoid adding this configuration to each and every service.

Step - 1
Implement the interface org.apache.rampart.RampartConfigCallbackHandler

Step - 2
In the RampartConfigCallbackHandler implementation update the RampartConfig instance passed into the method update() programmetically.

Step - 3
Add following to the service policy of all the corresponding services.

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:rampartConfigCallbackClass>RampartConfigCallbackHandlerImpl
</ramp:RampartConfig>

How to apply policies at binding hierarchy?

In this article Nandana explains how to apply policies at binding hierarchy.

Can we have per service, policy based results validators?

Yes... you can.

You need to implement org.apache.rampart.PolicyValidatorCallbackHandler interface and add the following configuration to your service policy - RampartConfig.

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
  <ramp:policyValidatorCbClass>my.CustomPolicyValidator</ramp:policyValidatorCbClass>
</ramp:RampartConfig>
This PolicyValidatorCallbackHandler interface allows different implementations of policy based results validation. Default implementation is org.apache.rampart.PolicyBasedResultsValidator.

It's always recommended that you use the default PolicyBasedResultsValidator - if you do not have a very specific custom requirement.

Would timestamp validation fail when servers and clients running in different timezones?

No. WSS4J keeps the time as UTC - so different timezones shouldn't matter.

Even in different timezones - if you have the correct time corresponding to that time zone - then it should be fine.

For example :

Time Zone A [GMT + 8] : Correct Time Now : 4.00 AM

Time Zone B [GMT + 11] : Correct Time Now : 7.00 AM

Then it should work with no issues.

But in the same case if you have the time, incorrectly, in Time Zone A as 5.00 AM [ in a case where it should be ideally 4 .00 AM] - then timestamp validation will fail.

So - timezone wouldn't be an issue if we still have the correct time in each case corresponding to the timezone - it belongs to.

Tuesday, August 18, 2009

How to secure a web service with UsernameToken + HTTPS?

In this blog post Thilina nicely explains how to secure a given web service with UsernameToken.

org.apache.rampart.RampartException: The timestamp could not be validated

Exception :
Caused by: org.apache.rampart.RampartException: The timestamp could not be validated
at org.apache.rampart.PolicyBasedResultsValidator.validat(PolicyBasedResultsValidator.java:188)
at org.apache.rampart.RampartEngine.process(RampartEngine.java:214)
at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.java:92)
Root Cause :
This could be either due to the server clock not in sync with the client clock or the transmission delay goes beyond the accepted TTL.

Solution :
Add the following to the RampartConfig in the policy file appropriately.

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
  <ramp:timestampTTL>600</ramp:timestampTTL>
  <ramp:timestampMaxSkew>600</ramp:timestampMaxSkew>
<ramp:RampartConfig>

The value must be the time skew /ttl in seconds and must be specified as an integer. By default Apache Rampart/Java tolarates a maximum time skew / ttl of five (5) minutes (300 seconds).

Explanation :
For the timestamp to be validated;

created timestamp <= now + maxSkew * 1000;
created timestamp >= now - ttl* 1000;

How to create wildcard certificates with java keytool?

Wildcard SSL Certificates let you secure an unlimited number of sub-domains under a single domain name.

This explains how to do it with java keytool.

How to enable SSL on WAMP?

This step by step guide explains how you can enble SSL on WAMP.

How to dump out JKS private key?

This post explains how you could programmatically access a java key store and dump its private key out.

How to ceate a new JKS with an existing private key and a signed certificate?

You have your own private key and a CA signed certificate - and now you want to import both the key and the certificate to a new JKS.

In this blog post I explain how to do it from scratch.

How to create a Certificate Authority with OpenSSL on Windows?

This post explains all the steps you need to create your own CA with OpenSSL.

How to secure web services with HTTP Basic Authentication?

This post explains how you could secure your web service with HTTP Basic Authentication.

How to enable SSL on Tomcat?

This post explains how you can enable SSL on Tomcat.

How to setup a secure conversation with an STS?

In this blog post, I explain steps required in setting up a Secure Conversation between a client and a service with the aid of an STS[Secure Token Service].

How to do UsernameToken authentication for web services based on AD?

in this post, I explain how you can authenticate users at the service end against an Active Directory[AD] - in the CallbackHandler.

How to secure a web service with UsernameToken?

In this bolg post, I explain security policy basics with an example in Rampart.

There the service expects clients to authenticate themselves with username/password credentials.

Can we have multiple private keys in a single JKS?

Yes - we can have any number of private/public key pairs in a given keystore.

We can use KeyTool IUI to get this done - which is available here for free download.

How to import/export certificates using Java keytool?

\>keytool -import -alias localhost -keystore wso2carbon.jks -file mycert.cer

The above will import the certificate mycert.cer to the keystore wso2carbon.jks - and will be stored with the alias localhost

\>keytool -export -alias localhost -keystore wso2carbon.jks -file mycert.cer

The above will export the certificate having the alias 'localhost' from the keystore wso2carbon.jks - to mycert.cer

How to call web services having SSL mutual authentication enabled?

First - your client needs to trust the service's certificate.

So - import the CA cert who signed service's certificate, to your trust store at the client side.

Then you need to set following in your client code;

System.setProperty("javax.net.ssl.trustStore", "truststore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "wso2carbon");
System.setProperty("javax.net.ssl.keyStore", "keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "wso2carbon");

keystore.jks will have your public certificate.

Or else, you can pass these parameters in command line as well;

\> client -Djavax.net.ssl.trustStore=truststore.jks
-Djavax.net.ssl.trustStorePassword=wso2carbon
-Djavax.net.ssl.trustStoreType=JKS
-Djavax.net.ssl.keyStore=keystore.jks
-Djavax.net.ssl.keyStorePassword=wso2carbon

<ramp:user> vs <ramp:encryptionUser> vs <ramp:userCertAlias>

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy">
<ramp:user>service</ramp:user>
<ramp:encryptionUser>client</ramp:encryptionUser>
<ramp:userCertAlias>client</ramp:userCertAlias>
</ramp:RampartConfig>


<ramp:user>

This is the user name used to retrieve the password from the CallbackHandler when UsernameToken security policy being configured.

<ramp:userCertAlias>

This is the key alias used to retrive the password of the corresponding private key from the CallbackHandler.

In the absence of this, <ramp:user> is used for the same purpose.

<ramp:encryptionUser>

This is the key alias of the public key used to encrypt the message.

java.security.UnrecoverableKeyException: Cannot recover key

Exception :
Caused by: java.security.UnrecoverableKeyException: Cannot recover key
at sun.security.provider.KeyProtector.recover(Unknown Source)
at sun.security.provider.JavaKeyStore.engineGetKey(Unknown Source)
at sun.security.provider.JavaKeyStore$JKS.engineGetKey(Unknown Source)
at java.security.KeyStore.getKey(Unknown Source)
at org.apache.ws.security.components.crypto.CryptoBase.getPrivateKey(CryptoBase.java:216)
at org.apache.ws.security.message.WSSecSignature.computeSignature(WSSecSignature.java:713)... 14 more
Root Cause :
Incorrect password provided from the CallbackHandler for the private key.

Solution :
Correctthe password provided from the CallbackHandler for the private key.

org.apache.axis2.AxisFault: First Element must contain the local name, Envelope , but found html

Exception :
org.apache.axis2.AxisFault: First Element must contain the local name, Envelope , but found html 
at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:90)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:353)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:416)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)
at org.apache.axis2.client.ServiceClient.sendReceive(ServiceClient.java:548)
Root Cause :
Service epr is incorrect. Basically the call is returning a HTML page instead of a SOAP document.

Solution :
Correct the service epr.

org.apache.axis2.phaseresolver.PhaseException: Did not find the desired phase 'Security' while deploying handler 'PolicyBasedSecurityOutHandler'

Exception :
org.apache.axis2.phaseresolver.PhaseException: Did not find the desired phase 'Security' while deploying handler 'PolicyBasedSecurityOutHandler'. 
at org.apache.axis2.phaseresolver.PhaseHolder.addHandler(PhaseHolder.java:75)
at org.apache.axis2.phaseresolver.PhaseResolver.engageModuleToFlow(PhaseResolver.java:68)
at org.apache.axis2.phaseresolver.PhaseResolver.engageModuleToOperation(PhaseResolver.java:104) at org.apache.axis2.phaseresolver.PhaseResolver.engageModuleToOperation(PhaseResolver.java:110)
at org.apache.axis2.description.AxisOperation.onEngage(AxisOperation.java:158)
at org.apache.axis2.description.AxisDescription.engageModule(AxisDescription.java:490) at org.apache.axis2.description.AxisService.onEngage(AxisService.java:788)
at org.apache.axis2.description.AxisDescription.engageModule(AxisDescription.java:490) at org.apache.axis2.description.AxisServiceGroup.onEngage(AxisServiceGroup.java:134)
at org.apache.axis2.description.AxisDescription.engageModule(AxisDescription.java:490) at org.apache.axis2.description.AxisDescription.engageModule(AxisDescription.java:453)
at org.apache.axis2.engine.AxisConfiguration.addServiceGroup(AxisConfiguration.java:323) at org.apache.axis2.engine.AxisConfiguration.addService(AxisConfiguration.java:293)
at org.apache.axis2.client.ServiceClient.configureServiceClient(ServiceClient.java:175)
at org.apache.axis2.client.ServiceClient.(ServiceClient.java:143)
Root Cause :
"Security" phase is not defined under "OutFaultFlow" in axi2.xml - which is required [by default this should be there]

Solution :
Define "Security" phase under "OutFaultFlow" in axi2.xml

<phaseOrder type="OutFaultFlow">
   <phase name="soapmonitorPhase"/>
   <phase name="OperationOutFaultPhase"/>
   <phase name="RMPhase"/>
   <phase name="PolicyDetermination"/>
   <phase name="MessageOut"/>
   <phase name="Security"/>
</phaseOrder>

java.security.InvalidKeyException: Illegal key size or default parameters

Exception :
Caused by: org.apache.ws.security.WSSecurityException: Cannot encrypt data; nested exception is:
org.apache.xml.security.encryption.XMLEncryptionException: Illegal key size or default parameters
Original Exception was java.security.InvalidKeyException: Illegal key size or default parameters
at org.apache.ws.security.message.WSSecEncrypt.doEncryption(WSSecEncrypt.java:567)
at org.apache.ws.security.message.WSSecEncrypt.doEncryption(WSSecEncrypt.java:454)
at org.apache.ws.security.message.WSSecEncrypt.encryptForInternalRef(WSSecEncrypt.java:351)
at org.apache.rampart.builder.AsymmetricBindingBuilder.doSignBeforeEncrypt(AsymmetricBindingBuilder.java:530)
... 12 more
Root Cause :
There are key size restrictions with the default JDK comes with - which limits it to 128.

If your security policy uses a key size larger than this - then the above exception is thrown.

For example - if your security policy specifies the algorithemic suite as Basic256 - then the key size to be used is 256.

Solution :
You need to patch your JDK with Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files.

For JDK 1.5 download those from here and copy the two jar files from the extracted jce directory (local_policy.jar and US_export_policy.jar) to $JAVA_HOME/jre/lib/security.

For JDK 1.6, policy files can be downloaded from here.

Notes :
If you are running your client through an IDE - and you still gets the above error after applying the provided solution - double check the JAVA_HOME set in the corresponding IDE - and need to patch that corresponding JDK.

Monday, August 17, 2009

What is Rampart?

Ruchith explains here the story behind Rampart/Java.