Caching crypto objects to improve the performance when using the same crypto 
for signing and encrypting.
--------------------------------------------------------------------------------------------------------

                 Key: RAMPART-248
                 URL: https://issues.apache.org/jira/browse/RAMPART-248
             Project: Rampart
          Issue Type: Improvement
          Components: rampart-core
    Affects Versions: 1.4
            Reporter: Thilina Buddhika
            Assignee: Ruchith Udayanga Fernando
             Fix For: 1.5


When a particular cryptographic operation is taken place, a crypto object is 
created for that operation. This process involves reading certificates from the 
file system each time a cryptographic operation is carried out. The situation 
gets worse when multiple threads are trying to invoke cryptographic operations 
that involves the same certificate. This may lead to race condition and ends up 
with an exception with the following stacktrace.

 at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(Unknown Source)
        at java.io.FileInputStream.<init>(Unknown Source)
        at org.apache.ws.security.components.crypto.AbstractCrypto.<init>(Abstra
ctCrypto.java:109)
        at org.apache.ws.security.components.crypto.Merlin.<init>(Merlin.java:72
)
        at sun.reflect.GeneratedConstructorAccessor234.newInstance(Unknown Sourc
e)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Sou
rce)
        at java.lang.reflect.Constructor.newInstance(Unknown Source)
        at org.apache.ws.security.components.crypto.CryptoFactory.loadClass(Cryp
toFactory.java:211)
        at org.apache.ws.security.components.crypto.CryptoFactory.getInstance(Cr
yptoFactory.java:93)
        at org.apache.rampart.util.RampartUtil.getSignatureCrypto(RampartUtil.ja
va:398)
        at org.apache.rampart.PolicyBasedResultsValidator.verifyTrust(PolicyBase
dResultsValidator.java:601)
        at org.apache.rampart.PolicyBasedResultsValidator.validate(PolicyBasedRe
sultsValidator.java:163)
        at org.apache.rampart.RampartEngine.process(RampartEngine.java:214)
        at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.jav
a:92)
        at org.apache.axis2.engine.Phase.invoke(Phase.java:317)
        at org.apache.axis2.engine.AxisEngin

------------------------------------------
So one possible solution for this is to implement crypto caching inside 
RampartUtil. This can be a hashtable which stores Crypto objects against a 
value of a unique property of a particular Crypto implementation. For example : 
If we take Merlin as the Crypto implementation, then 
"org.apache.ws.security.crypto.merlin.file" is the unique property for a 
particular Crypto object.
So it is required to identify the unique properties for a particular Crypto 
implementation. Then enough attention should be paid to refresh the cache, 
since there is a possibility of changing the certs in the file system. One 
solution for this is to set a cache refresh interval and invalidate the cache 
after that interval. So the unique property and the cache refresh interval 
needs to be captured from the user. So these information can be included in 
RamaprtConfig. 

Solution :
-----------------

To enable caching of Crypto objects, two attributes should be added to the 
crypto elements of "signatureCrypto"/"encryptionCrypto" of RampartConfig.

1.cryptoKey - As the value of this attribute, specify the property of a Crypto 
implementation which points to the location of the keystore. For example in 
Merlin, the property "org.apache.ws.security.crypto.merlin.file" is unique and 
its pointing to the location of the keystore. Absence of this attribute will 
not enable caching.

2.cacheRefreshInterval - This is the cache refresh interval specified in 
milliseconds. Any object that resides in the cache longer than this period will 
be considered as expired. Cache will not be refreshed if this attribute is not 
present in the configuration. If you do not want to refresh the cache, provide 
only the "cryptoKey" attribute. 

So this is a sample of the suggested Ramapart Config.

<ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy";>
                          <ramp:signatureCrypto>
                              <ramp:crypto 
provider="org.apache.ws.security.components.crypto.Merlin" 
cryptoKey="org.apache.ws.security.crypto.merlin.file" 
cacheRefreshInterval="300000">
                                        <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">servicePW</ramp:property>
                                </ramp:crypto>
                        </ramp:signatureCrypto>
                       <ramp:encryptionCypto>
                               <ramp:crypto 
provider="org.apache.ws.security.components.crypto.Merlin" 
cryptoKey="org.apache.ws.security.crypto.merlin.file" 
cacheRefreshInterval="300000>
                                             <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>

A sample configuration is provided below. It uses the Merlin crypto 
implementation for signing and encryption. Here, the value of the cryptoKey 
attribute is eqaul to "org.apache.ws.security.crypto.merlin.file" and the cache 
refresh interval is 300000 milliseconds.

I came with an implementation following the model explained above. his 
implementation is done in a backward compatible way and it will not break any 
of the current functionalities.

WDYT ?

Thanks.
/ thilina



 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to