The return type of StorageResolver.next() is X509Certificate, but the 
implementation attempts to return an StorageResolverSpi instance causing a 
ClassCastException. The way the KeyResolvers call this method, it appears the 
API is correct but the implementation is wrong. Indeed, I like the fact that we 
can call the KeyResolver only once with all available StorageResolverSpi's 
lumped into one StorageResolver. I'm a little perplexed why someone would 
create multiple StorageResolvers because that forces multiple executions of 
each KeyResolver. 

StorageResolver.getIterator() returns a raw Iterator, so that iterator's next() 
method returns Object which pushes the ClassCastException in the caller 
instead. One would expect the iterator to iterate over the same objects as 
StorageResolver.next(), so the same ClassCastException is lurking here.

What should be the behavior of those iterators?

To reproduce, run this sample program.

import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.Iterator;

import org.apache.xml.security.keys.storage.StorageResolver;
import org.apache.xml.security.keys.storage.StorageResolverSpi;
import org.apache.xml.security.keys.storage.implementations.KeyStoreResolver;

public class Repro {

        public static void main(String[] args) throws Exception
        {
                KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());

                ks.load(new java.io.FileInputStream(
                                
"data/org/apache/xml/security/samples/input/keystore.jks"),
                                "xmlsecurity".toCharArray());

                KeyStoreResolver ksResolver = new KeyStoreResolver(ks);
                StorageResolver storage = new StorageResolver(ksResolver);
                
                while (storage.hasNext())
                {
                        X509Certificate cert = storage.next();  // <--- 
ClassCastException here
                        System.out.println("cert is " + cert);
                }

                /*
                Iterator iter = storage.getIterator();
                while (iter.hasNext())
                {
                        X509Certificate cert = (X509Certificate)iter.next();  
// <--- iter.next() returns Object but causes ClassCastException if cast to 
X509Certificate
                        System.out.println("cert is " + cert);
                }
                */
        }
}

Reply via email to