santuario-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pellerin, Clement" <>
Subject RE: [Proposal] KeyResolvers
Date Mon, 14 Jun 2010 14:29:44 GMT
On June 11, 2010 5:56 PM, Chad La Joie wrote:
> On 6/4/10 9:15 AM, Pellerin, Clement wrote:
> > What is the recommended way to implement a KeyResolver for an EncryptedKey where
the KEK is a PublicKey?
> >
> > At first I thought I could write a Resolver for the KEK PrivateKey and let the EncryptedKeyResolver
call it.
> > Unfortunately, the KeyResolverSpi API can return a SecretKey but there is no provision
to return a PrivateKey.
> > Can we augment the KeyResolverSpi with a new method engineLookupAndResolvePrivateKey()?
> > This method would be called by the EncryptedKeyResolver when it detects the KeyWrap
algorithm rsa-1_5
> > or rsa-oaep-mgf1p. This change looks possible since KeyResolverSpi is a class not
an interface.
> I think the only way to do what you're asking for would be to add the 
> additional methods to KeyResolver and KeyResolverSpi.  Since the 
> KeyResolverSpi is an abstract class, adding a no-op 
> engineLookupAndResolvePrivateKey and engineResolvePrivateKey wouldn't 
> break API compatibility with.  Same with adding the analogous 
> resolvePrivateKey method on KeyResolver.
> > In the meantime, I tried to replace the EncryptedKeyResolver with my own implementation.
> > Again, I've hit a problem because I need the symmetric key algorithm.
> > Normally this is passed to the constructor of a temporary EncryptedKeyResolver in
the method
> > XMLCipher.decryptToByteArray():
> > 		ki.registerInternalKeyResolver(
> > 		        new EncryptedKeyResolver(
> >                           encryptedData.getEncryptionMethod().getAlgorithm(),
> >                           _kek));
> > As you can see, the constructor is called directly.
> > If you don't like my idea of a PrivateKey resolver, can we at least move that constructor
> > to a new protected method on XMLCipher so we could override it in a subclass?
> Whether a private key resolution method was added to the KeyResolver I'd 
> recommend moving the construction of the KEK resolver to a method 
> anyways.  Given some of the complexities surrounding key resolution 
> within XML encryption it's certainly not hard to imagine some else down 
> the road will need a hook like that.

This validates my approach.

I would like to point out something about the new factory method to create the EncryptedKeyResolver.
XMLCipher already has many similar methods but they are all for interfaces. This would be
the first factory method to create a class. Other classes could also make use of a factory
method. I can think of KeyInfo for example. XMLCipher.createKeyInfo() would be a great hook
to attach thread-specific KeyResolvers.

Once the KeyResolver can return a PrivateKey, we have to ask ourselves where does it get it
from. My first reaction was to write a KeyStoreKeyResolver that would know how to find a PrivateKey
within a KeyStore passed in the constructor. I soon realized this collided with the existing
KeyResolvers. It makes more sense to extend the existing KeyResolvers to resolve PrivateKeys
than to introduce a super KeyResolver that knows how to return a PrivateKey for any kind of
hint. KeyStoreKeyResolver was dead born.

Now that we know X509IssuerSerialResolver must resolve PrivateKeys, where does it get it from?
I believe the answer is: the same place where it gets the list of certificates. My proposal
is to augument the StorageResolver to return an iterator that iterates over the PrivateKeys.
For completeness, we would need a third iterator for the SymmetricKeys.

When I looked at KeyStoreResolver, I was surprised to find it is not thread-safe. The code
expects the user to be single-threaded or else it must create a new StorageResolver and a
new KeyStoreResolver each time. I think this is very error prone. It is very tempting for
the user to create his StorageResolver once and reuse it all the time. I suggest we make StorageResolver.hasNext()
and next() deprecated. I also suggest a new iterator should be returned every time StorageResolver.getIterator()
is called. Similarly, a new iterator should be returned every time StoreResolverSpi.getIterator()
is called (see KeyStoreResolver for example).

View raw message